@@ -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