@@ -66,6 +66,11 @@ export class NativeDateAdapter extends DateAdapter<Date> {
66
66
* Without this `Intl.DateTimeFormat` sometimes chooses the wrong timeZone, which can throw off
67
67
* the result. (e.g. in the en-US locale `new Date(1800, 7, 14).toLocaleDateString()`
68
68
* will produce `'8/13/1800'`.
69
+ *
70
+ * TODO(mmalerba): drop this variable. It's not being used in the code right now. We're now
71
+ * getting the string representation of a Date object from it's utc representation. We're keeping
72
+ * it here for sometime, just for precaution, in case we decide to revert some of these changes
73
+ * though.
69
74
*/
70
75
useUtcForDisplay : boolean ;
71
76
@@ -101,34 +106,35 @@ export class NativeDateAdapter extends DateAdapter<Date> {
101
106
102
107
getMonthNames ( style : 'long' | 'short' | 'narrow' ) : string [ ] {
103
108
if ( SUPPORTS_INTL_API ) {
104
- let dtf = new Intl . DateTimeFormat ( this . locale , { month : style } ) ;
105
- return range ( 12 , i => this . _stripDirectionalityCharacters ( dtf . format ( new Date ( 2017 , i , 1 ) ) ) ) ;
109
+ const dtf = new Intl . DateTimeFormat ( this . locale , { month : style , timeZone : 'utc' } ) ;
110
+ return range ( 12 , i =>
111
+ this . _stripDirectionalityCharacters ( this . _format ( dtf , new Date ( 2017 , i , 1 ) ) ) ) ;
106
112
}
107
113
return DEFAULT_MONTH_NAMES [ style ] ;
108
114
}
109
115
110
116
getDateNames ( ) : string [ ] {
111
117
if ( SUPPORTS_INTL_API ) {
112
- let dtf = new Intl . DateTimeFormat ( this . locale , { day : 'numeric' } ) ;
118
+ const dtf = new Intl . DateTimeFormat ( this . locale , { day : 'numeric' , timeZone : 'utc '} ) ;
113
119
return range ( 31 , i => this . _stripDirectionalityCharacters (
114
- dtf . format ( new Date ( 2017 , 0 , i + 1 ) ) ) ) ;
120
+ this . _format ( dtf , new Date ( 2017 , 0 , i + 1 ) ) ) ) ;
115
121
}
116
122
return DEFAULT_DATE_NAMES ;
117
123
}
118
124
119
125
getDayOfWeekNames ( style : 'long' | 'short' | 'narrow' ) : string [ ] {
120
126
if ( SUPPORTS_INTL_API ) {
121
- let dtf = new Intl . DateTimeFormat ( this . locale , { weekday : style } ) ;
127
+ const dtf = new Intl . DateTimeFormat ( this . locale , { weekday : style , timeZone : 'utc' } ) ;
122
128
return range ( 7 , i => this . _stripDirectionalityCharacters (
123
- dtf . format ( new Date ( 2017 , 0 , i + 1 ) ) ) ) ;
129
+ this . _format ( dtf , new Date ( 2017 , 0 , i + 1 ) ) ) ) ;
124
130
}
125
131
return DEFAULT_DAY_OF_WEEK_NAMES [ style ] ;
126
132
}
127
133
128
134
getYearName ( date : Date ) : string {
129
135
if ( SUPPORTS_INTL_API ) {
130
- let dtf = new Intl . DateTimeFormat ( this . locale , { year : 'numeric' } ) ;
131
- return this . _stripDirectionalityCharacters ( dtf . format ( date ) ) ;
136
+ const dtf = new Intl . DateTimeFormat ( this . locale , { year : 'numeric' , timeZone : 'utc '} ) ;
137
+ return this . _stripDirectionalityCharacters ( this . _format ( dtf , date ) ) ;
132
138
}
133
139
return String ( this . getYear ( date ) ) ;
134
140
}
@@ -159,7 +165,6 @@ export class NativeDateAdapter extends DateAdapter<Date> {
159
165
}
160
166
161
167
let result = this . _createDateWithOverflow ( year , month , date ) ;
162
-
163
168
// Check that the date wasn't above the upper bound for the month, causing the month to overflow
164
169
if ( result . getMonth ( ) != month ) {
165
170
throw Error ( `Invalid date "${ date } " for month with index "${ month } ".` ) ;
@@ -194,15 +199,10 @@ export class NativeDateAdapter extends DateAdapter<Date> {
194
199
date . setFullYear ( Math . max ( 1 , Math . min ( 9999 , date . getFullYear ( ) ) ) ) ;
195
200
}
196
201
197
- if ( this . useUtcForDisplay ) {
198
- date = new Date ( Date . UTC (
199
- date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) , date . getHours ( ) ,
200
- date . getMinutes ( ) , date . getSeconds ( ) , date . getMilliseconds ( ) ) ) ;
201
- displayFormat = { ...displayFormat , timeZone : 'utc' } ;
202
- }
202
+ displayFormat = { ...displayFormat , timeZone : 'utc' } ;
203
203
204
204
const dtf = new Intl . DateTimeFormat ( this . locale , displayFormat ) ;
205
- return this . _stripDirectionalityCharacters ( dtf . format ( date ) ) ;
205
+ return this . _stripDirectionalityCharacters ( this . _format ( dtf , date ) ) ;
206
206
}
207
207
return this . _stripDirectionalityCharacters ( date . toDateString ( ) ) ;
208
208
}
@@ -275,7 +275,7 @@ export class NativeDateAdapter extends DateAdapter<Date> {
275
275
276
276
/** Creates a date but allows the month and date to overflow. */
277
277
private _createDateWithOverflow ( year : number , month : number , date : number ) {
278
- let result = new Date ( year , month , date ) ;
278
+ const result = new Date ( year , month , date ) ;
279
279
280
280
// We need to correct for the fact that JS native Date treats years in range [0, 99] as
281
281
// abbreviations for 19xx.
@@ -304,4 +304,22 @@ export class NativeDateAdapter extends DateAdapter<Date> {
304
304
private _stripDirectionalityCharacters ( str : string ) {
305
305
return str . replace ( / [ \u200e \u200f ] / g, '' ) ;
306
306
}
307
+
308
+ /**
309
+ * When converting Date object to string, javascript built-in functions may return wrong
310
+ * results because it applies its internal DST rules. The DST rules around the world change
311
+ * very frequently, and the current valid rule is not always valid in previous years though.
312
+ * We work around this problem building a new Date object which has its internal UTC
313
+ * representation with the local date and time.
314
+ * @param dtf Intl.DateTimeFormat object, containg the desired string format. It must have
315
+ * timeZone set to 'utc' to work fine.
316
+ * @param date Date from which we want to get the string representation according to dtf
317
+ * @returns A Date object with its UTC representation based on the passed in date info
318
+ */
319
+ private _format ( dtf : Intl . DateTimeFormat , date : Date ) {
320
+ const d = new Date ( Date . UTC (
321
+ date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) , date . getHours ( ) ,
322
+ date . getMinutes ( ) , date . getSeconds ( ) , date . getMilliseconds ( ) ) ) ;
323
+ return dtf . format ( d ) ;
324
+ }
307
325
}
0 commit comments