UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

912 lines (805 loc) 28.5 kB
/*$ * @name datetime.js * @fileOverview date and time formatting routines * */ /*globals G11n enyo*/ //* @public /** Returns a date formatter object that formats dates according to the given parameters. * params (String/Object): Parameters that control the output format If _params_ is passed as a string, then the string should specify the custom date format to use. If _params_ is an object, the object may contain the following properties: * locale: Locale to use to format the date. If not specified, the locale used will be the current locale of the device. * date: The verbosity level of the date when formatted according to the locale's standard rules. Valid values are 'short', 'medium', 'long', and 'full'; you may also specify your own custom date format string. Defaults to "long" if no value is specified. * time: The verbosity level of the time when formatted according to the locale's standard rules. Valid values are 'short', 'medium', 'long', and 'full'; you may also specify your own custom time format string. Defaults to "long" if no value is specified. * format: The verbosity level of the date and time when formatted together according to the locale's standard rules. Valid values are 'short', 'medium', 'long', and 'full'; you may also specify your own custom date/time format string. * dateComponents: Formats a date with only certain components in it, using the locale's standard format for those components. Valid values are 'DM', 'MY', and 'DMY', which stand for "date and month", "month and year", and "date, month, and year", respectively. This may be combined with the _date_ or _format_ properties to specify the verbosity level of those components. Defaults to 'DMY' if no value is specified. * timeComponents: Formats a time with certain additional components in it, using the locale's standard format for those components. Valid values are 'A', 'Z', and 'AZ', which stand for "am/pm", "time zone", and "am/pm and time zone", respectively. The additional components appear before or after the time, as required by the locale. This can be combined with the _time_ or _format_ properties to specify the verbosity level of those components. Defaults to no additional components if no value is specified. * twelveHourFormat: If true, a 12-hour clock is used when formatting times; if false, a 24-hour clock is used. * weekday: If true, the formatted date is returned with the day of the week included. If the value is 'short', 'medium', 'long', or 'full', the day of the week is included at the appropriate level of verbosity. If no value is specified, the default is that no day of the week will be included in the format for the short, medium, or long styles. The full style always includes the day of the week. * TZ: Uses the given time zone. If no value is specified, the current device time zone is used. The following codes are used when specifying custom date or time formats: * yy: 2-digit year * yyyy: 4-digit year * MMMM: Name of a the month spelled out in long format (e.g., "July" or "August") * MMM: Name of the month in abbreviated form (e.g., "Jul" or "Aug") * MM: Zero-padded 2-digit month * M: 1- or 2-digit month, not padded * dd: Zero-padded 2-digit day of the month * d: 1- or 2-digit day of the month, not padded * zzz: Time zone name * a: am/pm notation for 12-hour formats * KK: Zero-padded hour of the day in the 12-hour clock, in the range 00 to 11 * K: Hour of the day in the 12-hour clock, not padded, in the range 0 to 11 * hh: Zero-padded hour of the day in the 12-hour clock, in the range 01 to 12 * h: Hour of the day in the 12-hour clock, not padded, in the range 1 to 12 * HH: Zero-padded hour of the day in the 24-hour clock, in the range 00 to 23 * H: Hour of the day in the 24-hour clock, not padded, in the range 0 to 23 * kk: Zero-padded hour of the day in the 24-hour clock, in the range 01 to 24 * k: Hour of the day in the 24-hour clock, not padded, in the range 1 to 24 * EEEE: Day of the week, spelled out fully (e.g., "Wednesday") * EEE: Day of the week, in 3-letter abbreviations (e.g., "Wed") * EE: Day of the week, in 2-letter abbreviations (e.g., "We") * E: Day of the week, in 1-letter abbreviations (e.g., "W") * mm: Zero-padded minute of the hour * ss: Zero-padded second of the minute Please note that the current formatter only supports formatting dates in the Gregorian calendar. */ enyo.g11n.DateFmt = function(params){ var locale, dateFormat, timeFormat, finalFormat, self; self = this; self._normalizedComponents = { date: { 'dm': 'DM', 'md': 'DM', 'my': 'MY', 'ym': 'MY', 'd': 'D', 'dmy': '', 'dym': '', 'mdy': '', 'myd': '', 'ydm': '', 'ymd': '' }, time: { 'az': 'AZ', 'za': 'AZ', 'a': 'A', 'z': 'Z', '': '' }, timeLength: { 'short': 'small', 'medium': 'small', 'long': 'big', 'full': 'big' } }; //* @protected self._normalizeDateTimeFormatComponents = function(options) { var dateComponents = options.dateComponents; var timeComponents = options.timeComponents; var dateComp, timeComp, time; var timeLength = options.time; if (options.date && dateComponents) { dateComp = self._normalizedComponents.date[dateComponents]; if (dateComp === undefined) { enyo.log("date component error: '" + dateComponents + "'"); dateComp = ''; } } if (timeLength && timeComponents !== undefined) { time = self._normalizedComponents.timeLength[timeLength]; if (time === undefined) { enyo.log("time format error: " + timeLength); time = 'small'; } timeComp = self._normalizedComponents.time[timeComponents]; if (timeComp === undefined) { enyo.log("time component error: '" + timeComponents + "'"); } } options.dateComponents = dateComp; options.timeComponents = timeComp; return options; }; //* @protected self._finalDateTimeFormat = function(dateFormat, timeFormat, options) { var dateTimeFormat = self.dateTimeFormatHash.dateTimeFormat || self.defaultFormats.dateTimeFormat; if (dateFormat && timeFormat) { return self._buildDateTimeFormat(dateTimeFormat, 'dateTime', {'TIME':timeFormat, 'DATE':dateFormat}); } else { return timeFormat || dateFormat || "M/d/yy h:mm a"; } }; //* @protected self._buildDateTimeFormat = function(format, parserChunk, subFormats) { var i, tokenLen; var acc = []; var tokenized = self._getTokenizedFormat(format, parserChunk); var formatChunk; for (i = 0, tokenLen = tokenized.length; i < tokenLen && tokenized[i] !== undefined; ++i) { formatChunk = subFormats[tokenized[i]]; if (formatChunk) { acc.push(formatChunk); } else { acc.push(tokenized[i]); } } return acc.join(""); }; //* @protected self._getDateFormat = function(dateLen, options) { var dateFormat = self._formatFetch(dateLen, options.dateComponents, "Date"); if (dateLen !== 'full' && options.weekday) { // The 'full' format already includes the weekday var weekdayFormat = self._formatFetch(options.weekday === true ? dateLen : options.weekday, '', 'Weekday'); dateFormat = self._buildDateTimeFormat( self.dateTimeFormatHash.weekDateFormat || self.defaultFormats.weekDateFormat, 'weekDate', { 'WEEK': weekdayFormat, 'DATE': dateFormat }); } return dateFormat; }; //* @protected self._getTimeFormat = function(dateLen, options) { var timeFormat = self._formatFetch(dateLen, '', self.twelveHourFormat ? "Time12" : "Time24"); // We check against undefined elsewhere because the empty string is valid // information there; here, if there are no time components, we can skip // _buildDateTimeFormat(); _formatFetch() gives us all we need. if (options.timeComponents) { var timeParserChunk = 'time' + options.timeComponents; var timePartsFormat = timeParserChunk + 'Format'; return self._buildDateTimeFormat( self.dateTimeFormatHash[timePartsFormat] || self.defaultFormats[timePartsFormat], timeParserChunk, { 'TIME': timeFormat, 'AM': 'a', 'ZONE': 'zzz' }); } return timeFormat; }; //* @protected self.ParserChunks = { full: "('[^']+'|y{2,4}|M{1,4}|d{1,2}|z{1,3}|a|h{1,2}|H{1,2}|k{1,2}|K{1,2}|E{1,4}|m{1,2}|s{1,2}|[^A-Za-z']+)?", dateTime: "(DATE|TIME|[^A-Za-z]+|'[^']+')?", weekDate: "(DATE|WEEK|[^A-Za-z]+|'[^']+')?", timeA: "(TIME|AM|[^A-Za-z]+|'[^']+')?", timeZ: "(TIME|ZONE|[^A-Za-z]+|'[^']+')?", timeAZ: "(TIME|AM|ZONE|[^A-Za-z]+|'[^']+')?" }; //* @protected self._getTokenizedFormat = function(format, parserChunk) { var regexFragment = (parserChunk && self.ParserChunks[parserChunk]) || self.ParserChunks.full; var formatLength = format.length; var formatArray = [], tempStr, tempLength; var testRegex = new RegExp(regexFragment,"g"); while(formatLength > 0){ tempStr = (testRegex.exec(format))[0]; tempLength = tempStr.length; if (tempLength === 0){ return []; //bad format string } formatArray.push(tempStr); formatLength -= tempLength; } return formatArray; }; //* @protected self._formatFetch = function(formatLen, formatComponents, type, options) { switch (formatLen) { case 'short': case 'medium': case 'long': case 'full': case 'small': case 'big': case 'default': return self.dateTimeFormatHash[formatLen + (formatComponents || '') + type]; default: //assume format was passed in if it's not a type return formatLen; } }; //* @protected self._dayOffset = function(now, date) { var diff; date = self._roundToMidnight(date); now = self._roundToMidnight(now); diff = (now.getTime() - date.getTime()) / 864e5; return diff; }; //* @protected self._roundToMidnight = function(date) { var numMs = date.getTime(); var rounded = new Date(); rounded.setTime(numMs); rounded.setHours(0); rounded.setMinutes(0); rounded.setSeconds(0); rounded.setMilliseconds(0); return rounded; }; self.inputParams = params; //locale = params.locale; /* var tokLoc = locale.split("_"); language = tokLoc[0]; region = tokLoc[1]; */ if (typeof(params) === 'undefined' || !params.locale) { locale = enyo.g11n.formatLocale(); } else if (typeof(params.locale) === 'string') { locale = new enyo.g11n.Locale(params.locale); } else { locale = params.locale; } if (!locale.language) { locale.useDefaultLang(); } this.locale = locale; if (typeof(params) === "string"){ self.formatType = params; }else if (typeof(params) === 'undefined'){ params = {"format": "short"}; self.formatType = params.format; }else { self.formatType = params.format; } if (!self.formatType && !params.time && !params.date) { if (!params) { params = {"format": 'short'}; } else { params.format = 'short'; } self.formatType = 'short'; } self.dateTimeHash = enyo.g11n.Utils.getJsonFile({ root: enyo.g11n.Utils._getEnyoRoot(), path: "base/datetime_data", locale: locale, type: "language" }); if (!self.dateTimeHash){ self.dateTimeHash = enyo.g11n.Utils.getJsonFile({ root: enyo.g11n.Utils._getEnyoRoot(), path: "base/datetime_data", locale: new enyo.g11n.Locale("en_us") }); } self.dateTimeFormatHash = enyo.g11n.Utils.getJsonFile({ root: enyo.g11n.Utils._getEnyoRoot(), path: "base/formats", locale: locale, type: "region" }); if (!self.dateTimeFormatHash){ self.dateTimeFormatHash = enyo.g11n.Utils.getJsonFile({ root: enyo.g11n.Utils._getEnyoRoot(), path: "base/formats", locale: new enyo.g11n.Locale("en_us"), type: "region" }); } self.rb = new enyo.g11n.Resources({ root: enyo.g11n.Utils._getEnyoRoot() + "/base", locale: locale }); if(typeof(params) === 'undefined' || typeof(params.twelveHourFormat) === 'undefined'){ self.twelveHourFormat = self.dateTimeFormatHash.is12HourDefault; }else{ self.twelveHourFormat = params.twelveHourFormat; } if (self.formatType) { switch (self.formatType) { case "short": case "medium": case "long": case "full": case "default": self.partsLength = self.formatType; finalFormat = self._finalDateTimeFormat(self._getDateFormat(self.formatType, params), self._getTimeFormat(self.formatType, params), params); break; default: finalFormat = self.formatType; } } else { params = self._normalizeDateTimeFormatComponents(params); if (params.time) { timeFormat = self._getTimeFormat(params.time, params); self.partsLength = params.time; } if (params.date) { dateFormat = self._getDateFormat(params.date, params); self.partsLength = params.date; } finalFormat = self._finalDateTimeFormat(dateFormat, timeFormat, params); } self.tokenized = self._getTokenizedFormat(finalFormat); if (!self.partsLength) { self.partsLength = 'full'; } }; //* @public /** Returns the format string that this formatter instance uses to format dates. */ enyo.g11n.DateFmt.prototype.toString = function() { return this.tokenized.join(""); }; //* @public /** Returns true if the current formatter uses a 12-hour clock to format times. */ enyo.g11n.DateFmt.prototype.isAmPm = function(){ return this.twelveHourFormat; }; //* @public /** Returns true if the locale of this formatter uses a 12-hour clock to format times. */ enyo.g11n.DateFmt.prototype.isAmPmDefault = function(){ return this.dateTimeFormatHash.is12HourDefault; }; //* @public /** Returns the day of the week that represents the first day of the week in the current locale. The numbers represent the days of the week as follows: * 0: Sunday * 1: Monday * 2: Tuesday * 3: Wednesday * 4: Thursday * 5: Friday * 6: Saturday */ enyo.g11n.DateFmt.prototype.getFirstDayOfWeek = function(){ return this.dateTimeFormatHash.firstDayOfWeek; }; //* @protected enyo.g11n.DateFmt.prototype._format = function(date, parsedArray) { //var startTime = new Date(); var self = this, hr, acc = [], dateTimeVerbosity, dateTimeType, dateTimeIdx, tz, i, length, dtHash, tokenized; dtHash = self.dateTimeHash; for(i=0, length = parsedArray.length; i < length && parsedArray[i] !== undefined; i++) { switch(parsedArray[i]) { case 'yy': dateTimeVerbosity = ''; acc.push((date.getFullYear() + "").substring(2)); break; case 'yyyy': dateTimeVerbosity = ''; acc.push(date.getFullYear()); break; case 'MMMM': dateTimeVerbosity = 'long'; dateTimeType = 'month'; dateTimeIdx = date.getMonth(); break; case 'MMM': dateTimeVerbosity = 'medium'; dateTimeType = 'month'; dateTimeIdx = date.getMonth(); break; case 'MM': dateTimeVerbosity = 'short'; dateTimeType = 'month'; dateTimeIdx = date.getMonth(); break; case 'M': dateTimeVerbosity = 'single'; dateTimeType = 'month'; dateTimeIdx = date.getMonth(); break; case 'dd': dateTimeVerbosity = 'short'; dateTimeType = 'date'; dateTimeIdx = date.getDate()-1; break; case 'd': dateTimeVerbosity = 'single'; dateTimeType = 'date'; dateTimeIdx = date.getDate()-1; break; //XXX FIXME case 'zzz': dateTimeVerbosity = ''; if (typeof(self.timezoneFmt) === 'undefined'){ if (typeof(self.inputParams) === 'undefined' || typeof(self.inputParams.TZ) === 'undefined'){ self.timezoneFmt = new enyo.g11n.TzFmt(); }else{ self.timezoneFmt = new enyo.g11n.TzFmt(self.inputParams); } } tz = self.timezoneFmt.getCurrentTimeZone(); acc.push(tz); break; case 'a': dateTimeVerbosity = ''; if(date.getHours() > 11) { acc.push(dtHash.pm); } else { acc.push(dtHash.am); } break; case 'K': dateTimeVerbosity = ''; acc.push(date.getHours() % 12); break; case 'KK': dateTimeVerbosity = ''; hr = date.getHours() % 12; //fix ugliness? acc.push((hr < 10) ? "0"+(""+hr) : hr); break; case 'h': dateTimeVerbosity = ''; hr = (date.getHours() % 12); acc.push(hr === 0 ? 12 : hr) ; break; case 'hh': dateTimeVerbosity = ''; hr = (date.getHours() % 12); // fix ugliness? acc.push(hr === 0 ? 12 : (hr < 10 ? "0" + (""+hr) : hr )) ; break; case 'H': dateTimeVerbosity = ''; acc.push(date.getHours()); break; case 'HH': dateTimeVerbosity = ''; hr = date.getHours(); //fix ugliness? acc.push(hr < 10 ? "0" + (""+hr) : hr); break; case 'k': dateTimeVerbosity = ''; hr = (date.getHours() % 12); acc.push(hr === 0 ? 12 : hr) ; break; case 'kk': dateTimeVerbosity = ''; hr = (date.getHours() % 12); //fix ugliness? acc.push(hr === 0 ? 12 : (hr < 10 ? "0"+(""+hr) : hr)) ; break; case 'EEEE': dateTimeVerbosity = 'long'; dateTimeType = 'day'; dateTimeIdx = date.getDay(); break; case 'EEE': dateTimeVerbosity = 'medium'; dateTimeType = 'day'; dateTimeIdx = date.getDay(); break; case 'EE': dateTimeVerbosity = 'short'; dateTimeType = 'day'; dateTimeIdx = date.getDay(); break; case 'E': dateTimeVerbosity = 'single'; dateTimeType = 'day'; dateTimeIdx = date.getDay(); break; case 'mm': case 'm': //no single minute? dateTimeVerbosity = ''; var mins = date.getMinutes(); acc.push(mins < 10 ? "0" + (""+mins) : mins); break; case 'ss': case 's': //no single second? dateTimeVerbosity = ''; var secs = date.getSeconds(); acc.push(secs < 10 ? "0" + (""+secs) : secs); break; default: tokenized = /'([A-Za-z]+)'/.exec(parsedArray[i]); dateTimeVerbosity = ''; if(tokenized) { acc.push(tokenized[1]); } else { acc.push(parsedArray[i]); } } if(dateTimeVerbosity) { acc.push(dtHash[dateTimeVerbosity][dateTimeType][dateTimeIdx]); } } //var endTime = new Date(); //enyo.log("Time elapsed: " + (endTime.getTime() - startTime.getTime())); return acc.join(""); }; //* @public /** Returns a string with the date formatted according to the format specified in the constructor for this formatter instance. * date (Object): A standard JavaScript date instance to format as a string */ enyo.g11n.DateFmt.prototype.format = function(date) { //var startTime = new Date(); var self = this; if (typeof(date) !== "object" || self.tokenized === null){ enyo.warn("DateFmt.format: no date to format or no format loaded"); return undefined; } return this._format(date, self.tokenized); }; //* @public /** Returns a string with the relative date (i.e., the date in relation to another date). * date (Object): The date/time object to format * options (Object): Options to apply to the formatting. The _options_ object may have the following properties: * referenceDate: The reference date, in relation to which the _date_ is being formatted * verbosity: If true, dates between a week old and a year old are formatted as relative; otherwise, these are formatted normally according to the specifications of the current formatter instance. This method formats a date, taking into consideration its relationship to another date. If the two dates are close in time, the time distance between them is returned, instead of a formatted date. If the two dates are not close, then the date is formatted as per the format set up for the given formatter instance. The relative dates/times are as follows: * today * yesterday * tomorrow * For dates within the last week, the day name * For dates within the last month, the number of weeks ago if _verbosity=true_, or the formatted date otherwise * For dates within the last year, the number of months ago if _verbosity=true_, or the formatted date otherwise * For all other dates, the date formatted according to the rules of the current formatter instance When relative strings are returned, the text in them is already localized to the current locale. */ enyo.g11n.DateFmt.prototype.formatRelativeDate = function(date, options) { var refDate, verbosity, template, offset, self = this; if (typeof(date) !== 'object'){ return undefined; } if (typeof(options) === 'undefined'){ verbosity = false; refDate = new Date(); }else{ if (typeof(options.referenceDate) !== 'undefined'){ refDate = options.referenceDate; }else{ refDate = new Date(); } if (typeof(options.verbosity) !== 'undefined'){ verbosity = options.verbosity; }else{ verbosity = false; } } offset = self._dayOffset(refDate, date); switch (offset) { case 0: return self.dateTimeHash.relative.today; case 1: return self.dateTimeHash.relative.yesterday; case -1: return self.dateTimeHash.relative.tomorrow; default: if (offset < 7) { return self.dateTimeHash.long.day[date.getDay()]; } else if (offset < 30) { if(verbosity){ template = new enyo.g11n.Template(self.dateTimeHash.relative.thisMonth); var weeks = Math.floor(offset / 7); return template.formatChoice(weeks,{num: weeks}); } else { return self.format(date); } } else if (offset < 365) { if (verbosity){ template = new enyo.g11n.Template(self.dateTimeHash.relative.thisYear); var months = Math.floor(offset / 30); return template.formatChoice(months, {num: months}); } else { return self.format(date); } } else { return self.format(date); } } }; /** Returns a string in which a pair of dates are formatted as a date range. * dateStart (Object): The date at the start of the range * dateEnd (Object): The date at the end of the range This method formats a pair of dates as a date/time range, from start to end, according to the settings of the formatter object. The format of the output string is determined as follows: * If the dates are on the same calendar day, the format is a time range of the form *(starttime_to_endtime, month+date)*. * If the dates are on different calendar days, but are in the same calendar month, the format is a date range of the form *(month date_to_date, year)*. * If the dates are on different calendar days and in different calendar months, but the same calendar year, the format is a date range of the form _(month+date to month+date, year)_. * If the dates are in different, but consecutive, calendar years, the format is a date range of the form _(month+date+year to month+date+year)_. * If the dates are more than two years apart, the format is a date range of the form _(year to year)_. The order of the month, date, and year in the above formats is locale-dependent, as are the separator characters. For example, if the start date is September 2, 2011, and the end date is September 5, 2011, the ranges would be: * US English: "Sept 2-5, 2011" * British English: "2-5 Sept, 2011" * German: "2.-5. Sept, 2011" The length of the month abbreviations is determined by the date verbosity with which the current formatter object was constructed. If the end date precedes the start date, the dates will be switched so that the earlier date becomes the start date. The text in the returned string will be localized to the locale of the formatter instance. */ enyo.g11n.DateFmt.prototype.formatRange = function(dateStart, dateEnd) { var temp, timeFmt, dateFmt, name, year, templ, startDay, endDay, formatLength = this.partsLength || "medium", dtHash = this.dateTimeHash, dtfHash = this.dateTimeFormatHash; if (!dateStart && !dateEnd) { return ""; } else if (!dateStart || !dateEnd) { return this.format(dateStart || dateEnd); } // make sure they are in the right order if (dateEnd.getTime() < dateStart.getTime()) { temp = dateEnd; dateEnd = dateStart; dateStart = temp; } startDay = new Date(dateStart.getTime()); startDay.setHours(0); startDay.setMinutes(0); startDay.setSeconds(0); startDay.setMilliseconds(0); endDay = new Date(dateEnd.getTime()); endDay.setHours(0); endDay.setMinutes(0); endDay.setSeconds(0); endDay.setMilliseconds(0); // 86400000 = the number of milliseconds in 1 day if ((endDay.getTime() - startDay.getTime()) === 86400000) { // if the dates on are on consecutive days, no matter if they are in different years or months or whatever, it should be formatted // with the time as well name = "shortTime" + (this.twelveHourFormat ? "12" : "24"); timeFmt = this._getTokenizedFormat(dtfHash[name]); name = formatLength + "Date"; dateFmt = this._getTokenizedFormat(dtfHash[name]); templ = new enyo.g11n.Template(this.rb.$L({key: "dateRangeConsecutiveDays", value: "#{startDate} #{startTime} - #{endDate} #{endTime}"})); return templ.evaluate({ startTime: this._format(dateStart, timeFmt), endTime: this._format(dateEnd, timeFmt), startDate: this._format(dateStart, dateFmt), endDate: this._format(dateEnd, dateFmt) }); } else if (dateStart.getYear() === dateEnd.getYear()) { year = (formatLength === 'short' || formatLength === 'single') ? (dateStart.getFullYear() + "").substring(2) : dateStart.getFullYear(); if (dateStart.getMonth() === dateEnd.getMonth()) { if (dateStart.getDate() === dateEnd.getDate()) { // format a time range on the same day name = "shortTime" + (this.twelveHourFormat ? "12" : "24"); timeFmt = this._getTokenizedFormat(dtfHash[name]); name = formatLength + "Date"; dateFmt = this._getTokenizedFormat(dtfHash[name]); templ = new enyo.g11n.Template(this.rb.$L({key: "dateRangeWithinDay", value: "#{startTime}-#{endTime}, #{date}"})); return templ.evaluate({ startTime: this._format(dateStart, timeFmt), endTime: this._format(dateEnd, timeFmt), date: this._format(dateStart, dateFmt) }); } else { name = formatLength + "DDate"; dateFmt = this._getTokenizedFormat(dtfHash[name]); templ = new enyo.g11n.Template(this.rb.$L({key: "dateRangeWithinMonth", value: "#{month} #{startDate}-#{endDate}, #{year}"})); return templ.evaluate({ month: dtHash[formatLength].month[dateStart.getMonth()], startDate: this._format(dateStart, dateFmt), endDate: this._format(dateEnd, dateFmt), year: year }); } } else { if (formatLength === 'full') { // there is no full DM format formatLength = "long"; } else if (formatLength === 'single') { // nor short formatLength = "short"; } name = formatLength + "DMDate"; dateFmt = this._getTokenizedFormat(dtfHash[name]); templ = new enyo.g11n.Template(this.rb.$L({key: "dateRangeWithinYear", value: "#{start} - #{end}, #{year}"})); return templ.evaluate({ start: this._format(dateStart, dateFmt), end: this._format(dateEnd, dateFmt), year: year }); } } else if (dateEnd.getYear() - dateStart.getYear() < 2) { name = formatLength + "Date"; dateFmt = this._getTokenizedFormat(dtfHash[name]); templ = new enyo.g11n.Template(this.rb.$L({key: "dateRangeWithinConsecutiveYears", value: "#{start} - #{end}"})); return templ.evaluate({ start: this._format(dateStart, dateFmt), end: this._format(dateEnd, dateFmt) }); } else { if (formatLength === 'full') { // there is no full MY format formatLength = "long"; } else if (formatLength === 'single') { // nor short formatLength = "short"; } name = formatLength + "MYDate"; dateFmt = this._getTokenizedFormat(dtfHash[name]); templ = new enyo.g11n.Template(this.rb.$L({key: "dateRangeMultipleYears", value: "#{startMonthYear} - #{endMonthYear}"})); return templ.evaluate({ startMonthYear: this._format(dateStart, dateFmt), endMonthYear: this._format(dateEnd, dateFmt) }); } };