Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/i18n/timezone.js
2868 views
1
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Functions to provide timezone information for use with
17
* date/time format.
18
*/
19
20
goog.provide('goog.i18n.TimeZone');
21
22
goog.require('goog.array');
23
/** @suppress {extraRequire} goog.date.DateLike represents a Date or a
24
* goog.Date object. It is a parameter in the following methods:
25
* - getDaylightAdjustment
26
* - getGMTString
27
* - getLongName
28
* - getOffset
29
* - getRFCTimeZoneString
30
* - getShortName
31
* - isDaylightTime
32
* - getLongNameGMT
33
* - getGenericLocation
34
* Lint warns that this require is unnecessary but the closure compiler needs
35
* it in order to accept a Date or a goog.Date object as a goog.date.DateLike
36
* parameter in any of these methods. */
37
goog.require('goog.date.DateLike');
38
goog.require('goog.object');
39
goog.require('goog.string');
40
41
42
43
/**
44
* TimeZone class implemented a time zone resolution and name information
45
* source for client applications. The time zone object is initiated from
46
* a time zone information object. Application can initiate a time zone
47
* statically, or it may choose to initiate from a data obtained from server.
48
* Each time zone information array is small, but the whole set of data
49
* is too much for client application to download. If end user is allowed to
50
* change time zone setting, dynamic retrieval should be the method to use.
51
* In case only time zone offset is known, there is a decent fallback
52
* that only use the time zone offset to create a TimeZone object.
53
* A whole set of time zone information array was available under
54
* http://go/js_locale_data. It is generated based on CLDR/ICU and
55
* Olson time zone data base, and will be updated timely.
56
*
57
* @constructor
58
* @final
59
*/
60
goog.i18n.TimeZone = function() {
61
/**
62
* The standard time zone id.
63
* @type {string}
64
* @private
65
*/
66
this.timeZoneId_;
67
68
69
/**
70
* The standard, non-daylight time zone offset, in minutes WEST of UTC.
71
* @type {number}
72
* @private
73
*/
74
this.standardOffset_;
75
76
77
/**
78
* An array of strings that can have 2 or 4 elements. The first two elements
79
* are the long and short names for standard time in this time zone, and the
80
* last two elements (if present) are the long and short names for daylight
81
* time in this time zone.
82
* @type {Array<string>}
83
* @private
84
*/
85
this.tzNames_;
86
87
88
/**
89
* An object of 2 to 4 elements. The STD_* are always available, while the
90
* DST_* are only available when daylight saving time is available for this
91
* time zone.
92
* <ul>
93
* <li>STD_LONG_NAME_GMT: long GMT name for standard time</li>
94
* <li>STD_GENERIC_LOCATION: generic location for standard time</li>
95
* <li>DST_LONG_NAME_GMT: long GMT for daylight saving time</li>
96
* <li>DST_GENERIC_LOCATION: generic location for daylight saving time</li>
97
* </ul>
98
* @type { { STD_LONG_NAME_GMT:string, STD_GENERIC_LOCATION:string } |
99
* { STD_LONG_NAME_GMT:string, STD_GENERIC_LOCATION:string,
100
* DST_LONG_NAME_GMT:string, DST_GENERIC_LOCATION:string }
101
* }
102
* @private
103
*/
104
this.tzNamesExt_;
105
106
107
/**
108
* This array specifies the Daylight Saving Time transitions for this time
109
* zone. This is a flat array of numbers which are interpreted in pairs:
110
* [time1, adjustment1, time2, adjustment2, ...] where each time is a DST
111
* transition point given as a number of hours since 00:00 UTC, January 1,
112
* 1970, and each adjustment is the adjustment to apply for times after the
113
* DST transition, given as minutes EAST of UTC.
114
* @type {Array<number>}
115
* @private
116
*/
117
this.transitions_;
118
};
119
120
121
/**
122
* The number of milliseconds in an hour.
123
* @type {number}
124
* @private
125
*/
126
goog.i18n.TimeZone.MILLISECONDS_PER_HOUR_ = 3600 * 1000;
127
128
129
/**
130
* Indices into the array of time zone names.
131
* @enum {number}
132
*/
133
goog.i18n.TimeZone.NameType = {
134
STD_SHORT_NAME: 0,
135
STD_LONG_NAME: 1,
136
DLT_SHORT_NAME: 2,
137
DLT_LONG_NAME: 3
138
};
139
140
141
/**
142
* This factory method creates a time zone instance. It takes either an object
143
* containing complete time zone information, or a single number representing a
144
* constant time zone offset. If the latter form is used, DST functionality is
145
* not available.
146
*
147
* @param {number|Object} timeZoneData If this parameter is a number, it should
148
* indicate minutes WEST of UTC to be used as a constant time zone offset.
149
* Otherwise, it should be an object with these four fields:
150
* <ul>
151
* <li>id: A string ID for the time zone.
152
* <li>std_offset: The standard time zone offset in minutes EAST of UTC.
153
* <li>names: An array of four names (standard short name, standard long
154
* name, daylight short name, daylight long, name)
155
* <li>names_ext: A hash of four fields (standard long name gmt, daylight
156
* long name gmt, standard generic location, daylight generic
157
* location)
158
* <li>transitions: An array of numbers which are interpreted in pairs:
159
* [time1, adjustment1, time2, adjustment2, ...] where each time is
160
* a DST transition point given as a number of hours since 00:00 UTC,
161
* January 1, 1970, and each adjustment is the adjustment to apply
162
* for times after the DST transition, given as minutes EAST of UTC.
163
* </ul>
164
* @return {!goog.i18n.TimeZone} A goog.i18n.TimeZone object for the given
165
* time zone data.
166
*/
167
goog.i18n.TimeZone.createTimeZone = function(timeZoneData) {
168
if (typeof timeZoneData == 'number') {
169
return goog.i18n.TimeZone.createSimpleTimeZone_(timeZoneData);
170
}
171
var tz = new goog.i18n.TimeZone();
172
tz.timeZoneId_ = timeZoneData['id'];
173
tz.standardOffset_ = -timeZoneData['std_offset'];
174
tz.tzNames_ = timeZoneData['names'];
175
tz.tzNamesExt_ = timeZoneData['names_ext'];
176
tz.transitions_ = timeZoneData['transitions'];
177
return tz;
178
};
179
180
181
/**
182
* This factory method creates a time zone object with a constant offset.
183
* @param {number} timeZoneOffsetInMinutes Offset in minutes WEST of UTC.
184
* @return {!goog.i18n.TimeZone} A time zone object with the given constant
185
* offset. Note that the time zone ID of this object will use the POSIX
186
* convention, which has a reversed sign ("Etc/GMT+8" means UTC-8 or PST).
187
* @private
188
*/
189
goog.i18n.TimeZone.createSimpleTimeZone_ = function(timeZoneOffsetInMinutes) {
190
var tz = new goog.i18n.TimeZone();
191
tz.standardOffset_ = timeZoneOffsetInMinutes;
192
tz.timeZoneId_ =
193
goog.i18n.TimeZone.composePosixTimeZoneID_(timeZoneOffsetInMinutes);
194
var str = goog.i18n.TimeZone.composeUTCString_(timeZoneOffsetInMinutes);
195
var strGMT = goog.i18n.TimeZone.composeGMTString_(timeZoneOffsetInMinutes);
196
tz.tzNames_ = [str, str];
197
tz.tzNamesExt_ = {STD_LONG_NAME_GMT: strGMT, STD_GENERIC_LOCATION: strGMT};
198
tz.transitions_ = [];
199
return tz;
200
};
201
202
203
/**
204
* Generate a GMT-relative string for a constant time zone offset.
205
* @param {number} offset The time zone offset in minutes WEST of UTC.
206
* @return {string} The GMT string for this offset, which will indicate
207
* hours EAST of UTC.
208
* @private
209
*/
210
goog.i18n.TimeZone.composeGMTString_ = function(offset) {
211
var parts = ['GMT'];
212
parts.push(offset <= 0 ? '+' : '-');
213
offset = Math.abs(offset);
214
parts.push(
215
goog.string.padNumber(Math.floor(offset / 60) % 100, 2), ':',
216
goog.string.padNumber(offset % 60, 2));
217
return parts.join('');
218
};
219
220
221
/**
222
* Generate a POSIX time zone ID for a constant time zone offset.
223
* @param {number} offset The time zone offset in minutes WEST of UTC.
224
* @return {string} The POSIX time zone ID for this offset, which will indicate
225
* hours WEST of UTC.
226
* @private
227
*/
228
goog.i18n.TimeZone.composePosixTimeZoneID_ = function(offset) {
229
if (offset == 0) {
230
return 'Etc/GMT';
231
}
232
var parts = ['Etc/GMT', offset < 0 ? '-' : '+'];
233
offset = Math.abs(offset);
234
parts.push(Math.floor(offset / 60) % 100);
235
offset = offset % 60;
236
if (offset != 0) {
237
parts.push(':', goog.string.padNumber(offset, 2));
238
}
239
return parts.join('');
240
};
241
242
243
/**
244
* Generate a UTC-relative string for a constant time zone offset.
245
* @param {number} offset The time zone offset in minutes WEST of UTC.
246
* @return {string} The UTC string for this offset, which will indicate
247
* hours EAST of UTC.
248
* @private
249
*/
250
goog.i18n.TimeZone.composeUTCString_ = function(offset) {
251
if (offset == 0) {
252
return 'UTC';
253
}
254
var parts = ['UTC', offset < 0 ? '+' : '-'];
255
offset = Math.abs(offset);
256
parts.push(Math.floor(offset / 60) % 100);
257
offset = offset % 60;
258
if (offset != 0) {
259
parts.push(':', offset);
260
}
261
return parts.join('');
262
};
263
264
265
/**
266
* Convert the contents of time zone object to a timeZoneData object, suitable
267
* for passing to goog.i18n.TimeZone.createTimeZone.
268
* @return {!Object} A timeZoneData object (see the documentation for
269
* goog.i18n.TimeZone.createTimeZone).
270
*/
271
goog.i18n.TimeZone.prototype.getTimeZoneData = function() {
272
return {
273
'id': this.timeZoneId_,
274
'std_offset': -this.standardOffset_, // note createTimeZone flips the sign
275
'names': goog.array.clone(this.tzNames_), // avoid aliasing the array
276
'names_ext': goog.object.clone(this.tzNamesExt_), // avoid aliasing
277
'transitions': goog.array.clone(this.transitions_) // avoid aliasing
278
};
279
};
280
281
282
/**
283
* Return the DST adjustment to the time zone offset for a given time.
284
* While Daylight Saving Time is in effect, this number is positive.
285
* Otherwise, it is zero.
286
* @param {goog.date.DateLike} date The time to check.
287
* @return {number} The DST adjustment in minutes EAST of UTC.
288
*/
289
goog.i18n.TimeZone.prototype.getDaylightAdjustment = function(date) {
290
var timeInMs = Date.UTC(
291
date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
292
date.getUTCHours(), date.getUTCMinutes());
293
var timeInHours = timeInMs / goog.i18n.TimeZone.MILLISECONDS_PER_HOUR_;
294
var index = 0;
295
while (index < this.transitions_.length &&
296
timeInHours >= this.transitions_[index]) {
297
index += 2;
298
}
299
return (index == 0) ? 0 : this.transitions_[index - 1];
300
};
301
302
303
/**
304
* Return the GMT representation of this time zone object.
305
* @param {goog.date.DateLike} date The date for which time to retrieve
306
* GMT string.
307
* @return {string} GMT representation string.
308
*/
309
goog.i18n.TimeZone.prototype.getGMTString = function(date) {
310
return goog.i18n.TimeZone.composeGMTString_(this.getOffset(date));
311
};
312
313
314
/**
315
* Get the long time zone name for a given date/time.
316
* @param {goog.date.DateLike} date The time for which to retrieve
317
* the long time zone name.
318
* @return {string} The long time zone name.
319
*/
320
goog.i18n.TimeZone.prototype.getLongName = function(date) {
321
return this.tzNames_[this.isDaylightTime(date) ?
322
goog.i18n.TimeZone.NameType.DLT_LONG_NAME :
323
goog.i18n.TimeZone.NameType.STD_LONG_NAME];
324
};
325
326
327
/**
328
* Get the time zone offset in minutes WEST of UTC for a given date/time.
329
* @param {goog.date.DateLike} date The time for which to retrieve
330
* the time zone offset.
331
* @return {number} The time zone offset in minutes WEST of UTC.
332
*/
333
goog.i18n.TimeZone.prototype.getOffset = function(date) {
334
return this.standardOffset_ - this.getDaylightAdjustment(date);
335
};
336
337
338
/**
339
* Get the RFC representation of the time zone for a given date/time.
340
* @param {goog.date.DateLike} date The time for which to retrieve the
341
* RFC time zone string.
342
* @return {string} The RFC time zone string.
343
*/
344
goog.i18n.TimeZone.prototype.getRFCTimeZoneString = function(date) {
345
var offset = -this.getOffset(date);
346
var parts = [offset < 0 ? '-' : '+'];
347
offset = Math.abs(offset);
348
parts.push(
349
goog.string.padNumber(Math.floor(offset / 60) % 100, 2),
350
goog.string.padNumber(offset % 60, 2));
351
return parts.join('');
352
};
353
354
355
/**
356
* Get the short time zone name for given date/time.
357
* @param {goog.date.DateLike} date The time for which to retrieve
358
* the short time zone name.
359
* @return {string} The short time zone name.
360
*/
361
goog.i18n.TimeZone.prototype.getShortName = function(date) {
362
return this.tzNames_[this.isDaylightTime(date) ?
363
goog.i18n.TimeZone.NameType.DLT_SHORT_NAME :
364
goog.i18n.TimeZone.NameType.STD_SHORT_NAME];
365
};
366
367
368
/**
369
* Return the time zone ID for this time zone.
370
* @return {string} The time zone ID.
371
*/
372
goog.i18n.TimeZone.prototype.getTimeZoneId = function() {
373
return this.timeZoneId_;
374
};
375
376
377
/**
378
* Check if Daylight Saving Time is in effect at a given time in this time zone.
379
* @param {goog.date.DateLike} date The time to check.
380
* @return {boolean} True if Daylight Saving Time is in effect.
381
*/
382
goog.i18n.TimeZone.prototype.isDaylightTime = function(date) {
383
return this.getDaylightAdjustment(date) > 0;
384
};
385
386
387
/**
388
* Get the long GMT time zone name for a given date/time.
389
* @param {!goog.date.DateLike} date The time for which to retrieve
390
* the long GMT time zone name.
391
* @return {string} The long GMT time zone name.
392
*/
393
goog.i18n.TimeZone.prototype.getLongNameGMT = function(date) {
394
if (this.isDaylightTime(date)) {
395
return (goog.isDef(this.tzNamesExt_.DST_LONG_NAME_GMT)) ?
396
this.tzNamesExt_.DST_LONG_NAME_GMT :
397
this.tzNamesExt_['DST_LONG_NAME_GMT'];
398
} else {
399
return (goog.isDef(this.tzNamesExt_.STD_LONG_NAME_GMT)) ?
400
this.tzNamesExt_.STD_LONG_NAME_GMT :
401
this.tzNamesExt_['STD_LONG_NAME_GMT'];
402
}
403
};
404
405
406
/**
407
* Get the generic location time zone name for a given date/time.
408
* @param {!goog.date.DateLike} date The time for which to retrieve
409
* the generic location time zone name.
410
* @return {string} The generic location time zone name.
411
*/
412
goog.i18n.TimeZone.prototype.getGenericLocation = function(date) {
413
if (this.isDaylightTime(date)) {
414
return (goog.isDef(this.tzNamesExt_.DST_GENERIC_LOCATION)) ?
415
this.tzNamesExt_.DST_GENERIC_LOCATION :
416
this.tzNamesExt_['DST_GENERIC_LOCATION'];
417
} else {
418
return (goog.isDef(this.tzNamesExt_.STD_GENERIC_LOCATION)) ?
419
this.tzNamesExt_.STD_GENERIC_LOCATION :
420
this.tzNamesExt_['STD_GENERIC_LOCATION'];
421
}
422
};
423
424