@@ -3,15 +3,14 @@ import { Date as Date_binding } from "./bindings/dom";
33
44// @ts -ignore: decorator
55@inline const
6+ MILLIS_LIMIT = 8640000000000000 ,
67 MILLIS_PER_DAY = 1000 * 60 * 60 * 24 ,
78 MILLIS_PER_HOUR = 1000 * 60 * 60 ,
89 MILLIS_PER_MINUTE = 1000 * 60 ,
910 MILLIS_PER_SECOND = 1000 ,
10-
11- YEARS_PER_EPOCH = 400 ,
12- DAYS_PER_EPOCH = 146097 ,
13- EPOCH_OFFSET = 719468 , // Jan 1, 1970
14- MILLIS_LIMIT = 8640000000000000 ;
11+ YEARS_PER_EPOCH = 400 ,
12+ DAYS_PER_EPOCH = 146097 , // 400 * 365 + 400 / 4 - 400 / 100 + 1
13+ EPOCH_OFFSET = 719468 ; // Jan 1, 1970
1514
1615// ymdFromEpochDays returns values via globals to avoid allocations
1716// @ts -ignore: decorator
@@ -62,7 +61,7 @@ export class Date {
6261 let timeString : string ;
6362 dateString = dateTimeString . substring ( 0 , posT ) ;
6463 timeString = dateTimeString . substring ( posT + 1 ) ;
65-
64+
6665 // might end with an offset ("Z", "+05:30", "-08:00", etc.)
6766 for ( let i = timeString . length - 1 ; i >= 0 ; i -- ) {
6867 let c = timeString . charCodeAt ( i ) ;
@@ -82,8 +81,8 @@ export class Date {
8281 } else {
8382 let offsetHours = i32 . parse ( timeString . substring ( i + 1 ) ) ;
8483 offsetMs = offsetHours * MILLIS_PER_HOUR ;
85- }
86-
84+ }
85+
8786 if ( c == 45 ) offsetMs = - offsetMs ; // negative offset
8887 timeString = timeString . substring ( 0 , i ) ;
8988 break ;
@@ -333,25 +332,23 @@ function invalidDate(millis: i64): bool {
333332// Paper: https://arxiv.org/pdf/2102.06959.pdf
334333function dateFromEpoch ( ms : i64 ) : i32 {
335334 let da = ( < i32 > floorDiv ( ms , MILLIS_PER_DAY ) * 4 + EPOCH_OFFSET * 4 ) | 3 ;
336- let q0 = floorDiv ( da , DAYS_PER_EPOCH ) ; // [0, 146096]
335+ let q0 = floorDiv ( da , DAYS_PER_EPOCH ) ; // [0, 146096]
337336 let r1 = < u32 > da - q0 * DAYS_PER_EPOCH ;
338337 let u1 = u64 ( r1 | 3 ) * 2939745 ;
339338 let dm1 = < u32 > u1 / 11758980 ;
340339 let n1 = 2141 * dm1 + 197913 ;
341340 let year = 100 * q0 + i32 ( u1 >>> 32 ) ;
342- let mo = n1 >>> 16 ;
343- _day = ( n1 & 0xFFFF ) / 2141 + 1 ; // [1, 31]
344- if ( dm1 >= 306 ) { mo -= 12 ; ++ year ; }
345- _month = mo ; // [1, 12]
346- return year ;
341+ _day = ( n1 & 0xFFFF ) / 2141 + 1 ; // [1, 31]
342+ _month = ( n1 >>> 16 ) - ( dm1 >= 306 ? 12 : 0 ) ; // [1, 12]
343+ return year + ( dm1 >= 306 ? 1 : 0 ) ;
347344}
348345
349346// http://howardhinnant.github.io/date_algorithms.html#days_from_civil
350- function daysSinceEpoch ( y : i32 , m : i32 , d : i32 ) : i64 {
351- y -= i32 ( m <= 2 ) ;
352- let era = < u32 > floorDiv ( y , YEARS_PER_EPOCH ) ;
353- let yoe = < u32 > y - era * YEARS_PER_EPOCH ; // [0, 399]
354- let doy = < u32 > ( 153 * ( m + ( m > 2 ? - 3 : 9 ) ) + 2 ) / 5 + d - 1 ; // [0, 365]
347+ function daysSinceEpoch ( year : i32 , month : i32 , day : i32 ) : i64 {
348+ year -= i32 ( month <= 2 ) ;
349+ let era = < u32 > floorDiv ( year , YEARS_PER_EPOCH ) ;
350+ let yoe = < u32 > year - era * YEARS_PER_EPOCH ; // [0, 399]
351+ let doy = < u32 > ( 153 * ( month + ( month > 2 ? - 3 : 9 ) ) + 2 ) / 5 + day - 1 ; // [0, 365]
355352 let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy ; // [0, 146096]
356353 return < i64 > < i32 > ( era * 146097 + doe - EPOCH_OFFSET ) ;
357354}
@@ -360,8 +357,9 @@ function daysSinceEpoch(y: i32, m: i32, d: i32): i64 {
360357function dayOfWeek ( year : i32 , month : i32 , day : i32 ) : i32 {
361358 const tab = memory . data < u8 > ( [ 0 , 3 , 2 , 5 , 0 , 3 , 5 , 1 , 4 , 6 , 2 , 4 ] ) ;
362359
363- year -= i32 ( month < 3 ) ;
364- year += floorDiv ( year , 4 ) - floorDiv ( year , 100 ) + floorDiv ( year , YEARS_PER_EPOCH ) ;
360+ year -= i32 ( month <= 2 ) ;
361+ const cent = floorDiv ( year >> 2 , 100 >> 2 ) ;
362+ year += ( year >> 2 ) - cent + ( cent >> 2 ) ;
365363 month = < i32 > load < u8 > ( tab + month - 1 ) ;
366364 return euclidRem ( year + month + day , 7 ) ;
367365}
0 commit comments