Path: blob/trunk/third_party/closure/goog/date/date.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 and objects for date representation and manipulation.16*17* @author [email protected] (Emil A Eklund)18*/1920goog.provide('goog.date');21goog.provide('goog.date.Date');22goog.provide('goog.date.DateTime');23goog.provide('goog.date.Interval');24goog.provide('goog.date.month');25goog.provide('goog.date.weekDay');2627goog.require('goog.asserts');28/** @suppress {extraRequire} */29goog.require('goog.date.DateLike');30goog.require('goog.i18n.DateTimeSymbols');31goog.require('goog.string');323334/**35* Constants for weekdays.36* @enum {number}37*/38goog.date.weekDay = {39MON: 0,40TUE: 1,41WED: 2,42THU: 3,43FRI: 4,44SAT: 5,45SUN: 646};474849/**50* Constants for months.51* @enum {number}52*/53goog.date.month = {54JAN: 0,55FEB: 1,56MAR: 2,57APR: 3,58MAY: 4,59JUN: 5,60JUL: 6,61AUG: 7,62SEP: 8,63OCT: 9,64NOV: 10,65DEC: 1166};676869/**70* Formats a month/year string.71* Example: "January 2008"72*73* @param {string} monthName The month name to use in the result.74* @param {number} yearNum The numeric year to use in the result.75* @return {string} A formatted month/year string.76*/77goog.date.formatMonthAndYear = function(monthName, yearNum) {78/** @desc Month/year format given the month name and the numeric year. */79var MSG_MONTH_AND_YEAR = goog.getMsg(80'{$monthName} {$yearNum}',81{'monthName': monthName, 'yearNum': String(yearNum)});82return MSG_MONTH_AND_YEAR;83};848586/**87* Regular expression for splitting date parts from ISO 8601 styled string.88* Examples: '20060210' or '2005-02-22' or '20050222' or '2005-08'89* or '2005-W22' or '2005W22' or '2005-W22-4', etc.90* For explanation and more examples, see:91* {@link http://en.wikipedia.org/wiki/ISO_8601}92*93* @type {RegExp}94* @private95*/96goog.date.splitDateStringRegex_ = new RegExp(97'^(\\d{4})(?:(?:-?(\\d{2})(?:-?(\\d{2}))?)|' +98'(?:-?(\\d{3}))|(?:-?W(\\d{2})(?:-?([1-7]))?))?$');99100101/**102* Regular expression for splitting time parts from ISO 8601 styled string.103* Examples: '18:46:39.994' or '184639.994'104*105* @type {RegExp}106* @private107*/108goog.date.splitTimeStringRegex_ =109/^(\d{2})(?::?(\d{2})(?::?(\d{2})(\.\d+)?)?)?$/;110111112/**113* Regular expression for splitting timezone parts from ISO 8601 styled string.114* Example: The part after the '+' in '18:46:39+07:00'. Or '09:30Z' (UTC).115*116* @type {RegExp}117* @private118*/119goog.date.splitTimezoneStringRegex_ = /Z|(?:([-+])(\d{2})(?::?(\d{2}))?)$/;120121122/**123* Regular expression for splitting duration parts from ISO 8601 styled string.124* Example: '-P1Y2M3DT4H5M6.7S'125*126* @type {RegExp}127* @private128*/129goog.date.splitDurationRegex_ = new RegExp(130'^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?' +131'(T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$');132133134/**135* Number of milliseconds in a day.136* @type {number}137*/138goog.date.MS_PER_DAY = 24 * 60 * 60 * 1000;139140141/**142* Returns whether the given year is a leap year.143*144* @param {number} year Year part of date.145* @return {boolean} Whether the given year is a leap year.146*/147goog.date.isLeapYear = function(year) {148// Leap year logic; the 4-100-400 rule149return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);150};151152153/**154* Returns whether the given year is a long ISO year.155* See {@link http://www.phys.uu.nl/~vgent/calendar/isocalendar_text3.htm}.156*157* @param {number} year Full year part of date.158* @return {boolean} Whether the given year is a long ISO year.159*/160goog.date.isLongIsoYear = function(year) {161var n = 5 * year + 12 - 4 * (Math.floor(year / 100) - Math.floor(year / 400));162n += Math.floor((year - 100) / 400) - Math.floor((year - 102) / 400);163n += Math.floor((year - 200) / 400) - Math.floor((year - 199) / 400);164165return n % 28 < 5;166};167168169/**170* Returns the number of days for a given month.171*172* @param {number} year Year part of date.173* @param {number} month Month part of date.174* @return {number} The number of days for the given month.175*/176goog.date.getNumberOfDaysInMonth = function(year, month) {177switch (month) {178case goog.date.month.FEB:179return goog.date.isLeapYear(year) ? 29 : 28;180case goog.date.month.JUN:181case goog.date.month.SEP:182case goog.date.month.NOV:183case goog.date.month.APR:184return 30;185}186return 31;187};188189190/**191* Returns true if the 2 dates are in the same day.192* @param {goog.date.DateLike} date The time to check.193* @param {goog.date.DateLike=} opt_now The current time.194* @return {boolean} Whether the dates are on the same day.195*/196goog.date.isSameDay = function(date, opt_now) {197var now = opt_now || new Date(goog.now());198return date.getDate() == now.getDate() && goog.date.isSameMonth(date, now);199};200201202/**203* Returns true if the 2 dates are in the same month.204* @param {goog.date.DateLike} date The time to check.205* @param {goog.date.DateLike=} opt_now The current time.206* @return {boolean} Whether the dates are in the same calendar month.207*/208goog.date.isSameMonth = function(date, opt_now) {209var now = opt_now || new Date(goog.now());210return date.getMonth() == now.getMonth() && goog.date.isSameYear(date, now);211};212213214/**215* Returns true if the 2 dates are in the same year.216* @param {goog.date.DateLike} date The time to check.217* @param {goog.date.DateLike=} opt_now The current time.218* @return {boolean} Whether the dates are in the same calendar year.219*/220goog.date.isSameYear = function(date, opt_now) {221var now = opt_now || new Date(goog.now());222return date.getFullYear() == now.getFullYear();223};224225226/**227* Static function for week number calculation. ISO 8601 implementation.228*229* @param {number} year Year part of date.230* @param {number} month Month part of date (0-11).231* @param {number} date Day part of date (1-31).232* @param {number=} opt_weekDay Cut off weekday, defaults to Thursday.233* @param {number=} opt_firstDayOfWeek First day of the week, defaults to234* Monday.235* Monday=0, Sunday=6.236* @return {number} The week number (1-53).237*/238goog.date.getWeekNumber = function(239year, month, date, opt_weekDay, opt_firstDayOfWeek) {240var d = new Date(year, month, date);241242// Default to Thursday for cut off as per ISO 8601.243var cutoff = goog.isDef(opt_weekDay) ? opt_weekDay : goog.date.weekDay.THU;244245// Default to Monday for first day of the week as per ISO 8601.246var firstday = opt_firstDayOfWeek || goog.date.weekDay.MON;247248// The d.getDay() has to be converted first to ISO weekday (Monday=0).249var isoday = (d.getDay() + 6) % 7;250251// Position of given day in the picker grid w.r.t. first day of week252var daypos = (isoday - firstday + 7) % 7;253254// Position of cut off day in the picker grid w.r.t. first day of week255var cutoffpos = (cutoff - firstday + 7) % 7;256257// Unix timestamp of the midnight of the cutoff day in the week of 'd'.258// There might be +-1 hour shift in the result due to the daylight saving,259// but it doesn't affect the year.260var cutoffSameWeek =261d.valueOf() + (cutoffpos - daypos) * goog.date.MS_PER_DAY;262263// Unix timestamp of January 1 in the year of 'cutoffSameWeek'.264var jan1 = new Date(new Date(cutoffSameWeek).getFullYear(), 0, 1).valueOf();265266// Number of week. The round() eliminates the effect of daylight saving.267return Math.floor(268Math.round((cutoffSameWeek - jan1) / goog.date.MS_PER_DAY) / 7) +2691;270};271272273/**274* @param {T} date1 A datelike object.275* @param {S} date2 Another datelike object.276* @return {T|S} The earlier of them in time.277* @template T,S278*/279goog.date.min = function(date1, date2) {280return date1 < date2 ? date1 : date2;281};282283284/**285* @param {T} date1 A datelike object.286* @param {S} date2 Another datelike object.287* @return {T|S} The later of them in time.288* @template T,S289*/290goog.date.max = function(date1, date2) {291return date1 > date2 ? date1 : date2;292};293294295/**296* Creates a DateTime from a datetime string expressed in ISO 8601 format.297*298* @param {string} formatted A date or datetime expressed in ISO 8601 format.299* @return {goog.date.DateTime} Parsed date or null if parse fails.300*/301goog.date.fromIsoString = function(formatted) {302var ret = new goog.date.DateTime(2000);303return goog.date.setIso8601DateTime(ret, formatted) ? ret : null;304};305306307/**308* Parses a datetime string expressed in ISO 8601 format. Overwrites the date309* and optionally the time part of the given object with the parsed values.310*311* @param {!goog.date.DateTime} dateTime Object whose fields will be set.312* @param {string} formatted A date or datetime expressed in ISO 8601 format.313* @return {boolean} Whether the parsing succeeded.314*/315goog.date.setIso8601DateTime = function(dateTime, formatted) {316formatted = goog.string.trim(formatted);317var delim = formatted.indexOf('T') == -1 ? ' ' : 'T';318var parts = formatted.split(delim);319return goog.date.setIso8601DateOnly_(dateTime, parts[0]) &&320(parts.length < 2 || goog.date.setIso8601TimeOnly_(dateTime, parts[1]));321};322323324/**325* Sets date fields based on an ISO 8601 format string.326*327* @param {!goog.date.DateTime} d Object whose fields will be set.328* @param {string} formatted A date expressed in ISO 8601 format.329* @return {boolean} Whether the parsing succeeded.330* @private331*/332goog.date.setIso8601DateOnly_ = function(d, formatted) {333// split the formatted ISO date string into its date fields334var parts = formatted.match(goog.date.splitDateStringRegex_);335if (!parts) {336return false;337}338339var year = Number(parts[1]);340var month = Number(parts[2]);341var date = Number(parts[3]);342var dayOfYear = Number(parts[4]);343var week = Number(parts[5]);344// ISO weekdays start with 1, native getDay() values start with 0345var dayOfWeek = Number(parts[6]) || 1;346347d.setFullYear(year);348349if (dayOfYear) {350d.setDate(1);351d.setMonth(0);352var offset = dayOfYear - 1; // offset, so 1-indexed, i.e., skip day 1353d.add(new goog.date.Interval(goog.date.Interval.DAYS, offset));354} else if (week) {355goog.date.setDateFromIso8601Week_(d, week, dayOfWeek);356} else {357if (month) {358d.setDate(1);359d.setMonth(month - 1);360}361if (date) {362d.setDate(date);363}364}365366return true;367};368369370/**371* Sets date fields based on an ISO 8601 week string.372* See {@link http://en.wikipedia.org/wiki/ISO_week_date}, "Relation with the373* Gregorian Calendar". The first week of a new ISO year is the week with the374* majority of its days in the new Gregorian year. I.e., ISO Week 1's Thursday375* is in that year. ISO weeks always start on Monday. So ISO Week 1 can376* contain a few days from the previous Gregorian year. And ISO weeks always377* end on Sunday, so the last ISO week (Week 52 or 53) can have a few days from378* the following Gregorian year.379* Example: '1997-W01' lasts from 1996-12-30 to 1997-01-05. January 1, 1997 is380* a Wednesday. So W01's Monday is Dec.30, 1996, and Sunday is January 5, 1997.381*382* @param {goog.date.DateTime} d Object whose fields will be set.383* @param {number} week ISO week number.384* @param {number} dayOfWeek ISO day of week.385* @private386*/387goog.date.setDateFromIso8601Week_ = function(d, week, dayOfWeek) {388// calculate offset for first week389d.setMonth(0);390d.setDate(1);391var jsDay = d.getDay();392// switch Sunday (0) to index 7; ISO days are 1-indexed393var jan1WeekDay = jsDay || 7;394395var THURSDAY = 4;396if (jan1WeekDay <= THURSDAY) {397// was extended back to Monday398var startDelta = 1 - jan1WeekDay; // e.g., Thu(4) ==> -3399} else {400// was extended forward to Monday401startDelta = 8 - jan1WeekDay; // e.g., Fri(5) ==> +3402}403404// find the absolute number of days to offset from the start of year405// to arrive close to the Gregorian equivalent (pending adjustments above)406// Note: decrement week multiplier by one because 1st week is407// represented by dayOfWeek value408var absoluteDays = Number(dayOfWeek) + (7 * (Number(week) - 1));409410// convert from ISO weekday format to Gregorian calendar date411// note: subtract 1 because 1-indexed; offset should not include 1st of month412var delta = startDelta + absoluteDays - 1;413var interval = new goog.date.Interval(goog.date.Interval.DAYS, delta);414d.add(interval);415};416417418/**419* Sets time fields based on an ISO 8601 format string.420* Note: only time fields, not date fields.421*422* @param {!goog.date.DateTime} d Object whose fields will be set.423* @param {string} formatted A time expressed in ISO 8601 format.424* @return {boolean} Whether the parsing succeeded.425* @private426*/427goog.date.setIso8601TimeOnly_ = function(d, formatted) {428// first strip timezone info from the end429var parts = formatted.match(goog.date.splitTimezoneStringRegex_);430431var offset = 0; // local time if no timezone info432if (parts) {433if (parts[0] != 'Z') {434offset = Number(parts[2]) * 60 + Number(parts[3]);435offset *= parts[1] == '-' ? 1 : -1;436}437offset -= d.getTimezoneOffset();438formatted = formatted.substr(0, formatted.length - parts[0].length);439}440441// then work out the time442parts = formatted.match(goog.date.splitTimeStringRegex_);443if (!parts) {444return false;445}446447d.setHours(Number(parts[1]));448d.setMinutes(Number(parts[2]) || 0);449d.setSeconds(Number(parts[3]) || 0);450d.setMilliseconds(parts[4] ? Number(parts[4]) * 1000 : 0);451452if (offset != 0) {453// adjust the date and time according to the specified timezone454d.setTime(d.getTime() + offset * 60000);455}456457return true;458};459460461462/**463* Class representing a date/time interval. Used for date calculations.464* <pre>465* new goog.date.Interval(0, 1) // One month466* new goog.date.Interval(0, 0, 3, 1) // Three days and one hour467* new goog.date.Interval(goog.date.Interval.DAYS, 1) // One day468* </pre>469*470* @param {number|string=} opt_years Years or string representing date part.471* @param {number=} opt_months Months or number of whatever date part specified472* by first parameter.473* @param {number=} opt_days Days.474* @param {number=} opt_hours Hours.475* @param {number=} opt_minutes Minutes.476* @param {number=} opt_seconds Seconds.477* @constructor478* @struct479* @final480*/481goog.date.Interval = function(482opt_years, opt_months, opt_days, opt_hours, opt_minutes, opt_seconds) {483if (goog.isString(opt_years)) {484var type = opt_years;485var interval = /** @type {number} */ (opt_months);486this.years = type == goog.date.Interval.YEARS ? interval : 0;487this.months = type == goog.date.Interval.MONTHS ? interval : 0;488this.days = type == goog.date.Interval.DAYS ? interval : 0;489this.hours = type == goog.date.Interval.HOURS ? interval : 0;490this.minutes = type == goog.date.Interval.MINUTES ? interval : 0;491this.seconds = type == goog.date.Interval.SECONDS ? interval : 0;492} else {493this.years = /** @type {number} */ (opt_years) || 0;494this.months = opt_months || 0;495this.days = opt_days || 0;496this.hours = opt_hours || 0;497this.minutes = opt_minutes || 0;498this.seconds = opt_seconds || 0;499}500};501502503/**504* Parses an XML Schema duration (ISO 8601 extended).505* @see http://www.w3.org/TR/xmlschema-2/#duration506*507* @param {string} duration An XML schema duration in textual format.508* Recurring durations and weeks are not supported.509* @return {goog.date.Interval} The duration as a goog.date.Interval or null510* if the parse fails.511*/512goog.date.Interval.fromIsoString = function(duration) {513var parts = duration.match(goog.date.splitDurationRegex_);514if (!parts) {515return null;516}517518var timeEmpty = !(parts[6] || parts[7] || parts[8]);519var dateTimeEmpty = timeEmpty && !(parts[2] || parts[3] || parts[4]);520if (dateTimeEmpty || timeEmpty && parts[5]) {521return null;522}523524var negative = parts[1];525var years = parseInt(parts[2], 10) || 0;526var months = parseInt(parts[3], 10) || 0;527var days = parseInt(parts[4], 10) || 0;528var hours = parseInt(parts[6], 10) || 0;529var minutes = parseInt(parts[7], 10) || 0;530var seconds = parseFloat(parts[8]) || 0;531return negative ?532new goog.date.Interval(533-years, -months, -days, -hours, -minutes, -seconds) :534new goog.date.Interval(years, months, days, hours, minutes, seconds);535};536537538/**539* Serializes goog.date.Interval into XML Schema duration (ISO 8601 extended).540* @see http://www.w3.org/TR/xmlschema-2/#duration541*542* @param {boolean=} opt_verbose Include zero fields in the duration string.543* @return {?string} An XML schema duration in ISO 8601 extended format,544* or null if the interval contains both positive and negative fields.545*/546goog.date.Interval.prototype.toIsoString = function(opt_verbose) {547var minField = Math.min(548this.years, this.months, this.days, this.hours, this.minutes,549this.seconds);550var maxField = Math.max(551this.years, this.months, this.days, this.hours, this.minutes,552this.seconds);553if (minField < 0 && maxField > 0) {554return null;555}556557// Return 0 seconds if all fields are zero.558if (!opt_verbose && minField == 0 && maxField == 0) {559return 'PT0S';560}561562var res = [];563564// Add sign and 'P' prefix.565if (minField < 0) {566res.push('-');567}568res.push('P');569570// Add date.571if (this.years || opt_verbose) {572res.push(Math.abs(this.years) + 'Y');573}574if (this.months || opt_verbose) {575res.push(Math.abs(this.months) + 'M');576}577if (this.days || opt_verbose) {578res.push(Math.abs(this.days) + 'D');579}580581// Add time.582if (this.hours || this.minutes || this.seconds || opt_verbose) {583res.push('T');584if (this.hours || opt_verbose) {585res.push(Math.abs(this.hours) + 'H');586}587if (this.minutes || opt_verbose) {588res.push(Math.abs(this.minutes) + 'M');589}590if (this.seconds || opt_verbose) {591res.push(Math.abs(this.seconds) + 'S');592}593}594595return res.join('');596};597598599/**600* Tests whether the given interval is equal to this interval.601* Note, this is a simple field-by-field comparison, it doesn't602* account for comparisons like "12 months == 1 year".603*604* @param {goog.date.Interval} other The interval to test.605* @return {boolean} Whether the intervals are equal.606*/607goog.date.Interval.prototype.equals = function(other) {608return other.years == this.years && other.months == this.months &&609other.days == this.days && other.hours == this.hours &&610other.minutes == this.minutes && other.seconds == this.seconds;611};612613614/**615* @return {!goog.date.Interval} A clone of the interval object.616*/617goog.date.Interval.prototype.clone = function() {618return new goog.date.Interval(619this.years, this.months, this.days, this.hours, this.minutes,620this.seconds);621};622623624/**625* Years constant for the date parts.626* @type {string}627*/628goog.date.Interval.YEARS = 'y';629630631/**632* Months constant for the date parts.633* @type {string}634*/635goog.date.Interval.MONTHS = 'm';636637638/**639* Days constant for the date parts.640* @type {string}641*/642goog.date.Interval.DAYS = 'd';643644645/**646* Hours constant for the date parts.647* @type {string}648*/649goog.date.Interval.HOURS = 'h';650651652/**653* Minutes constant for the date parts.654* @type {string}655*/656goog.date.Interval.MINUTES = 'n';657658659/**660* Seconds constant for the date parts.661* @type {string}662*/663goog.date.Interval.SECONDS = 's';664665666/**667* @return {boolean} Whether all fields of the interval are zero.668*/669goog.date.Interval.prototype.isZero = function() {670return this.years == 0 && this.months == 0 && this.days == 0 &&671this.hours == 0 && this.minutes == 0 && this.seconds == 0;672};673674675/**676* @return {!goog.date.Interval} Negative of this interval.677*/678goog.date.Interval.prototype.getInverse = function() {679return this.times(-1);680};681682683/**684* Calculates n * (this interval) by memberwise multiplication.685* @param {number} n An integer.686* @return {!goog.date.Interval} n * this.687*/688goog.date.Interval.prototype.times = function(n) {689return new goog.date.Interval(690this.years * n, this.months * n, this.days * n, this.hours * n,691this.minutes * n, this.seconds * n);692};693694695/**696* Gets the total number of seconds in the time interval. Assumes that months697* and years are empty.698* @return {number} Total number of seconds in the interval.699*/700goog.date.Interval.prototype.getTotalSeconds = function() {701goog.asserts.assert(this.years == 0 && this.months == 0);702return ((this.days * 24 + this.hours) * 60 + this.minutes) * 60 +703this.seconds;704};705706707/**708* Adds the Interval in the argument to this Interval field by field.709*710* @param {goog.date.Interval} interval The Interval to add.711*/712goog.date.Interval.prototype.add = function(interval) {713this.years += interval.years;714this.months += interval.months;715this.days += interval.days;716this.hours += interval.hours;717this.minutes += interval.minutes;718this.seconds += interval.seconds;719};720721722723/**724* Class representing a date. Defaults to current date if none is specified.725*726* Implements most methods of the native js Date object (except the time related727* ones, {@see goog.date.DateTime}) and can be used interchangeably with it just728* as if goog.date.Date was a synonym of Date. To make this more transparent,729* Closure APIs should accept goog.date.DateLike instead of the real Date730* object.731*732* @param {number|goog.date.DateLike=} opt_year Four digit year or a date-like733* object. If not set, the created object will contain the date734* determined by goog.now().735* @param {number=} opt_month Month, 0 = Jan, 11 = Dec.736* @param {number=} opt_date Date of month, 1 - 31.737* @constructor738* @struct739* @see goog.date.DateTime740*/741goog.date.Date = function(opt_year, opt_month, opt_date) {742/** @protected {!Date} The wrapped date or datetime. */743this.date;744// goog.date.DateTime assumes that only this.date is added in this ctor.745if (goog.isNumber(opt_year)) {746this.date = this.buildDate_(opt_year, opt_month || 0, opt_date || 1);747this.maybeFixDst_(opt_date || 1);748} else if (goog.isObject(opt_year)) {749this.date = this.buildDate_(750opt_year.getFullYear(), opt_year.getMonth(), opt_year.getDate());751this.maybeFixDst_(opt_year.getDate());752} else {753this.date = new Date(goog.now());754var expectedDate = this.date.getDate();755this.date.setHours(0);756this.date.setMinutes(0);757this.date.setSeconds(0);758this.date.setMilliseconds(0);759// In some time zones there is no "0" hour on certain days during DST.760// Adjust here, if necessary. See:761// https://github.com/google/closure-library/issues/34.762this.maybeFixDst_(expectedDate);763}764};765766767/**768* new Date(y, m, d) treats years in the interval [0, 100) as two digit years,769* adding 1900 to them. This method ensures that calling the date constructor770* as a copy constructor returns a value that is equal to the passed in771* date value by explicitly setting the full year.772* @private773* @param {number} fullYear The full year (including century).774* @param {number} month The month, from 0-11.775* @param {number} date The day of the month.776* @return {!Date} The constructed Date object.777*/778goog.date.Date.prototype.buildDate_ = function(fullYear, month, date) {779var d = new Date(fullYear, month, date);780if (fullYear >= 0 && fullYear < 100) {781// Can't just setFullYear as new Date() can flip over for e.g. month = 13.782d.setFullYear(d.getFullYear() - 1900);783}784return d;785};786787788/**789* First day of week. 0 = Mon, 6 = Sun.790* @type {number}791* @private792*/793goog.date.Date.prototype.firstDayOfWeek_ =794goog.i18n.DateTimeSymbols.FIRSTDAYOFWEEK;795796797/**798* The cut off weekday used for week number calculations. 0 = Mon, 6 = Sun.799* @type {number}800* @private801*/802goog.date.Date.prototype.firstWeekCutOffDay_ =803goog.i18n.DateTimeSymbols.FIRSTWEEKCUTOFFDAY;804805806/**807* @return {!goog.date.Date} A clone of the date object.808*/809goog.date.Date.prototype.clone = function() {810var date = new goog.date.Date(this.date);811date.firstDayOfWeek_ = this.firstDayOfWeek_;812date.firstWeekCutOffDay_ = this.firstWeekCutOffDay_;813814return date;815};816817818/**819* @return {number} The four digit year of date.820*/821goog.date.Date.prototype.getFullYear = function() {822return this.date.getFullYear();823};824825826/**827* Alias for getFullYear.828*829* @return {number} The four digit year of date.830* @see #getFullYear831*/832goog.date.Date.prototype.getYear = function() {833return this.getFullYear();834};835836837/**838* @return {goog.date.month} The month of date, 0 = Jan, 11 = Dec.839*/840goog.date.Date.prototype.getMonth = function() {841return /** @type {goog.date.month} */ (this.date.getMonth());842};843844845/**846* @return {number} The date of month.847*/848goog.date.Date.prototype.getDate = function() {849return this.date.getDate();850};851852853/**854* Returns the number of milliseconds since 1 January 1970 00:00:00.855*856* @return {number} The number of milliseconds since 1 January 1970 00:00:00.857*/858goog.date.Date.prototype.getTime = function() {859return this.date.getTime();860};861862863/**864* @return {number} The day of week, US style. 0 = Sun, 6 = Sat.865*/866goog.date.Date.prototype.getDay = function() {867return this.date.getDay();868};869870871/**872* @return {goog.date.weekDay} The day of week, ISO style. 0 = Mon, 6 = Sun.873*/874goog.date.Date.prototype.getIsoWeekday = function() {875return /** @type {goog.date.weekDay} */ ((this.getDay() + 6) % 7);876};877878879/**880* @return {number} The day of week according to firstDayOfWeek setting.881*/882goog.date.Date.prototype.getWeekday = function() {883return (this.getIsoWeekday() - this.firstDayOfWeek_ + 7) % 7;884};885886887/**888* @return {number} The four digit year of date according to universal time.889*/890goog.date.Date.prototype.getUTCFullYear = function() {891return this.date.getUTCFullYear();892};893894895/**896* @return {goog.date.month} The month of date according to universal time,897* 0 = Jan, 11 = Dec.898*/899goog.date.Date.prototype.getUTCMonth = function() {900return /** @type {goog.date.month} */ (this.date.getUTCMonth());901};902903904/**905* @return {number} The date of month according to universal time.906*/907goog.date.Date.prototype.getUTCDate = function() {908return this.date.getUTCDate();909};910911912/**913* @return {number} The day of week according to universal time, US style.914* 0 = Sun, 1 = Mon, 6 = Sat.915*/916goog.date.Date.prototype.getUTCDay = function() {917return this.date.getDay();918};919920921/**922* @return {number} The hours value according to universal time.923*/924goog.date.Date.prototype.getUTCHours = function() {925return this.date.getUTCHours();926};927928929/**930* @return {number} The minutes value according to universal time.931*/932goog.date.Date.prototype.getUTCMinutes = function() {933return this.date.getUTCMinutes();934};935936937/**938* @return {goog.date.weekDay} The day of week according to universal time, ISO939* style. 0 = Mon, 6 = Sun.940*/941goog.date.Date.prototype.getUTCIsoWeekday = function() {942return /** @type {goog.date.weekDay} */ ((this.date.getUTCDay() + 6) % 7);943};944945946/**947* @return {number} The day of week according to universal time and948* firstDayOfWeek setting.949*/950goog.date.Date.prototype.getUTCWeekday = function() {951return (this.getUTCIsoWeekday() - this.firstDayOfWeek_ + 7) % 7;952};953954955/**956* @return {number} The first day of the week. 0 = Mon, 6 = Sun.957*/958goog.date.Date.prototype.getFirstDayOfWeek = function() {959return this.firstDayOfWeek_;960};961962963/**964* @return {number} The cut off weekday used for week number calculations.965* 0 = Mon, 6 = Sun.966*/967goog.date.Date.prototype.getFirstWeekCutOffDay = function() {968return this.firstWeekCutOffDay_;969};970971972/**973* @return {number} The number of days for the selected month.974*/975goog.date.Date.prototype.getNumberOfDaysInMonth = function() {976return goog.date.getNumberOfDaysInMonth(this.getFullYear(), this.getMonth());977};978979980/**981* @return {number} The week number.982*/983goog.date.Date.prototype.getWeekNumber = function() {984return goog.date.getWeekNumber(985this.getFullYear(), this.getMonth(), this.getDate(),986this.firstWeekCutOffDay_, this.firstDayOfWeek_);987};988989990/**991* @return {number} The day of year.992*/993goog.date.Date.prototype.getDayOfYear = function() {994var dayOfYear = this.getDate();995var year = this.getFullYear();996for (var m = this.getMonth() - 1; m >= 0; m--) {997dayOfYear += goog.date.getNumberOfDaysInMonth(year, m);998}9991000return dayOfYear;1001};100210031004/**1005* Returns timezone offset. The timezone offset is the delta in minutes between1006* UTC and your local time. E.g., UTC+10 returns -600. Daylight savings time1007* prevents this value from being constant.1008*1009* @return {number} The timezone offset.1010*/1011goog.date.Date.prototype.getTimezoneOffset = function() {1012return this.date.getTimezoneOffset();1013};101410151016/**1017* Returns timezone offset as a string. Returns offset in [+-]HH:mm format or Z1018* for UTC.1019*1020* @return {string} The timezone offset as a string.1021*/1022goog.date.Date.prototype.getTimezoneOffsetString = function() {1023var tz;1024var offset = this.getTimezoneOffset();10251026if (offset == 0) {1027tz = 'Z';1028} else {1029var n = Math.abs(offset) / 60;1030var h = Math.floor(n);1031var m = (n - h) * 60;1032tz = (offset > 0 ? '-' : '+') + goog.string.padNumber(h, 2) + ':' +1033goog.string.padNumber(m, 2);1034}10351036return tz;1037};103810391040/**1041* Sets the date.1042*1043* @param {goog.date.Date} date Date object to set date from.1044*/1045goog.date.Date.prototype.set = function(date) {1046this.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());1047};104810491050/**1051* Sets the year part of the date.1052*1053* @param {number} year Four digit year.1054*/1055goog.date.Date.prototype.setFullYear = function(year) {1056this.date.setFullYear(year);1057};105810591060/**1061* Alias for setFullYear.1062*1063* @param {number} year Four digit year.1064* @see #setFullYear1065*/1066goog.date.Date.prototype.setYear = function(year) {1067this.setFullYear(year);1068};106910701071/**1072* Sets the month part of the date.1073*1074* TODO(nnaze): Update type to goog.date.month.1075*1076* @param {number} month The month, where 0 = Jan, 11 = Dec.1077*/1078goog.date.Date.prototype.setMonth = function(month) {1079this.date.setMonth(month);1080};108110821083/**1084* Sets the day part of the date.1085*1086* @param {number} date The day part.1087*/1088goog.date.Date.prototype.setDate = function(date) {1089this.date.setDate(date);1090};109110921093/**1094* Sets the value of the date object as expressed in the number of milliseconds1095* since 1 January 1970 00:00:00.1096*1097* @param {number} ms Number of milliseconds since 1 Jan 1970.1098*/1099goog.date.Date.prototype.setTime = function(ms) {1100this.date.setTime(ms);1101};110211031104/**1105* Sets the year part of the date according to universal time.1106*1107* @param {number} year Four digit year.1108*/1109goog.date.Date.prototype.setUTCFullYear = function(year) {1110this.date.setUTCFullYear(year);1111};111211131114/**1115* Sets the month part of the date according to universal time.1116*1117* @param {number} month The month, where 0 = Jan, 11 = Dec.1118*/1119goog.date.Date.prototype.setUTCMonth = function(month) {1120this.date.setUTCMonth(month);1121};112211231124/**1125* Sets the day part of the date according to universal time.1126*1127* @param {number} date The UTC date.1128*/1129goog.date.Date.prototype.setUTCDate = function(date) {1130this.date.setUTCDate(date);1131};113211331134/**1135* Sets the first day of week.1136*1137* @param {number} day 0 = Mon, 6 = Sun.1138*/1139goog.date.Date.prototype.setFirstDayOfWeek = function(day) {1140this.firstDayOfWeek_ = day;1141};114211431144/**1145* Sets cut off weekday used for week number calculations. 0 = Mon, 6 = Sun.1146*1147* @param {number} day The cut off weekday.1148*/1149goog.date.Date.prototype.setFirstWeekCutOffDay = function(day) {1150this.firstWeekCutOffDay_ = day;1151};115211531154/**1155* Performs date calculation by adding the supplied interval to the date.1156*1157* @param {goog.date.Interval} interval Date interval to add.1158*/1159goog.date.Date.prototype.add = function(interval) {1160if (interval.years || interval.months) {1161// As months have different number of days adding a month to Jan 31 by just1162// setting the month would result in a date in early March rather than Feb1163// 28 or 29. Doing it this way overcomes that problem.11641165// adjust year and month, accounting for both directions1166var month = this.getMonth() + interval.months + interval.years * 12;1167var year = this.getYear() + Math.floor(month / 12);1168month %= 12;1169if (month < 0) {1170month += 12;1171}11721173var daysInTargetMonth = goog.date.getNumberOfDaysInMonth(year, month);1174var date = Math.min(daysInTargetMonth, this.getDate());11751176// avoid inadvertently causing rollovers to adjacent months1177this.setDate(1);11781179this.setFullYear(year);1180this.setMonth(month);1181this.setDate(date);1182}11831184if (interval.days) {1185// Convert the days to milliseconds and add it to the UNIX timestamp.1186// Taking noon helps to avoid 1 day error due to the daylight saving.1187var noon = new Date(this.getYear(), this.getMonth(), this.getDate(), 12);1188var result = new Date(noon.getTime() + interval.days * 86400000);11891190// Set date to 1 to prevent rollover caused by setting the year or month.1191this.setDate(1);1192this.setFullYear(result.getFullYear());1193this.setMonth(result.getMonth());1194this.setDate(result.getDate());11951196this.maybeFixDst_(result.getDate());1197}1198};119912001201/**1202* Returns ISO 8601 string representation of date.1203*1204* @param {boolean=} opt_verbose Whether the verbose format should be used1205* instead of the default compact one.1206* @param {boolean=} opt_tz Whether the timezone offset should be included1207* in the string.1208* @return {string} ISO 8601 string representation of date.1209*/1210goog.date.Date.prototype.toIsoString = function(opt_verbose, opt_tz) {1211var str = [1212this.getFullYear(), goog.string.padNumber(this.getMonth() + 1, 2),1213goog.string.padNumber(this.getDate(), 2)1214];12151216return str.join((opt_verbose) ? '-' : '') +1217(opt_tz ? this.getTimezoneOffsetString() : '');1218};121912201221/**1222* Returns ISO 8601 string representation of date according to universal time.1223*1224* @param {boolean=} opt_verbose Whether the verbose format should be used1225* instead of the default compact one.1226* @param {boolean=} opt_tz Whether the timezone offset should be included in1227* the string.1228* @return {string} ISO 8601 string representation of date according to1229* universal time.1230*/1231goog.date.Date.prototype.toUTCIsoString = function(opt_verbose, opt_tz) {1232var str = [1233this.getUTCFullYear(), goog.string.padNumber(this.getUTCMonth() + 1, 2),1234goog.string.padNumber(this.getUTCDate(), 2)1235];12361237return str.join((opt_verbose) ? '-' : '') + (opt_tz ? 'Z' : '');1238};123912401241/**1242* Tests whether given date is equal to this Date.1243* Note: This ignores units more precise than days (hours and below)1244* and also ignores timezone considerations.1245*1246* @param {goog.date.Date} other The date to compare.1247* @return {boolean} Whether the given date is equal to this one.1248*/1249goog.date.Date.prototype.equals = function(other) {1250return !!(1251other && this.getYear() == other.getYear() &&1252this.getMonth() == other.getMonth() && this.getDate() == other.getDate());1253};125412551256/**1257* Overloaded toString method for object.1258* @return {string} ISO 8601 string representation of date.1259* @override1260*/1261goog.date.Date.prototype.toString = function() {1262return this.toIsoString();1263};126412651266/**1267* Fixes date to account for daylight savings time in browsers that fail to do1268* so automatically.1269* @param {number} expected Expected date.1270* @private1271*/1272goog.date.Date.prototype.maybeFixDst_ = function(expected) {1273if (this.getDate() != expected) {1274var dir = this.getDate() < expected ? 1 : -1;1275this.date.setUTCHours(this.date.getUTCHours() + dir);1276}1277};127812791280/**1281* @return {number} Value of wrapped date.1282* @override1283*/1284goog.date.Date.prototype.valueOf = function() {1285return this.date.valueOf();1286};128712881289/**1290* Compares two dates. May be used as a sorting function.1291* @see goog.array.sort1292* @param {!goog.date.DateLike} date1 Date to compare.1293* @param {!goog.date.DateLike} date2 Date to compare.1294* @return {number} Comparison result. 0 if dates are the same, less than 0 if1295* date1 is earlier than date2, greater than 0 if date1 is later than date2.1296*/1297goog.date.Date.compare = function(date1, date2) {1298return date1.getTime() - date2.getTime();1299};1300130113021303/**1304* Class representing a date and time. Defaults to current date and time if none1305* is specified.1306*1307* Implements most methods of the native js Date object and can be used1308* interchangeably with it just as if goog.date.DateTime was a subclass of Date.1309*1310* @param {number|Object=} opt_year Four digit year or a date-like object. If1311* not set, the created object will contain the date determined by1312* goog.now().1313* @param {number=} opt_month Month, 0 = Jan, 11 = Dec.1314* @param {number=} opt_date Date of month, 1 - 31.1315* @param {number=} opt_hours Hours, 0 - 23.1316* @param {number=} opt_minutes Minutes, 0 - 59.1317* @param {number=} opt_seconds Seconds, 0 - 61.1318* @param {number=} opt_milliseconds Milliseconds, 0 - 999.1319* @constructor1320* @struct1321* @extends {goog.date.Date}1322*/1323goog.date.DateTime = function(1324opt_year, opt_month, opt_date, opt_hours, opt_minutes, opt_seconds,1325opt_milliseconds) {1326if (goog.isNumber(opt_year)) {1327this.date = new Date(1328opt_year, opt_month || 0, opt_date || 1, opt_hours || 0,1329opt_minutes || 0, opt_seconds || 0, opt_milliseconds || 0);1330} else {1331this.date = new Date(1332opt_year && opt_year.getTime ? opt_year.getTime() : goog.now());1333}1334};1335goog.inherits(goog.date.DateTime, goog.date.Date);133613371338/**1339* @param {number} timestamp Number of milliseconds since Epoch.1340* @return {!goog.date.DateTime}1341*/1342goog.date.DateTime.fromTimestamp = function(timestamp) {1343var date = new goog.date.DateTime();1344date.setTime(timestamp);1345return date;1346};134713481349/**1350* Creates a DateTime from a datetime string expressed in RFC 822 format.1351*1352* @param {string} formatted A date or datetime expressed in RFC 822 format.1353* @return {goog.date.DateTime} Parsed date or null if parse fails.1354*/1355goog.date.DateTime.fromRfc822String = function(formatted) {1356var date = new Date(formatted);1357return !isNaN(date.getTime()) ? new goog.date.DateTime(date) : null;1358};135913601361/**1362* Returns the hours part of the datetime.1363*1364* @return {number} An integer between 0 and 23, representing the hour.1365*/1366goog.date.DateTime.prototype.getHours = function() {1367return this.date.getHours();1368};136913701371/**1372* Returns the minutes part of the datetime.1373*1374* @return {number} An integer between 0 and 59, representing the minutes.1375*/1376goog.date.DateTime.prototype.getMinutes = function() {1377return this.date.getMinutes();1378};137913801381/**1382* Returns the seconds part of the datetime.1383*1384* @return {number} An integer between 0 and 59, representing the seconds.1385*/1386goog.date.DateTime.prototype.getSeconds = function() {1387return this.date.getSeconds();1388};138913901391/**1392* Returns the milliseconds part of the datetime.1393*1394* @return {number} An integer between 0 and 999, representing the milliseconds.1395*/1396goog.date.DateTime.prototype.getMilliseconds = function() {1397return this.date.getMilliseconds();1398};139914001401/**1402* Returns the day of week according to universal time, US style.1403*1404* @return {goog.date.weekDay} Day of week, 0 = Sun, 1 = Mon, 6 = Sat.1405* @override1406*/1407goog.date.DateTime.prototype.getUTCDay = function() {1408return /** @type {goog.date.weekDay} */ (this.date.getUTCDay());1409};141014111412/**1413* Returns the hours part of the datetime according to universal time.1414*1415* @return {number} An integer between 0 and 23, representing the hour.1416* @override1417*/1418goog.date.DateTime.prototype.getUTCHours = function() {1419return this.date.getUTCHours();1420};142114221423/**1424* Returns the minutes part of the datetime according to universal time.1425*1426* @return {number} An integer between 0 and 59, representing the minutes.1427* @override1428*/1429goog.date.DateTime.prototype.getUTCMinutes = function() {1430return this.date.getUTCMinutes();1431};143214331434/**1435* Returns the seconds part of the datetime according to universal time.1436*1437* @return {number} An integer between 0 and 59, representing the seconds.1438*/1439goog.date.DateTime.prototype.getUTCSeconds = function() {1440return this.date.getUTCSeconds();1441};144214431444/**1445* Returns the milliseconds part of the datetime according to universal time.1446*1447* @return {number} An integer between 0 and 999, representing the milliseconds.1448*/1449goog.date.DateTime.prototype.getUTCMilliseconds = function() {1450return this.date.getUTCMilliseconds();1451};145214531454/**1455* Sets the hours part of the datetime.1456*1457* @param {number} hours An integer between 0 and 23, representing the hour.1458*/1459goog.date.DateTime.prototype.setHours = function(hours) {1460this.date.setHours(hours);1461};146214631464/**1465* Sets the minutes part of the datetime.1466*1467* @param {number} minutes Integer between 0 and 59, representing the minutes.1468*/1469goog.date.DateTime.prototype.setMinutes = function(minutes) {1470this.date.setMinutes(minutes);1471};147214731474/**1475* Sets the seconds part of the datetime.1476*1477* @param {number} seconds Integer between 0 and 59, representing the seconds.1478*/1479goog.date.DateTime.prototype.setSeconds = function(seconds) {1480this.date.setSeconds(seconds);1481};148214831484/**1485* Sets the milliseconds part of the datetime.1486*1487* @param {number} ms Integer between 0 and 999, representing the milliseconds.1488*/1489goog.date.DateTime.prototype.setMilliseconds = function(ms) {1490this.date.setMilliseconds(ms);1491};149214931494/**1495* Sets the hours part of the datetime according to universal time.1496*1497* @param {number} hours An integer between 0 and 23, representing the hour.1498*/1499goog.date.DateTime.prototype.setUTCHours = function(hours) {1500this.date.setUTCHours(hours);1501};150215031504/**1505* Sets the minutes part of the datetime according to universal time.1506*1507* @param {number} minutes Integer between 0 and 59, representing the minutes.1508*/1509goog.date.DateTime.prototype.setUTCMinutes = function(minutes) {1510this.date.setUTCMinutes(minutes);1511};151215131514/**1515* Sets the seconds part of the datetime according to universal time.1516*1517* @param {number} seconds Integer between 0 and 59, representing the seconds.1518*/1519goog.date.DateTime.prototype.setUTCSeconds = function(seconds) {1520this.date.setUTCSeconds(seconds);1521};152215231524/**1525* Sets the seconds part of the datetime according to universal time.1526*1527* @param {number} ms Integer between 0 and 999, representing the milliseconds.1528*/1529goog.date.DateTime.prototype.setUTCMilliseconds = function(ms) {1530this.date.setUTCMilliseconds(ms);1531};153215331534/**1535* @return {boolean} Whether the datetime is aligned to midnight.1536*/1537goog.date.DateTime.prototype.isMidnight = function() {1538return this.getHours() == 0 && this.getMinutes() == 0 &&1539this.getSeconds() == 0 && this.getMilliseconds() == 0;1540};154115421543/**1544* Performs date calculation by adding the supplied interval to the date.1545*1546* @param {goog.date.Interval} interval Date interval to add.1547* @override1548*/1549goog.date.DateTime.prototype.add = function(interval) {1550goog.date.Date.prototype.add.call(this, interval);15511552if (interval.hours) {1553this.setUTCHours(this.date.getUTCHours() + interval.hours);1554}1555if (interval.minutes) {1556this.setUTCMinutes(this.date.getUTCMinutes() + interval.minutes);1557}1558if (interval.seconds) {1559this.setUTCSeconds(this.date.getUTCSeconds() + interval.seconds);1560}1561};156215631564/**1565* Returns ISO 8601 string representation of date/time.1566*1567* @param {boolean=} opt_verbose Whether the verbose format should be used1568* instead of the default compact one.1569* @param {boolean=} opt_tz Whether the timezone offset should be included1570* in the string.1571* @return {string} ISO 8601 string representation of date/time.1572* @override1573*/1574goog.date.DateTime.prototype.toIsoString = function(opt_verbose, opt_tz) {1575var dateString = goog.date.Date.prototype.toIsoString.call(this, opt_verbose);15761577if (opt_verbose) {1578return dateString + ' ' + goog.string.padNumber(this.getHours(), 2) + ':' +1579goog.string.padNumber(this.getMinutes(), 2) + ':' +1580goog.string.padNumber(this.getSeconds(), 2) +1581(opt_tz ? this.getTimezoneOffsetString() : '');1582}15831584return dateString + 'T' + goog.string.padNumber(this.getHours(), 2) +1585goog.string.padNumber(this.getMinutes(), 2) +1586goog.string.padNumber(this.getSeconds(), 2) +1587(opt_tz ? this.getTimezoneOffsetString() : '');1588};158915901591/**1592* Returns XML Schema 2 string representation of date/time.1593* The return value is also ISO 8601 compliant.1594*1595* @param {boolean=} opt_timezone Should the timezone offset be included in the1596* string?.1597* @return {string} XML Schema 2 string representation of date/time.1598*/1599goog.date.DateTime.prototype.toXmlDateTime = function(opt_timezone) {1600return goog.date.Date.prototype.toIsoString.call(this, true) + 'T' +1601goog.string.padNumber(this.getHours(), 2) + ':' +1602goog.string.padNumber(this.getMinutes(), 2) + ':' +1603goog.string.padNumber(this.getSeconds(), 2) +1604(opt_timezone ? this.getTimezoneOffsetString() : '');1605};160616071608/**1609* Returns ISO 8601 string representation of date/time according to universal1610* time.1611*1612* @param {boolean=} opt_verbose Whether the opt_verbose format should be1613* returned instead of the default compact one.1614* @param {boolean=} opt_tz Whether the the timezone offset should be included1615* in the string.1616* @return {string} ISO 8601 string representation of date/time according to1617* universal time.1618* @override1619*/1620goog.date.DateTime.prototype.toUTCIsoString = function(opt_verbose, opt_tz) {1621var dateStr = goog.date.Date.prototype.toUTCIsoString.call(this, opt_verbose);16221623if (opt_verbose) {1624return dateStr + ' ' + goog.string.padNumber(this.getUTCHours(), 2) + ':' +1625goog.string.padNumber(this.getUTCMinutes(), 2) + ':' +1626goog.string.padNumber(this.getUTCSeconds(), 2) + (opt_tz ? 'Z' : '');1627}16281629return dateStr + 'T' + goog.string.padNumber(this.getUTCHours(), 2) +1630goog.string.padNumber(this.getUTCMinutes(), 2) +1631goog.string.padNumber(this.getUTCSeconds(), 2) + (opt_tz ? 'Z' : '');1632};163316341635/**1636* Returns RFC 3339 string representation of datetime in UTC.1637*1638* @return {string} A UTC datetime expressed in RFC 3339 format.1639*/1640goog.date.DateTime.prototype.toUTCRfc3339String = function() {1641var date = this.toUTCIsoString(true).replace(' ', 'T');1642var millis = this.getUTCMilliseconds();1643return (millis ? date + '.' + millis : date) + 'Z';1644};164516461647/**1648* Tests whether given datetime is exactly equal to this DateTime.1649*1650* @param {goog.date.Date} other The datetime to compare.1651* @return {boolean} Whether the given datetime is exactly equal to this one.1652* @override1653*/1654goog.date.DateTime.prototype.equals = function(other) {1655return this.getTime() == other.getTime();1656};165716581659/**1660* Overloaded toString method for object.1661* @return {string} ISO 8601 string representation of date/time.1662* @override1663*/1664goog.date.DateTime.prototype.toString = function() {1665return this.toIsoString();1666};166716681669/**1670* Generates time label for the datetime, e.g., '5:30 AM'.1671* By default this does not pad hours (e.g., to '05:30') and it does add1672* an am/pm suffix.1673* TODO(user): i18n -- hardcoding time format like this is bad. E.g., in CJK1674* locales, need Chinese characters for hour and minute units.1675* @param {boolean=} opt_padHours Whether to pad hours, e.g., '05:30' vs '5:30'.1676* @param {boolean=} opt_showAmPm Whether to show the 'am' and 'pm' suffix.1677* @param {boolean=} opt_omitZeroMinutes E.g., '5:00pm' becomes '5pm',1678* but '5:01pm' remains '5:01pm'.1679* @return {string} The time label.1680*/1681goog.date.DateTime.prototype.toUsTimeString = function(1682opt_padHours, opt_showAmPm, opt_omitZeroMinutes) {1683var hours = this.getHours();16841685// show am/pm marker by default1686if (!goog.isDef(opt_showAmPm)) {1687opt_showAmPm = true;1688}16891690// 12pm1691var isPM = hours == 12;16921693// change from 1-24 to 1-12 basis1694if (hours > 12) {1695hours -= 12;1696isPM = true;1697}16981699// midnight is expressed as "12am", but if am/pm marker omitted, keep as '0'1700if (hours == 0 && opt_showAmPm) {1701hours = 12;1702}17031704var label = opt_padHours ? goog.string.padNumber(hours, 2) : String(hours);1705var minutes = this.getMinutes();1706if (!opt_omitZeroMinutes || minutes > 0) {1707label += ':' + goog.string.padNumber(minutes, 2);1708}17091710// by default, show am/pm suffix1711if (opt_showAmPm) {1712label += isPM ? ' PM' : ' AM';1713}1714return label;1715};171617171718/**1719* Generates time label for the datetime in standard ISO 24-hour time format.1720* E.g., '06:00:00' or '23:30:15'.1721* @param {boolean=} opt_showSeconds Whether to shows seconds. Defaults to TRUE.1722* @return {string} The time label.1723*/1724goog.date.DateTime.prototype.toIsoTimeString = function(opt_showSeconds) {1725var hours = this.getHours();1726var label = goog.string.padNumber(hours, 2) + ':' +1727goog.string.padNumber(this.getMinutes(), 2);1728if (!goog.isDef(opt_showSeconds) || opt_showSeconds) {1729label += ':' + goog.string.padNumber(this.getSeconds(), 2);1730}1731return label;1732};173317341735/**1736* @return {!goog.date.DateTime} A clone of the datetime object.1737* @override1738*/1739goog.date.DateTime.prototype.clone = function() {1740var date = new goog.date.DateTime(this.date);1741date.setFirstDayOfWeek(this.getFirstDayOfWeek());1742date.setFirstWeekCutOffDay(this.getFirstWeekCutOffDay());1743return date;1744};174517461747