@@ -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,37 +62,67 @@ 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
+
77
+ let posColon = timeString . indexOf ( ":" , i + 1 ) ;
78
+ if ( ~ posColon ) {
79
+ let offsetHours = i32 . parse ( timeString . substring ( i + 1 , posColon ) ) ;
80
+ let offsetMinutes = i32 . parse ( timeString . substring ( posColon + 1 ) ) ;
81
+ offsetMs = ( offsetHours * 60 + offsetMinutes ) * MILLIS_PER_MINUTE ;
82
+ } else {
83
+ let offsetHours = i32 . parse ( timeString . substring ( i + 1 ) ) ;
84
+ offsetMs = offsetHours * MILLIS_PER_HOUR ;
85
+ }
86
+
87
+ if ( c == 45 ) offsetMs = - offsetMs ; // negative offset
88
+ timeString = timeString . substring ( 0 , i ) ;
89
+ break ;
90
+ }
91
+ }
92
+
93
+ // parse the HH:MM:SS component
65
94
let timeParts = timeString . split ( ":" ) ;
66
95
let len = timeParts . length ;
67
96
if ( len <= 1 ) throw new RangeError ( E_INVALIDDATE ) ;
68
97
69
- hour = I32 . parseInt ( timeParts [ 0 ] ) ;
70
- min = I32 . parseInt ( timeParts [ 1 ] ) ;
98
+ hour = i32 . parse ( timeParts [ 0 ] ) ;
99
+ min = i32 . parse ( timeParts [ 1 ] ) ;
71
100
if ( len >= 3 ) {
72
- let secAndMs = timeParts [ 2 ] ;
73
- let posDot = secAndMs . indexOf ( "." ) ;
101
+ let secAndFrac = timeParts [ 2 ] ;
102
+ let posDot = secAndFrac . indexOf ( "." ) ;
74
103
if ( ~ posDot ) {
75
- // includes milliseconds
76
- sec = I32 . parseInt ( secAndMs . substring ( 0 , posDot ) ) ;
77
- ms = I32 . parseInt ( secAndMs . substring ( posDot + 1 ) ) ;
104
+ // includes fractional seconds (truncate to milliseconds)
105
+ sec = i32 . parse ( secAndFrac . substring ( 0 , posDot ) ) ;
106
+ ms = i32 . parse ( secAndFrac . substr ( posDot + 1 , 3 ) . padEnd ( 3 , "0" ) ) ;
78
107
} else {
79
- sec = I32 . parseInt ( secAndMs ) ;
108
+ sec = i32 . parse ( secAndFrac ) ;
80
109
}
81
110
}
82
111
}
112
+
83
113
// parse the YYYY-MM-DD component
84
114
let parts = dateString . split ( "-" ) ;
85
- let year = I32 . parseInt ( parts [ 0 ] ) ;
115
+ let year = i32 . parse ( parts [ 0 ] ) ;
86
116
let month = 1 , day = 1 ;
87
117
let len = parts . length ;
88
118
if ( len >= 2 ) {
89
- month = I32 . parseInt ( parts [ 1 ] ) ;
119
+ month = i32 . parse ( parts [ 1 ] ) ;
90
120
if ( len >= 3 ) {
91
- day = I32 . parseInt ( parts [ 2 ] ) ;
121
+ day = i32 . parse ( parts [ 2 ] ) ;
92
122
}
93
123
}
94
- return new Date ( epochMillis ( year , month , day , hour , min , sec , ms ) ) ;
124
+
125
+ return new Date ( epochMillis ( year , month , day , hour , min , sec , ms ) - offsetMs ) ;
95
126
}
96
127
97
128
constructor ( private epochMillis : i64 ) {
0 commit comments