Skip to content

Commit 876f9ff

Browse files
authored
Refactor stringify methods of Date (#2398)
1 parent 3e0462b commit 876f9ff

File tree

3 files changed

+2238
-2343
lines changed

3 files changed

+2238
-2343
lines changed

Diff for: std/assembly/date.ts

+63-82
Original file line numberDiff line numberDiff line change
@@ -169,125 +169,98 @@ export class Date {
169169

170170
setUTCDate(day: i32): void {
171171
if (this.day == day) return;
172-
var ms = euclidRem(this.epochMillis, MILLIS_PER_DAY);
173-
this.setTime(i64(daysSinceEpoch(this.year, this.month, day)) * MILLIS_PER_DAY + ms);
172+
this.setTime(join(this.year, this.month, day, this.epochMillis));
174173
}
175174

176175
setUTCMonth(month: i32, day: i32 = this.day): void {
177176
if (this.month == month + 1) return;
178-
var ms = euclidRem(this.epochMillis, MILLIS_PER_DAY);
179-
this.setTime(i64(daysSinceEpoch(this.year, month + 1, day)) * MILLIS_PER_DAY + ms);
177+
this.setTime(join(this.year, month + 1, day, this.epochMillis));
180178
}
181179

182180
setUTCFullYear(year: i32): void {
183181
if (this.year == year) return;
184-
var ms = euclidRem(this.epochMillis, MILLIS_PER_DAY);
185-
this.setTime(i64(daysSinceEpoch(year, this.month, this.day)) * MILLIS_PER_DAY + ms);
182+
this.setTime(join(year, this.month, this.day, this.epochMillis));
186183
}
187184

188185
toISOString(): string {
189186
// TODO: add more low-level helper which combine toString and padStart without extra allocation
190-
var yearStr: string;
191-
var year = this.year;
192-
var isNeg = year < 0;
193-
if (isNeg || year >= 10000) {
194-
yearStr = (isNeg ? "-" : "+") + abs(year).toString().padStart(6, "0");
195-
} else {
196-
yearStr = year.toString().padStart(4, "0");
197-
}
198187

199-
return (
200-
yearStr +
201-
"-" +
202-
this.month.toString().padStart(2, "0") +
203-
"-" +
204-
this.day.toString().padStart(2, "0") +
205-
"T" +
206-
this.getUTCHours().toString().padStart(2, "0") +
207-
":" +
208-
this.getUTCMinutes().toString().padStart(2, "0") +
209-
":" +
210-
this.getUTCSeconds().toString().padStart(2, "0") +
211-
"." +
212-
this.getUTCMilliseconds().toString().padStart(3, "0") +
213-
"Z"
214-
);
188+
var yr = this.year;
189+
var isNeg = yr < 0;
190+
var year = (isNeg || yr >= 10000)
191+
? (isNeg ? "-" : "+") + stringify(abs(yr), 6)
192+
: stringify(yr, 4);
193+
var month = stringify(this.month, 2);
194+
var day = stringify(this.day);
195+
var hours = stringify(this.getUTCHours());
196+
var mins = stringify(this.getUTCMinutes());
197+
var secs = stringify(this.getUTCSeconds());
198+
var ms = stringify(this.getUTCMilliseconds(), 3);
199+
200+
return `${year}-${month}-${day}T${hours}:${mins}:${secs}.${ms}Z`;
215201
}
216202

217203
toUTCString(): string {
218-
const weeks: StaticArray<string> = [
219-
"Sun, ", "Mon, ", "Tue, ", "Wed, ", "Thu, ", "Fri, ", "Sat, "
220-
];
221-
222-
const months: StaticArray<string> = [
223-
" Jan ", " Feb ", " Mar ", " Apr ", " May ", " Jun ",
224-
" Jul ", " Aug ", " Sep ", " Oct ", " Nov ", " Dec "
225-
];
204+
const
205+
weeks: StaticArray<string> = [
206+
"Sun, ", "Mon, ", "Tue, ", "Wed, ", "Thu, ", "Fri, ", "Sat, "
207+
],
208+
months: StaticArray<string> = [
209+
" Jan ", " Feb ", " Mar ", " Apr ", " May ", " Jun ",
210+
" Jul ", " Aug ", " Sep ", " Oct ", " Nov ", " Dec "
211+
];
226212

227213
var mo = this.month;
228214
var da = this.day;
229215
var yr = this.year;
230216
var wd = dayOfWeek(yr, mo, da);
231-
var year = abs(yr).toString().padStart(4, "0");
232-
if (yr < 0) year = "-" + year;
233-
234-
return (
235-
unchecked(weeks[wd]) +
236-
da.toString().padStart(2, "0") +
237-
unchecked(months[mo - 1]) +
238-
year +
239-
" " +
240-
this.getUTCHours().toString().padStart(2, "0") +
241-
":" +
242-
this.getUTCMinutes().toString().padStart(2, "0") +
243-
":" +
244-
this.getUTCSeconds().toString().padStart(2, "0") +
245-
" GMT"
246-
);
217+
var year = stringify(abs(yr), 4);
218+
var month = unchecked(months[mo - 1]);
219+
var week = unchecked(weeks[wd]);
220+
var day = stringify(da);
221+
var hours = stringify(this.getUTCHours());
222+
var mins = stringify(this.getUTCMinutes());
223+
var secs = stringify(this.getUTCSeconds());
224+
225+
return `${week}${day}${month}${yr < 0 ? "-" : ""}${year} ${hours}:${mins}:${secs} GMT`;
247226
}
248227

249228
toDateString(): string {
250229
// TODO: use u64 static data instead 4 chars
251230
// also use stream itoa variants.
252-
const weeks: StaticArray<string> = [
253-
"Sun ", "Mon ", "Tue ", "Wed ", "Thu ", "Fri ", "Sat "
254-
];
255-
256-
const months: StaticArray<string> = [
257-
"Jan ", "Feb ", "Mar ", "Apr ", "May ", "Jun ",
258-
"Jul ", "Aug ", "Sep ", "Oct ", "Nov ", "Dec "
259-
];
231+
const
232+
weeks: StaticArray<string> = [
233+
"Sun ", "Mon ", "Tue ", "Wed ", "Thu ", "Fri ", "Sat "
234+
],
235+
months: StaticArray<string> = [
236+
"Jan ", "Feb ", "Mar ", "Apr ", "May ", "Jun ",
237+
"Jul ", "Aug ", "Sep ", "Oct ", "Nov ", "Dec "
238+
];
260239

261240
var mo = this.month;
262241
var da = this.day;
263242
var yr = this.year;
264243
var wd = dayOfWeek(yr, mo, da);
265-
var year = abs(yr).toString().padStart(4, "0");
266-
if (yr < 0) year = "-" + year;
267-
268-
return (
269-
unchecked(weeks[wd]) +
270-
unchecked(months[mo - 1]) +
271-
da.toString().padStart(2, "0") +
272-
" " + year
273-
);
244+
var year = stringify(abs(yr), 4);
245+
var month = unchecked(months[mo - 1]);
246+
var week = unchecked(weeks[wd]);
247+
var day = stringify(da);
248+
249+
return `${week}${month}${day}${yr < 0 ? " -" : " "}${year}`;
274250
}
275251

276252
// Note: it uses UTC time instead local time (without timezone offset)
277253
toTimeString(): string {
254+
var hours = stringify(this.getUTCHours());
255+
var mins = stringify(this.getUTCMinutes());
256+
var secs = stringify(this.getUTCSeconds());
278257
// TODO: add timezone
279-
return (
280-
this.getUTCHours().toString().padStart(2, "0") +
281-
":" +
282-
this.getUTCMinutes().toString().padStart(2, "0") +
283-
":" +
284-
this.getUTCSeconds().toString().padStart(2, "0")
285-
);
258+
return `${hours}:${mins}:${secs}`;
286259
}
287260

288261
// Note: it uses UTC datetime instead local datetime (without timezone offset)
289262
toString(): string {
290-
return this.toDateString() + " " + this.toTimeString();
263+
return `${this.toDateString()} ${this.toTimeString()}`;
291264
}
292265
}
293266

@@ -301,7 +274,7 @@ function epochMillis(
301274
milliseconds: i32
302275
): i64 {
303276
return (
304-
i64(daysSinceEpoch(year, month, day)) * MILLIS_PER_DAY +
277+
daysSinceEpoch(year, month, day) * MILLIS_PER_DAY +
305278
hour * MILLIS_PER_HOUR +
306279
minute * MILLIS_PER_MINUTE +
307280
second * MILLIS_PER_SECOND +
@@ -343,13 +316,13 @@ function dateFromEpoch(ms: i64): i32 {
343316
}
344317

345318
// http://howardhinnant.github.io/date_algorithms.html#days_from_civil
346-
function daysSinceEpoch(y: i32, m: i32, d: i32): i32 {
319+
function daysSinceEpoch(y: i32, m: i32, d: i32): i64 {
347320
y -= i32(m <= 2);
348321
var era = <u32>floorDiv(y, YEARS_PER_EPOCH);
349322
var yoe = <u32>y - era * YEARS_PER_EPOCH; // [0, 399]
350323
var doy = <u32>(153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; // [0, 365]
351324
var doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
352-
return era * 146097 + doe - EPOCH_OFFSET;
325+
return <i64><i32>(era * 146097 + doe - EPOCH_OFFSET);
353326
}
354327

355328
// TomohikoSakamoto algorithm from https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week
@@ -361,3 +334,11 @@ function dayOfWeek(year: i32, month: i32, day: i32): i32 {
361334
month = <i32>load<u8>(tab + month - 1);
362335
return euclidRem(year + month + day, 7);
363336
}
337+
338+
function stringify(value: i32, padding: i32 = 2): string {
339+
return value.toString().padStart(padding, "0");
340+
}
341+
342+
function join(year: i32, month: i32, day: i32, ms: i64): i64 {
343+
return daysSinceEpoch(year, month, day) * MILLIS_PER_DAY + euclidRem(ms, MILLIS_PER_DAY);
344+
}

0 commit comments

Comments
 (0)