Path: blob/trunk/third_party/closure/goog/i18n/datetimeformat.js
2868 views
// Copyright 2006 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Functions for dealing with date/time formatting.16*/171819/**20* Namespace for i18n date/time formatting functions21*/22goog.provide('goog.i18n.DateTimeFormat');23goog.provide('goog.i18n.DateTimeFormat.Format');2425goog.require('goog.asserts');26goog.require('goog.date');27goog.require('goog.i18n.DateTimeSymbols');28goog.require('goog.i18n.TimeZone');29goog.require('goog.string');303132/**33* Datetime formatting functions following the pattern specification as defined34* in JDK, ICU and CLDR, with minor modification for typical usage in JS.35* Pattern specification:36* {@link http://userguide.icu-project.org/formatparse/datetime}37* <pre>38* Symbol Meaning Presentation Example39* ------ ------- ------------ -------40* G# era designator (Text) AD41* y# year (Number) 199642* Y* year (week of year) (Number) 199743* u* extended year (Number) 460144* Q# quarter (Text) Q3 & 3rd quarter45* M month in year (Text & Number) July & 0746* L month in year (standalone) (Text & Number) July & 0747* d day in month (Number) 1048* h hour in am/pm (1~12) (Number) 1249* H hour in day (0~23) (Number) 050* m minute in hour (Number) 3051* s second in minute (Number) 5552* S fractional second (Number) 97853* E# day of week (Text) Tue & Tuesday54* e* day of week (local 1~7) (Number) 255* c# day of week (standalone) (Text & Number) 2 & Tues & Tuesday & T56* D* day in year (Number) 18957* F* day of week in month (Number) 2 (2nd Wed in July)58* w week in year (Number) 2759* W* week in month (Number) 260* a am/pm marker (Text) PM61* k hour in day (1~24) (Number) 2462* K hour in am/pm (0~11) (Number) 063* z time zone (Text) Pacific Standard Time64* Z# time zone (RFC 822) (Number) -080065* v# time zone (generic) (Text) America/Los_Angeles66* V# time zone (Text) Los Angeles Time67* g* Julian day (Number) 245133468* A* milliseconds in day (Number) 6954000069* ' escape for text (Delimiter) 'Date='70* '' single quote (Literal) 'o''clock'71*72* Item marked with '*' are not supported yet.73* Item marked with '#' works different than java74*75* The count of pattern letters determine the format.76* (Text): 4 or more, use full form, <4, use short or abbreviated form if it77* exists. (e.g., "EEEE" produces "Monday", "EEE" produces "Mon")78*79* (Number): the minimum number of digits. Shorter numbers are zero-padded to80* this amount (e.g. if "m" produces "6", "mm" produces "06"). Year is handled81* specially; that is, if the count of 'y' is 2, the Year will be truncated to82* 2 digits. (e.g., if "yyyy" produces "1997", "yy" produces "97".) Unlike other83* fields, fractional seconds are padded on the right with zero.84*85* :(Text & Number) 3 or over, use text, otherwise use number. (e.g., "M"86* produces "1", "MM" produces "01", "MMM" produces "Jan", and "MMMM" produces87* "January".)88*89* Any characters in the pattern that are not in the ranges of ['a'..'z'] and90* ['A'..'Z'] will be treated as quoted text. For instance, characters like ':',91* '.', ' ', '#' and '@' will appear in the resulting time text even they are92* not embraced within single quotes.93* </pre>94*/9596/**97* Construct a DateTimeFormat object based on current locale.98* @constructor99* @param {string|number} pattern pattern specification or pattern type.100* @param {!Object=} opt_dateTimeSymbols Optional symbols to use for this101* instance rather than the global symbols.102* @final103*/104goog.i18n.DateTimeFormat = function(pattern, opt_dateTimeSymbols) {105goog.asserts.assert(goog.isDef(pattern), 'Pattern must be defined');106goog.asserts.assert(107goog.isDef(opt_dateTimeSymbols) || goog.isDef(goog.i18n.DateTimeSymbols),108'goog.i18n.DateTimeSymbols or explicit symbols must be defined');109110this.patternParts_ = [];111112/**113* Data structure that with all the locale info needed for date formatting.114* (day/month names, most common patterns, rules for week-end, etc.)115* @private {!goog.i18n.DateTimeSymbolsType}116*/117this.dateTimeSymbols_ = /** @type {!goog.i18n.DateTimeSymbolsType} */ (118opt_dateTimeSymbols || goog.i18n.DateTimeSymbols);119if (typeof pattern == 'number') {120this.applyStandardPattern_(pattern);121} else {122this.applyPattern_(pattern);123}124};125126127/**128* Enum to identify predefined Date/Time format pattern.129* @enum {number}130*/131goog.i18n.DateTimeFormat.Format = {132FULL_DATE: 0,133LONG_DATE: 1,134MEDIUM_DATE: 2,135SHORT_DATE: 3,136FULL_TIME: 4,137LONG_TIME: 5,138MEDIUM_TIME: 6,139SHORT_TIME: 7,140FULL_DATETIME: 8,141LONG_DATETIME: 9,142MEDIUM_DATETIME: 10,143SHORT_DATETIME: 11144};145146147/**148* regular expression pattern for parsing pattern string149* @type {Array<RegExp>}150* @private151*/152goog.i18n.DateTimeFormat.TOKENS_ = [153// quote string154/^\'(?:[^\']|\'\')*(\'|$)/,155// pattern chars156/^(?:G+|y+|M+|k+|S+|E+|a+|h+|K+|H+|c+|L+|Q+|d+|m+|s+|v+|V+|w+|z+|Z+)/,157// and all the other chars158/^[^\'GyMkSEahKHcLQdmsvVwzZ]+/ // and all the other chars159];160161162/**163* These are token types, corresponding to above token definitions.164* @enum {number}165* @private166*/167goog.i18n.DateTimeFormat.PartTypes_ = {168QUOTED_STRING: 0,169FIELD: 1,170LITERAL: 2171};172173174/**175* @param {!goog.date.DateLike} date176* @return {number}177* @private178*/179goog.i18n.DateTimeFormat.getHours_ = function(date) {180return date.getHours ? date.getHours() : 0;181};182183184/**185* Apply specified pattern to this formatter object.186* @param {string} pattern String specifying how the date should be formatted.187* @private188*/189goog.i18n.DateTimeFormat.prototype.applyPattern_ = function(pattern) {190if (goog.i18n.DateTimeFormat.removeRlmInPatterns_) {191// Remove RLM unicode control character from pattern.192pattern = pattern.replace(/\u200f/g, '');193}194// lex the pattern, once for all uses195while (pattern) {196var previousPattern = pattern;197for (var i = 0; i < goog.i18n.DateTimeFormat.TOKENS_.length; ++i) {198var m = pattern.match(goog.i18n.DateTimeFormat.TOKENS_[i]);199if (m) {200var part = m[0];201pattern = pattern.substring(part.length);202if (i == goog.i18n.DateTimeFormat.PartTypes_.QUOTED_STRING) {203if (part == "''") {204part = "'"; // '' -> '205} else {206part = part.substring(2071,208m[1] == '\'' ? part.length - 1 : part.length); // strip quotes209part = part.replace(/\'\'/g, '\'');210}211}212this.patternParts_.push({text: part, type: i});213break;214}215}216if (previousPattern === pattern) {217// On every iteration, part of the pattern string must be consumed.218throw new Error('Malformed pattern part: ' + pattern);219}220}221};222223224/**225* Format the given date object according to preset pattern and current locale.226* @param {goog.date.DateLike} date The Date object that is being formatted.227* @param {goog.i18n.TimeZone=} opt_timeZone optional, if specified, time228* related fields will be formatted based on its setting. When this field229* is not specified, "undefined" will be pass around and those function230* that really need time zone service will create a default one.231* @return {string} Formatted string for the given date.232* Throws an error if the date is null or if one tries to format a date-only233* object (for instance goog.date.Date) using a pattern with time fields.234*/235goog.i18n.DateTimeFormat.prototype.format = function(date, opt_timeZone) {236if (!date) throw Error('The date to format must be non-null.');237238// We don't want to write code to calculate each date field because we239// want to maximize performance and minimize code size.240// JavaScript only provide API to render local time.241// Suppose target date is: 16:00 GMT-0400242// OS local time is: 12:00 GMT-0800243// We want to create a Local Date Object : 16:00 GMT-0800, and fix the244// time zone display ourselves.245// Thing get a little bit tricky when daylight time transition happens. For246// example, suppose OS timeZone is America/Los_Angeles, it is impossible to247// represent "2006/4/2 02:30" even for those timeZone that has no transition248// at this time. Because 2:00 to 3:00 on that day does not exist in249// America/Los_Angeles time zone. To avoid calculating date field through250// our own code, we uses 3 Date object instead, one for "Year, month, day",251// one for time within that day, and one for timeZone object since it need252// the real time to figure out actual time zone offset.253var diff = opt_timeZone ?254(date.getTimezoneOffset() - opt_timeZone.getOffset(date)) * 60000 :2550;256var dateForDate = diff ? new Date(date.getTime() + diff) : date;257var dateForTime = dateForDate;258// When the time manipulation applied above spans the DST on/off hour, this259// could alter the time incorrectly by adding or subtracting an additional260// hour.261// We can mitigate this by:262// - Adding the difference in timezone offset to the date. This ensures that263// the dateForDate is still within the right day if the extra DST hour264// affected the date.265// - Move the time one day forward if we applied a timezone offset backwards,266// or vice versa. This trick ensures that the time is in the same offset267// as the original date, so we remove the additional hour added or268// subtracted by the DST switch.269if (opt_timeZone &&270dateForDate.getTimezoneOffset() != date.getTimezoneOffset()) {271var dstDiff =272(dateForDate.getTimezoneOffset() - date.getTimezoneOffset()) * 60000;273dateForDate = new Date(dateForDate.getTime() + dstDiff);274275diff += diff > 0 ? -goog.date.MS_PER_DAY : goog.date.MS_PER_DAY;276dateForTime = new Date(date.getTime() + diff);277}278279var out = [];280for (var i = 0; i < this.patternParts_.length; ++i) {281var text = this.patternParts_[i].text;282if (goog.i18n.DateTimeFormat.PartTypes_.FIELD ==283this.patternParts_[i].type) {284out.push(285this.formatField_(286text, date, dateForDate, dateForTime, opt_timeZone));287} else {288out.push(text);289}290}291return out.join('');292};293294295/**296* Apply a predefined pattern as identified by formatType, which is stored in297* locale specific repository.298* @param {number} formatType A number that identified the predefined pattern.299* @private300*/301goog.i18n.DateTimeFormat.prototype.applyStandardPattern_ = function(302formatType) {303var pattern;304if (formatType < 4) {305pattern = this.dateTimeSymbols_.DATEFORMATS[formatType];306} else if (formatType < 8) {307pattern = this.dateTimeSymbols_.TIMEFORMATS[formatType - 4];308} else if (formatType < 12) {309pattern = this.dateTimeSymbols_.DATETIMEFORMATS[formatType - 8];310pattern = pattern.replace(311'{1}', this.dateTimeSymbols_.DATEFORMATS[formatType - 8]);312pattern = pattern.replace(313'{0}', this.dateTimeSymbols_.TIMEFORMATS[formatType - 8]);314} else {315this.applyStandardPattern_(goog.i18n.DateTimeFormat.Format.MEDIUM_DATETIME);316return;317}318this.applyPattern_(pattern);319};320321322/**323* Localizes a string potentially containing numbers, replacing ASCII digits324* with native digits if specified so by the locale. Leaves other characters.325* @param {string} input the string to be localized, using ASCII digits.326* @return {string} localized string, potentially using native digits.327* @private328*/329goog.i18n.DateTimeFormat.prototype.localizeNumbers_ = function(input) {330return goog.i18n.DateTimeFormat.localizeNumbers(input, this.dateTimeSymbols_);331};332333334/**335* If the usage of Ascii digits should be enforced regardless of locale.336* @type {boolean}337* @private338*/339goog.i18n.DateTimeFormat.enforceAsciiDigits_ = false;340341342/**343* If RLM unicode characters should be removed from date/time patterns (useful344* when enforcing ASCII digits for Arabic). See {@code #setEnforceAsciiDigits}.345* @type {boolean}346* @private347*/348goog.i18n.DateTimeFormat.removeRlmInPatterns_ = false;349350351/**352* Sets if the usage of Ascii digits in formatting should be enforced in353* formatted date/time even for locales where native digits are indicated.354* Also sets whether to remove RLM unicode control characters when using355* standard enumerated patterns (they exist e.g. in standard d/M/y for Arabic).356* Production code should call this once before any {@code DateTimeFormat}357* object is instantiated.358* Caveats:359* * Enforcing ASCII digits affects all future formatting by new or existing360* {@code DateTimeFormat} objects.361* * Removal of RLM characters only applies to {@code DateTimeFormat} objects362* instantiated after this call.363* @param {boolean} enforceAsciiDigits Whether Ascii digits should be enforced.364*/365goog.i18n.DateTimeFormat.setEnforceAsciiDigits = function(enforceAsciiDigits) {366goog.i18n.DateTimeFormat.enforceAsciiDigits_ = enforceAsciiDigits;367368// Also setting removal of RLM chracters when forcing ASCII digits since it's369// the right thing to do for Arabic standard patterns. One could add an370// optional argument here or to the {@code DateTimeFormat} constructor to371// enable an alternative behavior.372goog.i18n.DateTimeFormat.removeRlmInPatterns_ = enforceAsciiDigits;373};374375376/**377* @return {boolean} Whether enforcing ASCII digits for all locales. See378* {@code #setEnforceAsciiDigits} for more details.379*/380goog.i18n.DateTimeFormat.isEnforceAsciiDigits = function() {381return goog.i18n.DateTimeFormat.enforceAsciiDigits_;382};383384385/**386* Localizes a string potentially containing numbers, replacing ASCII digits387* with native digits if specified so by the locale. Leaves other characters.388* @param {number|string} input the string to be localized, using ASCII digits.389* @param {!Object=} opt_dateTimeSymbols Optional symbols to use rather than390* the global symbols.391* @return {string} localized string, potentially using native digits.392*/393goog.i18n.DateTimeFormat.localizeNumbers = function(394input, opt_dateTimeSymbols) {395input = String(input);396var dateTimeSymbols = opt_dateTimeSymbols || goog.i18n.DateTimeSymbols;397if (dateTimeSymbols.ZERODIGIT === undefined ||398goog.i18n.DateTimeFormat.enforceAsciiDigits_) {399return input;400}401402var parts = [];403for (var i = 0; i < input.length; i++) {404var c = input.charCodeAt(i);405parts.push(406(0x30 <= c && c <= 0x39) ? // '0' <= c <= '9'407String.fromCharCode(dateTimeSymbols.ZERODIGIT + c - 0x30) :408input.charAt(i));409}410return parts.join('');411};412413414/**415* Formats Era field according to pattern specified.416*417* @param {number} count Number of time pattern char repeats, it controls418* how a field should be formatted.419* @param {!goog.date.DateLike} date It holds the date object to be formatted.420* @return {string} Formatted string that represent this field.421* @private422*/423goog.i18n.DateTimeFormat.prototype.formatEra_ = function(count, date) {424var value = date.getFullYear() > 0 ? 1 : 0;425return count >= 4 ? this.dateTimeSymbols_.ERANAMES[value] :426this.dateTimeSymbols_.ERAS[value];427};428429430/**431* Formats Year field according to pattern specified432* Javascript Date object seems incapable handling 1BC and433* year before. It can show you year 0 which does not exists.434* following we just keep consistent with javascript's435* toString method. But keep in mind those things should be436* unsupported.437* @param {number} count Number of time pattern char repeats, it controls438* how a field should be formatted.439* @param {!goog.date.DateLike} date It holds the date object to be formatted.440* @return {string} Formatted string that represent this field.441* @private442*/443goog.i18n.DateTimeFormat.prototype.formatYear_ = function(count, date) {444var value = date.getFullYear();445if (value < 0) {446value = -value;447}448if (count == 2) {449// See comment about special casing 'yy' at the start of the file, this450// matches ICU and CLDR behaviour. See also:451// http://icu-project.org/apiref/icu4j/com/ibm/icu/text/SimpleDateFormat.html452// http://www.unicode.org/reports/tr35/tr35-dates.html453value = value % 100;454}455return this.localizeNumbers_(goog.string.padNumber(value, count));456};457458459/**460* Formats Month field according to pattern specified461*462* @param {number} count Number of time pattern char repeats, it controls463* how a field should be formatted.464* @param {!goog.date.DateLike} date It holds the date object to be formatted.465* @return {string} Formatted string that represent this field.466* @private467*/468goog.i18n.DateTimeFormat.prototype.formatMonth_ = function(count, date) {469var value = date.getMonth();470switch (count) {471case 5:472return this.dateTimeSymbols_.NARROWMONTHS[value];473case 4:474return this.dateTimeSymbols_.MONTHS[value];475case 3:476return this.dateTimeSymbols_.SHORTMONTHS[value];477default:478return this.localizeNumbers_(goog.string.padNumber(value + 1, count));479}480};481482483/**484* Validates is the goog.date.DateLike object to format has a time.485* DateLike means Date|goog.date.Date, and goog.date.DateTime inherits486* from goog.date.Date. But goog.date.Date does not have time related487* members (getHours, getMinutes, getSeconds).488* Formatting can be done, if there are no time placeholders in the pattern.489*490* @param {!goog.date.DateLike} date the object to validate.491* @private492*/493goog.i18n.DateTimeFormat.validateDateHasTime_ = function(date) {494if (date.getHours && date.getSeconds && date.getMinutes) return;495// if (date instanceof Date || date instanceof goog.date.DateTime)496throw Error(497'The date to format has no time (probably a goog.date.Date). ' +498'Use Date or goog.date.DateTime, or use a pattern without time fields.');499};500501502/**503* Formats (1..24) Hours field according to pattern specified504*505* @param {number} count Number of time pattern char repeats. This controls506* how a field should be formatted.507* @param {!goog.date.DateLike} date It holds the date object to be formatted.508* @return {string} Formatted string that represent this field.509* @private510*/511goog.i18n.DateTimeFormat.prototype.format24Hours_ = function(count, date) {512goog.i18n.DateTimeFormat.validateDateHasTime_(date);513var hours = goog.i18n.DateTimeFormat.getHours_(date) || 24;514return this.localizeNumbers_(goog.string.padNumber(hours, count));515};516517518/**519* Formats Fractional seconds field according to pattern520* specified521*522* @param {number} count Number of time pattern char repeats, it controls523* how a field should be formatted.524* @param {!goog.date.DateLike} date It holds the date object to be formatted.525*526* @return {string} Formatted string that represent this field.527* @private528*/529goog.i18n.DateTimeFormat.prototype.formatFractionalSeconds_ = function(530count, date) {531// Fractional seconds left-justify, append 0 for precision beyond 3532var value = date.getTime() % 1000 / 1000;533return this.localizeNumbers_(534value.toFixed(Math.min(3, count)).substr(2) +535(count > 3 ? goog.string.padNumber(0, count - 3) : ''));536};537538539/**540* Formats Day of week field according to pattern specified541*542* @param {number} count Number of time pattern char repeats, it controls543* how a field should be formatted.544* @param {!goog.date.DateLike} date It holds the date object to be formatted.545* @return {string} Formatted string that represent this field.546* @private547*/548goog.i18n.DateTimeFormat.prototype.formatDayOfWeek_ = function(count, date) {549var value = date.getDay();550return count >= 4 ? this.dateTimeSymbols_.WEEKDAYS[value] :551this.dateTimeSymbols_.SHORTWEEKDAYS[value];552};553554555/**556* Formats Am/Pm field according to pattern specified557*558* @param {number} count Number of time pattern char repeats, it controls559* how a field should be formatted.560* @param {!goog.date.DateLike} date It holds the date object to be formatted.561* @return {string} Formatted string that represent this field.562* @private563*/564goog.i18n.DateTimeFormat.prototype.formatAmPm_ = function(count, date) {565goog.i18n.DateTimeFormat.validateDateHasTime_(date);566var hours = goog.i18n.DateTimeFormat.getHours_(date);567return this.dateTimeSymbols_.AMPMS[hours >= 12 && hours < 24 ? 1 : 0];568};569570571/**572* Formats (1..12) Hours field according to pattern specified573*574* @param {number} count Number of time pattern char repeats, it controls575* how a field should be formatted.576* @param {!goog.date.DateLike} date It holds the date object to be formatted.577* @return {string} formatted string that represent this field.578* @private579*/580goog.i18n.DateTimeFormat.prototype.format1To12Hours_ = function(count, date) {581goog.i18n.DateTimeFormat.validateDateHasTime_(date);582var hours = goog.i18n.DateTimeFormat.getHours_(date) % 12 || 12;583return this.localizeNumbers_(goog.string.padNumber(hours, count));584};585586587/**588* Formats (0..11) Hours field according to pattern specified589*590* @param {number} count Number of time pattern char repeats, it controls591* how a field should be formatted.592* @param {!goog.date.DateLike} date It holds the date object to be formatted.593* @return {string} formatted string that represent this field.594* @private595*/596goog.i18n.DateTimeFormat.prototype.format0To11Hours_ = function(count, date) {597goog.i18n.DateTimeFormat.validateDateHasTime_(date);598var hours = goog.i18n.DateTimeFormat.getHours_(date) % 12;599return this.localizeNumbers_(goog.string.padNumber(hours, count));600};601602603/**604* Formats (0..23) Hours field according to pattern specified605*606* @param {number} count Number of time pattern char repeats, it controls607* how a field should be formatted.608* @param {!goog.date.DateLike} date It holds the date object to be formatted.609* @return {string} formatted string that represent this field.610* @private611*/612goog.i18n.DateTimeFormat.prototype.format0To23Hours_ = function(count, date) {613goog.i18n.DateTimeFormat.validateDateHasTime_(date);614var hours = goog.i18n.DateTimeFormat.getHours_(date);615return this.localizeNumbers_(goog.string.padNumber(hours, count));616};617618619/**620* Formats Standalone weekday field according to pattern specified621*622* @param {number} count Number of time pattern char repeats, it controls623* how a field should be formatted.624* @param {!goog.date.DateLike} date It holds the date object to be formatted.625* @return {string} formatted string that represent this field.626* @private627*/628goog.i18n.DateTimeFormat.prototype.formatStandaloneDay_ = function(629count, date) {630var value = date.getDay();631switch (count) {632case 5:633return this.dateTimeSymbols_.STANDALONENARROWWEEKDAYS[value];634case 4:635return this.dateTimeSymbols_.STANDALONEWEEKDAYS[value];636case 3:637return this.dateTimeSymbols_.STANDALONESHORTWEEKDAYS[value];638default:639return this.localizeNumbers_(goog.string.padNumber(value, 1));640}641};642643644/**645* Formats Standalone Month field according to pattern specified646*647* @param {number} count Number of time pattern char repeats, it controls648* how a field should be formatted.649* @param {!goog.date.DateLike} date It holds the date object to be formatted.650* @return {string} formatted string that represent this field.651* @private652*/653goog.i18n.DateTimeFormat.prototype.formatStandaloneMonth_ = function(654count, date) {655var value = date.getMonth();656switch (count) {657case 5:658return this.dateTimeSymbols_.STANDALONENARROWMONTHS[value];659case 4:660return this.dateTimeSymbols_.STANDALONEMONTHS[value];661case 3:662return this.dateTimeSymbols_.STANDALONESHORTMONTHS[value];663default:664return this.localizeNumbers_(goog.string.padNumber(value + 1, count));665}666};667668669/**670* Formats Quarter field according to pattern specified671*672* @param {number} count Number of time pattern char repeats, it controls673* how a field should be formatted.674* @param {!goog.date.DateLike} date It holds the date object to be formatted.675* @return {string} Formatted string that represent this field.676* @private677*/678goog.i18n.DateTimeFormat.prototype.formatQuarter_ = function(count, date) {679var value = Math.floor(date.getMonth() / 3);680return count < 4 ? this.dateTimeSymbols_.SHORTQUARTERS[value] :681this.dateTimeSymbols_.QUARTERS[value];682};683684685/**686* Formats Date field according to pattern specified687*688* @param {number} count Number of time pattern char repeats, it controls689* how a field should be formatted.690* @param {!goog.date.DateLike} date It holds the date object to be formatted.691* @return {string} Formatted string that represent this field.692* @private693*/694goog.i18n.DateTimeFormat.prototype.formatDate_ = function(count, date) {695return this.localizeNumbers_(goog.string.padNumber(date.getDate(), count));696};697698699/**700* Formats Minutes field according to pattern specified701*702* @param {number} count Number of time pattern char repeats, it controls703* how a field should be formatted.704* @param {!goog.date.DateLike} date It holds the date object to be formatted.705* @return {string} Formatted string that represent this field.706* @private707*/708goog.i18n.DateTimeFormat.prototype.formatMinutes_ = function(count, date) {709goog.i18n.DateTimeFormat.validateDateHasTime_(date);710return this.localizeNumbers_(711goog.string.padNumber(712/** @type {!goog.date.DateTime} */ (date).getMinutes(), count));713};714715716/**717* Formats Seconds field according to pattern specified718*719* @param {number} count Number of time pattern char repeats, it controls720* how a field should be formatted.721* @param {!goog.date.DateLike} date It holds the date object to be formatted.722* @return {string} Formatted string that represent this field.723* @private724*/725goog.i18n.DateTimeFormat.prototype.formatSeconds_ = function(count, date) {726goog.i18n.DateTimeFormat.validateDateHasTime_(date);727return this.localizeNumbers_(728goog.string.padNumber(729/** @type {!goog.date.DateTime} */ (date).getSeconds(), count));730};731732733/**734* Formats the week of year field according to pattern specified735*736* @param {number} count Number of time pattern char repeats, it controls737* how a field should be formatted.738* @param {!goog.date.DateLike} date It holds the date object to be formatted.739* @return {string} Formatted string that represent this field.740* @private741*/742goog.i18n.DateTimeFormat.prototype.formatWeekOfYear_ = function(count, date) {743744745var weekNum = goog.date.getWeekNumber(746date.getFullYear(), date.getMonth(), date.getDate(),747this.dateTimeSymbols_.FIRSTWEEKCUTOFFDAY,748this.dateTimeSymbols_.FIRSTDAYOFWEEK);749750return this.localizeNumbers_(goog.string.padNumber(weekNum, count));751};752753754/**755* Formats TimeZone field following RFC756*757* @param {number} count Number of time pattern char repeats, it controls758* how a field should be formatted.759* @param {!goog.date.DateLike} date It holds the date object to be formatted.760* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.761* @return {string} Formatted string that represent this field.762* @private763*/764goog.i18n.DateTimeFormat.prototype.formatTimeZoneRFC_ = function(765count, date, opt_timeZone) {766opt_timeZone = opt_timeZone ||767goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());768769// RFC 822 formats should be kept in ASCII, but localized GMT formats may need770// to use native digits.771return count < 4 ? opt_timeZone.getRFCTimeZoneString(date) :772this.localizeNumbers_(opt_timeZone.getGMTString(date));773};774775776/**777* Generate GMT timeZone string for given date778* @param {number} count Number of time pattern char repeats, it controls779* how a field should be formatted.780* @param {!goog.date.DateLike} date Whose value being evaluated.781* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.782* @return {string} GMT timeZone string.783* @private784*/785goog.i18n.DateTimeFormat.prototype.formatTimeZone_ = function(786count, date, opt_timeZone) {787opt_timeZone = opt_timeZone ||788goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());789return count < 4 ? opt_timeZone.getShortName(date) :790opt_timeZone.getLongName(date);791};792793794/**795* Generate GMT timeZone string for given date796* @param {!goog.date.DateLike} date Whose value being evaluated.797* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.798* @return {string} GMT timeZone string.799* @private800*/801goog.i18n.DateTimeFormat.prototype.formatTimeZoneId_ = function(802date, opt_timeZone) {803opt_timeZone = opt_timeZone ||804goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());805return opt_timeZone.getTimeZoneId();806};807808809/**810* Generate localized, location dependent time zone id811* @param {number} count Number of time pattern char repeats, it controls812* how a field should be formatted.813* @param {!goog.date.DateLike} date Whose value being evaluated.814* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.815* @return {string} GMT timeZone string.816* @private817*/818goog.i18n.DateTimeFormat.prototype.formatTimeZoneLocationId_ = function(819count, date, opt_timeZone) {820opt_timeZone = opt_timeZone ||821goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());822return count <= 2 ? opt_timeZone.getTimeZoneId() :823opt_timeZone.getGenericLocation(date);824};825826827/**828* Formatting one date field.829* @param {string} patternStr The pattern string for the field being formatted.830* @param {!goog.date.DateLike} date represents the real date to be formatted.831* @param {!goog.date.DateLike} dateForDate used to resolve date fields832* for formatting.833* @param {!goog.date.DateLike} dateForTime used to resolve time fields834* for formatting.835* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.836* @return {string} string representation for the given field.837* @private838*/839goog.i18n.DateTimeFormat.prototype.formatField_ = function(840patternStr, date, dateForDate, dateForTime, opt_timeZone) {841var count = patternStr.length;842switch (patternStr.charAt(0)) {843case 'G':844return this.formatEra_(count, dateForDate);845case 'y':846return this.formatYear_(count, dateForDate);847case 'M':848return this.formatMonth_(count, dateForDate);849case 'k':850return this.format24Hours_(count, dateForTime);851case 'S':852return this.formatFractionalSeconds_(count, dateForTime);853case 'E':854return this.formatDayOfWeek_(count, dateForDate);855case 'a':856return this.formatAmPm_(count, dateForTime);857case 'h':858return this.format1To12Hours_(count, dateForTime);859case 'K':860return this.format0To11Hours_(count, dateForTime);861case 'H':862return this.format0To23Hours_(count, dateForTime);863case 'c':864return this.formatStandaloneDay_(count, dateForDate);865case 'L':866return this.formatStandaloneMonth_(count, dateForDate);867case 'Q':868return this.formatQuarter_(count, dateForDate);869case 'd':870return this.formatDate_(count, dateForDate);871case 'm':872return this.formatMinutes_(count, dateForTime);873case 's':874return this.formatSeconds_(count, dateForTime);875case 'v':876return this.formatTimeZoneId_(date, opt_timeZone);877case 'V':878return this.formatTimeZoneLocationId_(count, date, opt_timeZone);879case 'w':880return this.formatWeekOfYear_(count, dateForTime);881case 'z':882return this.formatTimeZone_(count, date, opt_timeZone);883case 'Z':884return this.formatTimeZoneRFC_(count, date, opt_timeZone);885default:886return '';887}888};889890891