UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

374 lines (346 loc) 13 kB
/*! * OpenUI5 * (c) Copyright 2009-2021 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides class sap.ui.core.date.UniversalDate sap.ui.define(['sap/ui/base/Object', 'sap/ui/core/LocaleData', './_Calendars'], function(BaseObject, LocaleData, _Calendars) { "use strict"; /** * Constructor for UniversalDate. * * @class * The UniversalDate is the base class of calendar date instances. It contains the static methods to create calendar * specific instances. * * The member variable <code>this.oDate</code> contains the JS Date object, which is the source value of the date information. * The prototype is containing getters and setters of the JS Date and is delegating them to the internal date object. * Implementations for specific calendars may override methods needed for their specific calendar (e.g. getYear * and getEra for Japanese emperor calendar); * * @private * @ui5-restricted * @alias sap.ui.core.date.UniversalDate */ var UniversalDate = BaseObject.extend("sap.ui.core.date.UniversalDate", /** @lends sap.ui.core.date.UniversalDate.prototype */ { constructor: function() { var clDate = UniversalDate.getClass(); return this.createDate(clDate, arguments); } }); UniversalDate.UTC = function() { var clDate = UniversalDate.getClass(); return clDate.UTC.apply(clDate, arguments); }; UniversalDate.now = function() { return Date.now(); }; UniversalDate.prototype.createDate = function(clDate, aArgs) { switch (aArgs.length) { case 0: return new clDate(); // new Date(new Date()) is officially not supported // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date // IE 11 loses milliseconds when using new Date(new Date()) // var oDateWithMs = new Date(1985, 9, 9, 13, 37, 13, 370); // new Date(oDateWithMs).getMilliseconds(); // ie11: 0 // chrome/edge/safari/ff: 370 // -> Date#getTime to circumvent this problem // this is e.g. executed when calling <code>new UniversalDate(oDateWithMs)</code> case 1: return new clDate(aArgs[0] instanceof Date ? aArgs[0].getTime() : aArgs[0]); case 2: return new clDate(aArgs[0], aArgs[1]); case 3: return new clDate(aArgs[0], aArgs[1], aArgs[2]); case 4: return new clDate(aArgs[0], aArgs[1], aArgs[2], aArgs[3]); case 5: return new clDate(aArgs[0], aArgs[1], aArgs[2], aArgs[3], aArgs[4]); case 6: return new clDate(aArgs[0], aArgs[1], aArgs[2], aArgs[3], aArgs[4], aArgs[5]); case 7: return new clDate(aArgs[0], aArgs[1], aArgs[2], aArgs[3], aArgs[4], aArgs[5], aArgs[6]); } }; /** * Returns an instance of Date, based on the calendar type from the configuration, or as explicitly * defined by parameter. The object provides all methods also known on the JavaScript Date object. * * Note: Prefer this method over calling <code>new UniversalDate</code> with an instance of <code>Date</code> * * @param {Date|sap.ui.core.date.UniversalDate} [oDate] JavaScript date object, defaults to <code>new Date()</code> * @param {sap.ui.core.CalendarType} [sCalendarType] The calendar type, defaults to <code>sap.ui.getCore().getConfiguration().getCalendarType()</code> * @returns {sap.ui.core.date.UniversalDate} The date instance * @public */ UniversalDate.getInstance = function(oDate, sCalendarType) { var clDate, oInstance; if (oDate instanceof UniversalDate) { oDate = oDate.getJSDate(); } else if (!oDate) { oDate = new Date(); } if (!sCalendarType) { sCalendarType = sap.ui.getCore().getConfiguration().getCalendarType(); } clDate = UniversalDate.getClass(sCalendarType); oInstance = Object.create(clDate.prototype); oInstance.oDate = oDate; oInstance.sCalendarType = sCalendarType; return oInstance; }; /** * Returns a specific Date class, based on the calendar type from the configuration, or as explicitly * defined by parameter. The object provides all methods also known on the JavaScript Date object. * * @param {sap.ui.core.CalendarType} sCalendarType the type of the used calendar * @public */ UniversalDate.getClass = function(sCalendarType) { if (!sCalendarType) { sCalendarType = sap.ui.getCore().getConfiguration().getCalendarType(); } return _Calendars.get(sCalendarType); }; /* * Loop through the Date class and create delegates of all Date API methods */ [ "getDate", "getMonth", "getFullYear", "getYear", "getDay", "getHours", "getMinutes", "getSeconds", "getMilliseconds", "getUTCDate", "getUTCMonth", "getUTCFullYear", "getUTCDay", "getUTCHours", "getUTCMinutes", "getUTCSeconds", "getUTCMilliseconds", "getTime", "valueOf", "getTimezoneOffset", "toString", "toDateString", "setDate", "setFullYear", "setYear", "setMonth", "setHours", "setMinutes", "setSeconds", "setMilliseconds", "setUTCDate", "setUTCFullYear", "setUTCMonth", "setUTCHours", "setUTCMinutes", "setUTCSeconds", "setUTCMilliseconds" ].forEach(function(sName) { UniversalDate.prototype[sName] = function() { return this.oDate[sName].apply(this.oDate, arguments); }; }); /** * Returns the JS date object representing the current calendar date value. * * @returns {Date} The JS date object representing the current calendar date value * @public */ UniversalDate.prototype.getJSDate = function() { return this.oDate; }; /** * Returns the calendar type of the current instance of a UniversalDate. * * @returns {sap.ui.core.CalendarType} The calendar type of the date */ UniversalDate.prototype.getCalendarType = function() { return this.sCalendarType; }; /* * Provide additional getters/setters, not yet covered by the JS Date */ UniversalDate.prototype.getEra = function() { return UniversalDate.getEraByDate(this.sCalendarType, this.oDate.getFullYear(), this.oDate.getMonth(), this.oDate.getDate()); }; UniversalDate.prototype.setEra = function(iEra) { // The default implementation does not support setting the era }; UniversalDate.prototype.getUTCEra = function() { return UniversalDate.getEraByDate(this.sCalendarType, this.oDate.getUTCFullYear(), this.oDate.getUTCMonth(), this.oDate.getUTCDate()); }; UniversalDate.prototype.setUTCEra = function(iEra) { // The default implementation does not support setting the era }; UniversalDate.prototype.getWeek = function() { return UniversalDate.getWeekByDate(this.sCalendarType, this.getFullYear(), this.getMonth(), this.getDate()); }; UniversalDate.prototype.setWeek = function(oWeek) { var oDate = UniversalDate.getFirstDateOfWeek(this.sCalendarType, oWeek.year || this.getFullYear(), oWeek.week); this.setFullYear(oDate.year, oDate.month, oDate.day); }; UniversalDate.prototype.getUTCWeek = function() { return UniversalDate.getWeekByDate(this.sCalendarType, this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate()); }; UniversalDate.prototype.setUTCWeek = function(oWeek) { var oDate = UniversalDate.getFirstDateOfWeek(this.sCalendarType, oWeek.year || this.getFullYear(), oWeek.week); this.setUTCFullYear(oDate.year, oDate.month, oDate.day); }; UniversalDate.prototype.getQuarter = function() { return Math.floor((this.getMonth() / 3)); }; UniversalDate.prototype.getUTCQuarter = function() { return Math.floor((this.getUTCMonth() / 3)); }; UniversalDate.prototype.getDayPeriod = function() { if (this.getHours() < 12) { return 0; } else { return 1; } }; UniversalDate.prototype.getUTCDayPeriod = function() { if (this.getUTCHours() < 12) { return 0; } else { return 1; } }; // TODO: These are currently needed for the DateFormat test, as the date used in the test // has been enhanced with these methods. Should be implemented using CLDR data. UniversalDate.prototype.getTimezoneShort = function() { if (this.oDate.getTimezoneShort) { return this.oDate.getTimezoneShort(); } }; UniversalDate.prototype.getTimezoneLong = function() { if (this.oDate.getTimezoneLong) { return this.oDate.getTimezoneLong(); } }; /* * Helper methods for week calculations */ var iMillisecondsInWeek = 7 * 24 * 60 * 60 * 1000; UniversalDate.getWeekByDate = function(sCalendarType, iYear, iMonth, iDay) { var oLocale = sap.ui.getCore().getConfiguration().getFormatSettings().getFormatLocale(), clDate = this.getClass(sCalendarType), oFirstDay = getFirstDayOfFirstWeek(clDate, iYear), oDate = new clDate(clDate.UTC(iYear, iMonth, iDay)), iWeek, iLastYear, iNextYear, oLastFirstDay, oNextFirstDay; // If region is US, always calculate the week for the current year, otherwise // the week might be the last week of the previous year or first week of next year if (oLocale.getRegion() === "US") { iWeek = calculateWeeks(oFirstDay, oDate); } else { iLastYear = iYear - 1; iNextYear = iYear + 1; oLastFirstDay = getFirstDayOfFirstWeek(clDate, iLastYear); oNextFirstDay = getFirstDayOfFirstWeek(clDate, iNextYear); if (oDate >= oNextFirstDay) { iYear = iNextYear; iWeek = 0; } else if (oDate < oFirstDay) { iYear = iLastYear; iWeek = calculateWeeks(oLastFirstDay, oDate); } else { iWeek = calculateWeeks(oFirstDay, oDate); } } return { year: iYear, week: iWeek }; }; UniversalDate.getFirstDateOfWeek = function(sCalendarType, iYear, iWeek) { var oLocale = sap.ui.getCore().getConfiguration().getFormatSettings().getFormatLocale(), clDate = this.getClass(sCalendarType), oFirstDay = getFirstDayOfFirstWeek(clDate, iYear), oDate = new clDate(oFirstDay.valueOf() + iWeek * iMillisecondsInWeek); //If first day of week is in last year and region is US, return the //1st of January instead for symmetric behaviour if (oLocale.getRegion() === "US" && iWeek === 0 && oFirstDay.getUTCFullYear() < iYear) { return { year: iYear, month: 0, day: 1 }; } return { year: oDate.getUTCFullYear(), month: oDate.getUTCMonth(), day: oDate.getUTCDate() }; }; function getFirstDayOfFirstWeek(clDate, iYear) { var oLocale = sap.ui.getCore().getConfiguration().getFormatSettings().getFormatLocale(), oLocaleData = LocaleData.getInstance(oLocale), iMinDays = oLocaleData.getMinimalDaysInFirstWeek(), iFirstDayOfWeek = oLocaleData.getFirstDayOfWeek(), oFirstDay = new clDate(clDate.UTC(iYear, 0, 1)), iDayCount = 7; // Find the first day of the first week of the year while (oFirstDay.getUTCDay() !== iFirstDayOfWeek) { oFirstDay.setUTCDate(oFirstDay.getUTCDate() - 1); iDayCount--; } // If less than min days are left, first week is one week later if (iDayCount < iMinDays) { oFirstDay.setUTCDate(oFirstDay.getUTCDate() + 7); } return oFirstDay; } function calculateWeeks(oFromDate, oToDate) { return Math.floor((oToDate.valueOf() - oFromDate.valueOf()) / iMillisecondsInWeek); } /* * Helper methods for era calculations */ var mEras = {}; UniversalDate.getEraByDate = function(sCalendarType, iYear, iMonth, iDay) { var aEras = getEras(sCalendarType), iTimestamp = new Date(0).setUTCFullYear(iYear, iMonth, iDay), oEra; for (var i = aEras.length - 1; i >= 0; i--) { oEra = aEras[i]; if (!oEra) { continue; } if (oEra._start && iTimestamp >= oEra._startInfo.timestamp) { return i; } if (oEra._end && iTimestamp < oEra._endInfo.timestamp) { return i; } } }; UniversalDate.getCurrentEra = function(sCalendarType) { var oNow = new Date(); return this.getEraByDate(sCalendarType, oNow.getFullYear(), oNow.getMonth(), oNow.getDate()); }; UniversalDate.getEraStartDate = function(sCalendarType, iEra) { var aEras = getEras(sCalendarType), oEra = aEras[iEra] || aEras[0]; if (oEra._start) { return oEra._startInfo; } }; function getEras(sCalendarType) { var oLocale = sap.ui.getCore().getConfiguration().getFormatSettings().getFormatLocale(), oLocaleData = LocaleData.getInstance(oLocale), aEras = mEras[sCalendarType]; if (!aEras) { // Get eras from localedata, parse it and add it to the array var aEras = oLocaleData.getEraDates(sCalendarType); if (!aEras[0]) { aEras[0] = {_start: "1-1-1"}; } for (var i = 0; i < aEras.length; i++) { var oEra = aEras[i]; if (!oEra) { continue; } if (oEra._start) { oEra._startInfo = parseDateString(oEra._start); } if (oEra._end) { oEra._endInfo = parseDateString(oEra._end); } } mEras[sCalendarType] = aEras; } return aEras; } function parseDateString(sDateString) { var aParts = sDateString.split("-"), iYear, iMonth, iDay; if (aParts[0] == "") { // negative year iYear = -parseInt(aParts[1]); iMonth = parseInt(aParts[2]) - 1; iDay = parseInt(aParts[3]); } else { iYear = parseInt(aParts[0]); iMonth = parseInt(aParts[1]) - 1; iDay = parseInt(aParts[2]); } return { timestamp: new Date(0).setUTCFullYear(iYear, iMonth, iDay), year: iYear, month: iMonth, day: iDay }; } return UniversalDate; });