@@ -169,125 +169,98 @@ export class Date {
169
169
170
170
setUTCDate ( day : i32 ) : void {
171
171
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 ) ) ;
174
173
}
175
174
176
175
setUTCMonth ( month : i32 , day : i32 = this . day ) : void {
177
176
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 ) ) ;
180
178
}
181
179
182
180
setUTCFullYear ( year : i32 ) : void {
183
181
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 ) ) ;
186
183
}
187
184
188
185
toISOString ( ) : string {
189
186
// 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
- }
198
187
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` ;
215
201
}
216
202
217
203
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
+ ] ;
226
212
227
213
var mo = this . month ;
228
214
var da = this . day ;
229
215
var yr = this . year ;
230
216
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` ;
247
226
}
248
227
249
228
toDateString ( ) : string {
250
229
// TODO: use u64 static data instead 4 chars
251
230
// 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
+ ] ;
260
239
261
240
var mo = this . month ;
262
241
var da = this . day ;
263
242
var yr = this . year ;
264
243
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 } ` ;
274
250
}
275
251
276
252
// Note: it uses UTC time instead local time (without timezone offset)
277
253
toTimeString ( ) : string {
254
+ var hours = stringify ( this . getUTCHours ( ) ) ;
255
+ var mins = stringify ( this . getUTCMinutes ( ) ) ;
256
+ var secs = stringify ( this . getUTCSeconds ( ) ) ;
278
257
// 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 } ` ;
286
259
}
287
260
288
261
// Note: it uses UTC datetime instead local datetime (without timezone offset)
289
262
toString ( ) : string {
290
- return this . toDateString ( ) + " " + this . toTimeString ( ) ;
263
+ return ` ${ this . toDateString ( ) } ${ this . toTimeString ( ) } ` ;
291
264
}
292
265
}
293
266
@@ -301,7 +274,7 @@ function epochMillis(
301
274
milliseconds : i32
302
275
) : i64 {
303
276
return (
304
- i64 ( daysSinceEpoch ( year , month , day ) ) * MILLIS_PER_DAY +
277
+ daysSinceEpoch ( year , month , day ) * MILLIS_PER_DAY +
305
278
hour * MILLIS_PER_HOUR +
306
279
minute * MILLIS_PER_MINUTE +
307
280
second * MILLIS_PER_SECOND +
@@ -343,13 +316,13 @@ function dateFromEpoch(ms: i64): i32 {
343
316
}
344
317
345
318
// 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 {
347
320
y -= i32 ( m <= 2 ) ;
348
321
var era = < u32 > floorDiv ( y , YEARS_PER_EPOCH ) ;
349
322
var yoe = < u32 > y - era * YEARS_PER_EPOCH ; // [0, 399]
350
323
var doy = < u32 > ( 153 * ( m + ( m > 2 ? - 3 : 9 ) ) + 2 ) / 5 + d - 1 ; // [0, 365]
351
324
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 ) ;
353
326
}
354
327
355
328
// 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 {
361
334
month = < i32 > load < u8 > ( tab + month - 1 ) ;
362
335
return euclidRem ( year + month + day , 7 ) ;
363
336
}
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