@@ -52,7 +52,8 @@ export class Date {
52
52
hour : i32 = 0 ,
53
53
min : i32 = 0 ,
54
54
sec : i32 = 0 ,
55
- ms : i32 = 0 ;
55
+ ms : i32 = 0 ,
56
+ offsetMs : i32 = 0 ;
56
57
57
58
let dateString = dateTimeString ;
58
59
let posT = dateTimeString . indexOf ( "T" ) ;
@@ -61,25 +62,49 @@ export class Date {
61
62
let timeString : string ;
62
63
dateString = dateTimeString . substring ( 0 , posT ) ;
63
64
timeString = dateTimeString . substring ( posT + 1 ) ;
64
- // parse the HH-MM-SS component
65
+
66
+ // might end with an offset ("Z", "+05:30", "-08:00", etc.)
67
+ for ( let i = timeString . length - 1 ; i >= 0 ; i -- ) {
68
+ let c = timeString . charCodeAt ( i ) ;
69
+ if ( c == 90 ) { // Z
70
+ timeString = timeString . substring ( 0 , i ) ;
71
+ break ;
72
+ } else if ( c == 43 || c == 45 ) { // + or -
73
+ if ( i == timeString . length - 1 ) {
74
+ throw new RangeError ( E_INVALIDDATE ) ;
75
+ }
76
+ let offsetParts = timeString . substring ( i + 1 ) . split ( ":" ) ;
77
+ let offsetHours = i32 . parse ( offsetParts [ 0 ] ) ;
78
+ let offsetMinutes = offsetParts . length >= 2 ? i32 . parse ( offsetParts [ 1 ] ) : 0 ;
79
+ offsetMs = ( offsetHours * 60 + offsetMinutes ) * 60000 ;
80
+ if ( c == 45 ) {
81
+ offsetMs = - offsetMs ; // negative offset
82
+ }
83
+ timeString = timeString . substring ( 0 , i ) ;
84
+ break ;
85
+ }
86
+ }
87
+
88
+ // parse the HH:MM:SS component
65
89
let timeParts = timeString . split ( ":" ) ;
66
90
let len = timeParts . length ;
67
91
if ( len <= 1 ) throw new RangeError ( E_INVALIDDATE ) ;
68
92
69
93
hour = i32 . parse ( timeParts [ 0 ] ) ;
70
94
min = i32 . parse ( timeParts [ 1 ] ) ;
71
95
if ( len >= 3 ) {
72
- let secAndMs = timeParts [ 2 ] ;
73
- let posDot = secAndMs . indexOf ( "." ) ;
96
+ let secAndFrac = timeParts [ 2 ] ;
97
+ let posDot = secAndFrac . indexOf ( "." ) ;
74
98
if ( ~ posDot ) {
75
- // includes milliseconds
76
- sec = i32 . parse ( secAndMs . substring ( 0 , posDot ) ) ;
77
- ms = i32 . parse ( secAndMs . substring ( posDot + 1 ) ) ;
99
+ // includes fractional seconds (truncate to milliseconds)
100
+ sec = i32 . parse ( secAndFrac . substring ( 0 , posDot ) ) ;
101
+ ms = i32 . parse ( secAndFrac . substr ( posDot + 1 , 3 ) . padEnd ( 3 , "0" ) ) ;
78
102
} else {
79
- sec = i32 . parse ( secAndMs ) ;
103
+ sec = i32 . parse ( secAndFrac ) ;
80
104
}
81
105
}
82
106
}
107
+
83
108
// parse the YYYY-MM-DD component
84
109
let parts = dateString . split ( "-" ) ;
85
110
let year = i32 . parse ( parts [ 0 ] ) ;
@@ -91,7 +116,8 @@ export class Date {
91
116
day = i32 . parse ( parts [ 2 ] ) ;
92
117
}
93
118
}
94
- return new Date ( epochMillis ( year , month , day , hour , min , sec , ms ) ) ;
119
+
120
+ return new Date ( epochMillis ( year , month , day , hour , min , sec , ms ) - offsetMs ) ;
95
121
}
96
122
97
123
constructor ( private epochMillis : i64 ) {
0 commit comments