static SoupDate* msToSoupDate(double ms) { int year = msToYear(ms); int dayOfYear = dayInYear(ms, year); bool leapYear = isLeapYear(year); return soup_date_new(year, monthFromDayInYear(dayOfYear, leapYear), dayInMonthFromDayInYear(dayOfYear, leapYear), msToHours(ms), msToMinutes(ms), static_cast<int>(ms / 1000) % 60); }
bool DateComponents::setMillisecondsSinceEpochForDateInternal(double ms) { m_year = msToYear(ms); int yearDay = dayInYear(ms, m_year); m_month = monthFromDayInYear(yearDay, isLeapYear(m_year)); m_monthDay = dayInMonthFromDayInYear(yearDay, isLeapYear(m_year)); return true; }
bool DateComponents::setMillisecondsSinceEpochForWeek(double ms) { m_type = Invalid; if (!std::isfinite(ms)) return false; ms = round(ms); m_year = msToYear(ms); if (m_year < minimumYear() || m_year > maximumYear()) return false; int yearDay = dayInYear(ms, m_year); int offset = offsetTo1stWeekStart(m_year); if (yearDay < offset) { // The day belongs to the last week of the previous year. m_year--; if (m_year <= minimumYear()) return false; m_week = maxWeekNumberInYear(); } else { m_week = ((yearDay - offset) / 7) + 1; if (m_week > maxWeekNumberInYear()) { m_year++; m_week = 1; } if (m_year > maximumYear() || (m_year == maximumYear() && m_week > maximumWeekInMaximumYear)) return false; } m_type = Week; return true; }
static inline int msToMonth(double ms) { int step; int year = msToYear(ms); int d = dayInYear(ms, year); if (d < (step = 31)) return 0; step += (isInLeapYear(ms) ? 29 : 28); if (d < step) return 1; if (d < (step += 31)) return 2; if (d < (step += 30)) return 3; if (d < (step += 31)) return 4; if (d < (step += 30)) return 5; if (d < (step += 31)) return 6; if (d < (step += 31)) return 7; if (d < (step += 30)) return 8; if (d < (step += 31)) return 9; if (d < (step += 30)) return 10; return 11; }
void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) { // input is UTC double dstOff = 0.0; const double utcOff = getUTCOffset(); if (!outputIsUTC) { // convert to local time dstOff = getDSTOffset(ms, utcOff); ms += dstOff + utcOff; } const int year = msToYear(ms); tm.second = msToSeconds(ms); tm.minute = msToMinutes(ms); tm.hour = msToHours(ms); tm.weekDay = msToWeekDay(ms); tm.yearDay = dayInYear(ms, year); tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; tm.isDST = dstOff != 0.0; tm.utcOffset = outputIsUTC ? 0 : static_cast<long>((dstOff + utcOff) / msPerSecond); tm.timeZone = NULL; }
double dateToDaysFrom1970(int year, int month, int day) { year += month / 12; month %= 12; if (month < 0) { month += 12; --year; } double yearday = floor(daysFrom1970ToYear(year)); ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0)); return yearday + dayInYear(year, month, day); }
void GregorianDateTime::setToCurrentLocalTime() { #if OS(WINDOWS) SYSTEMTIME systemTime; GetLocalTime(&systemTime); TIME_ZONE_INFORMATION timeZoneInformation; DWORD timeZoneId = GetTimeZoneInformation(&timeZoneInformation); LONG bias = 0; if (timeZoneId != TIME_ZONE_ID_INVALID) { bias = timeZoneInformation.Bias; if (timeZoneId == TIME_ZONE_ID_DAYLIGHT) bias += timeZoneInformation.DaylightBias; else if ((timeZoneId == TIME_ZONE_ID_STANDARD) || (timeZoneId == TIME_ZONE_ID_UNKNOWN)) bias += timeZoneInformation.StandardBias; else ASSERT(0); } m_year = systemTime.wYear; m_month = systemTime.wMonth - 1; m_monthDay = systemTime.wDay; m_yearDay = dayInYear(m_year, m_month, m_monthDay); m_weekDay = systemTime.wDayOfWeek; m_hour = systemTime.wHour; m_minute = systemTime.wMinute; m_second = systemTime.wSecond; m_utcOffset = -bias * secondsPerMinute; m_isDST = timeZoneId == TIME_ZONE_ID_DAYLIGHT ? 1 : 0; #else tm localTM; time_t localTime = time(0); localtime_r(&localTime, &localTM); m_year = localTM.tm_year + 1900; m_month = localTM.tm_mon; m_monthDay = localTM.tm_mday; m_yearDay = localTM.tm_yday; m_weekDay = localTM.tm_wday; m_hour = localTM.tm_hour; m_minute = localTM.tm_min; m_second = localTM.tm_sec; m_isDST = localTM.tm_isdst; #if HAVE(TM_GMTOFF) m_utcOffset = localTM.tm_gmtoff; #else m_utcOffset = calculateLocalTimeOffset(localTime * msPerSecond).offset / msPerSecond; #endif #endif }
// Returns combined offset in millisecond (UTC + DST). LocalTimeOffset calculateLocalTimeOffset(double ms, TimeType inputTimeType) { #if HAVE(TM_GMTOFF) double localToUTCTimeOffset = inputTimeType == LocalTime ? calculateUTCOffset() : 0; #else double localToUTCTimeOffset = calculateUTCOffset(); #endif if (inputTimeType == LocalTime) ms -= localToUTCTimeOffset; // On Mac OS X, the call to localtime (see calculateDSTOffset) will return historically accurate // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript // standard explicitly dictates that historical information should not be considered when // determining DST. For this reason we shift away from years that localtime can handle but would // return historically accurate information. int year = msToYear(ms); int equivalentYear = equivalentYearForDST(year); if (year != equivalentYear) { bool leapYear = isLeapYear(year); int dayInYearLocal = dayInYear(ms, year); int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); int month = monthFromDayInYear(dayInYearLocal, leapYear); double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); ms = (day * msPerDay) + msToMilliseconds(ms); } double localTimeSeconds = ms / msPerSecond; if (localTimeSeconds > maxUnixTime) localTimeSeconds = maxUnixTime; else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0). localTimeSeconds += secondsPerDay; // FIXME: time_t has a potential problem in 2038. time_t localTime = static_cast<time_t>(localTimeSeconds); #if HAVE(TM_GMTOFF) tm localTM; getLocalTime(&localTime, &localTM); return LocalTimeOffset(localTM.tm_isdst, localTM.tm_gmtoff * msPerSecond); #else double dstOffset = calculateDSTOffset(localTime, localToUTCTimeOffset); return LocalTimeOffset(dstOffset, localToUTCTimeOffset + dstOffset); #endif }
static inline int msToDayInMonth(double ms) { int step, next; int year = msToYear(ms); int d = dayInYear(ms, year); if (d <= (next = 30)) return d + 1; step = next; next += (isInLeapYear(ms) ? 29 : 28); if (d <= next) return d - step; step = next; if (d <= (next += 31)) return d - step; step = next; if (d <= (next += 30)) return d - step; step = next; if (d <= (next += 31)) return d - step; step = next; if (d <= (next += 30)) return d - step; step = next; if (d <= (next += 31)) return d - step; step = next; if (d <= (next += 31)) return d - step; step = next; if (d <= (next += 30)) return d - step; step = next; if (d <= (next += 31)) return d - step; step = next; if (d <= (next += 30)) return d - step; step = next; return d - step; }
// Get the DST offset, given a time in UTC static double calculateDSTOffset(double ms, double utcOffset) { // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript // standard explicitly dictates that historical information should not be considered when // determining DST. For this reason we shift away from years that localtime can handle but would // return historically accurate information. int year = msToYear(ms); int equivalentYear = equivalentYearForDST(year); if (year != equivalentYear) { bool leapYear = isLeapYear(year); int dayInYearLocal = dayInYear(ms, year); int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); int month = monthFromDayInYear(dayInYearLocal, leapYear); double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); ms = (day * msPerDay) + msToMilliseconds(ms); } return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset); }
// input is UTC void msToGregorianDateTime(VM& vm, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm) { LocalTimeOffset localTime; if (outputTimeType == WTF::LocalTime) { localTime = localTimeOffset(vm, ms); ms += localTime.offset; } const int year = msToYear(ms); tm.setSecond(msToSeconds(ms)); tm.setMinute(msToMinutes(ms)); tm.setHour(msToHours(ms)); tm.setWeekDay(msToWeekDay(ms)); tm.setYearDay(dayInYear(ms, year)); tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setYear(year); tm.setIsDST(localTime.isDST); tm.setUtcOffset(localTime.offset / WTF::msPerSecond); }
// input is UTC void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) { LocalTimeOffset localTime(false, 0); if (!outputIsUTC) { localTime = localTimeOffset(exec, ms); ms += localTime.offset; } const int year = msToYear(ms); tm.second = msToSeconds(ms); tm.minute = msToMinutes(ms); tm.hour = msToHours(ms); tm.weekDay = msToWeekDay(ms); tm.yearDay = dayInYear(ms, year); tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; tm.isDST = localTime.isDST; tm.utcOffset = localTime.offset / WTF::msPerSecond; tm.timeZone = NULL; }
// input is UTC void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) { double dstOff = 0.0; double utcOff = 0.0; if (!outputIsUTC) { utcOff = getUTCOffset(exec); dstOff = getDSTOffset(exec, ms, utcOff); ms += dstOff + utcOff; } const int year = msToYear(ms); tm.setSecond(msToSeconds(ms)); tm.setMinute(msToMinutes(ms)); tm.setHour(msToHours(ms)); tm.setWeekDay(msToWeekDay(ms)); tm.setYearDay(dayInYear(ms, year)); tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year))); tm.setYear(year); tm.setIsDST(dstOff != 0.0); tm.setUtcOffset(static_cast<long>((dstOff + utcOff) / WTF::msPerSecond)); }
// input is UTC void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) { double dstOff = 0.0; double utcOff = 0.0; if (!outputIsUTC) { utcOff = getUTCOffset(exec); dstOff = getDSTOffset(exec, ms, utcOff); ms += dstOff + utcOff; } const int year = msToYear(ms); tm.second = msToSeconds(ms); tm.minute = msToMinutes(ms); tm.hour = msToHours(ms); tm.weekDay = msToWeekDay(ms); tm.yearDay = dayInYear(ms, year); tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); tm.year = year - 1900; tm.isDST = dstOff != 0.0; tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond); tm.timeZone = NULL; }
void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) { // input is UTC double dstOff = 0.0; if (!outputIsUTC) { // convert to local time dstOff = getDSTOffset(ms); ms += dstOff + getUTCOffset(); } tm.second = msToSeconds(ms); tm.minute = msToMinutes(ms); tm.hour = msToHours(ms); tm.weekDay = msToWeekDay(ms); tm.monthDay = msToDayInMonth(ms); tm.yearDay = dayInYear(ms, msToYear(ms)); tm.month = msToMonth(ms); tm.year = msToYear(ms) - 1900; tm.isDST = dstOff != 0.0; tm.utcOffset = static_cast<long>((dstOff + getUTCOffset()) / msPerSecond); tm.timeZone = NULL; }
char* DS3231::dateFormat(const char* dateFormat, RTCDateTime dt) { char buffer[255]; buffer[0] = 0; char helper[11]; while (*dateFormat != '\0') { switch (dateFormat[0]) { // Day decoder case 'd': sprintf(helper, "%02d", dt.day); strcat(buffer, (const char *)helper); break; case 'j': sprintf(helper, "%d", dt.day); strcat(buffer, (const char *)helper); break; case 'l': strcat(buffer, (const char *)strDayOfWeek(dt.dayOfWeek)); break; case 'D': strncat(buffer, strDayOfWeek(dt.dayOfWeek), 3); break; case 'N': sprintf(helper, "%d", dt.dayOfWeek); strcat(buffer, (const char *)helper); break; case 'w': sprintf(helper, "%d", (dt.dayOfWeek + 7) % 7); strcat(buffer, (const char *)helper); break; case 'z': sprintf(helper, "%d", dayInYear(dt.year, dt.month, dt.day)); strcat(buffer, (const char *)helper); break; case 'S': strcat(buffer, (const char *)strDaySufix(dt.day)); break; // Month decoder case 'm': sprintf(helper, "%02d", dt.month); strcat(buffer, (const char *)helper); break; case 'n': sprintf(helper, "%d", dt.month); strcat(buffer, (const char *)helper); break; case 'F': strcat(buffer, (const char *)strMonth(dt.month)); break; case 'M': strncat(buffer, (const char *)strMonth(dt.month), 3); break; case 't': sprintf(helper, "%d", daysInMonth(dt.year, dt.month)); strcat(buffer, (const char *)helper); break; // Year decoder case 'Y': sprintf(helper, "%d", dt.year); strcat(buffer, (const char *)helper); break; case 'y': sprintf(helper, "%02d", dt.year-2000); strcat(buffer, (const char *)helper); break; case 'L': sprintf(helper, "%d", isLeapYear(dt.year)); strcat(buffer, (const char *)helper); break; // Hour decoder case 'H': sprintf(helper, "%02d", dt.hour); strcat(buffer, (const char *)helper); break; case 'G': sprintf(helper, "%d", dt.hour); strcat(buffer, (const char *)helper); break; case 'h': sprintf(helper, "%02d", hour12(dt.hour)); strcat(buffer, (const char *)helper); break; case 'g': sprintf(helper, "%d", hour12(dt.hour)); strcat(buffer, (const char *)helper); break; case 'A': strcat(buffer, (const char *)strAmPm(dt.hour, true)); break; case 'a': strcat(buffer, (const char *)strAmPm(dt.hour, false)); break; // Minute decoder case 'i': sprintf(helper, "%02d", dt.minute); strcat(buffer, (const char *)helper); break; // Second decoder case 's': sprintf(helper, "%02d", dt.second); strcat(buffer, (const char *)helper); break; // Misc decoder case 'U': sprintf(helper, "%lu", dt.unixtime); strcat(buffer, (const char *)helper); break; default: strncat(buffer, dateFormat, 1); break; } dateFormat++; } return buffer; }