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