bool DateComponents::addDay(int dayDiff) { ASSERT(m_monthDay); int day = m_monthDay + dayDiff; if (day > maxDayOfMonth(m_year, m_month)) { day = m_monthDay; int year = m_year; int month = m_month; int maxDay = maxDayOfMonth(year, month); for (; dayDiff > 0; --dayDiff) { ++day; if (day > maxDay) { day = 1; ++month; if (month >= 12) { // month is 0-origin. month = 0; ++year; } maxDay = maxDayOfMonth(year, month); } } if (!withinHTMLDateLimits(year, month, day)) return false; m_year = year; m_month = month; } else if (day < 1) { int month = m_month; int year = m_year; day = m_monthDay; for (; dayDiff < 0; ++dayDiff) { --day; if (day < 1) { --month; if (month < 0) { month = 11; --year; } day = maxDayOfMonth(year, month); } } if (!withinHTMLDateLimits(year, month, day)) return false; m_year = year; m_month = month; } else { if (!withinHTMLDateLimits(m_year, m_month, day)) return false; } m_monthDay = day; return true; }
bool DateComponents::addMinute(int minute) { // This function is used to adjust timezone offset. So m_year, m_month, // m_monthDay have values between the lower and higher limits. ASSERT(withinHTMLDateLimits(m_year, m_month, m_monthDay)); int carry; // minute can be negative or greater than 59. minute += m_minute; if (minute > 59) { carry = minute / 60; minute = minute % 60; } else if (minute < 0) { carry = (59 - minute) / 60; minute += carry * 60; carry = -carry; ASSERT(minute >= 0 && minute <= 59); } else { if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, minute, m_second, m_millisecond)) return false; m_minute = minute; return true; } int hour = m_hour + carry; if (hour > 23) { carry = hour / 24; hour = hour % 24; } else if (hour < 0) { carry = (23 - hour) / 24; hour += carry * 24; carry = -carry; ASSERT(hour >= 0 && hour <= 23); } else { if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond)) return false; m_minute = minute; m_hour = hour; return true; } if (!addDay(carry)) return false; if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond)) return false; m_minute = minute; m_hour = hour; return true; }
bool DateComponents::setMillisecondsSinceEpochForMonth(double ms) { m_type = Invalid; if (!std::isfinite(ms)) return false; if (!setMillisecondsSinceEpochForDateInternal(round(ms))) return false; if (!withinHTMLDateLimits(m_year, m_month)) return false; m_type = Month; return true; }
bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms) { m_type = Invalid; if (!std::isfinite(ms)) return false; ms = round(ms); setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay)); if (!setMillisecondsSinceEpochForDateInternal(ms)) return false; if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond)) return false; m_type = DateTime; return true; }
bool DateComponents::setMonthsSinceEpoch(double months) { if (!std::isfinite(months)) return false; months = round(months); double doubleMonth = positiveFmod(months, 12); double doubleYear = 1970 + (months - doubleMonth) / 12; if (doubleYear < minimumYear() || maximumYear() < doubleYear) return false; int year = static_cast<int>(doubleYear); int month = static_cast<int>(doubleMonth); if (!withinHTMLDateLimits(year, month)) return false; m_year = year; m_month = month; m_type = Month; return true; }
bool DateComponents::parseDateTimeLocal(const String& src, unsigned start, unsigned& end) { unsigned index; if (!parseDate(src, start, index)) return false; if (index >= src.length()) return false; if (src[index] != 'T') return false; ++index; if (!parseTime(src, index, end)) return false; if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond)) return false; m_type = DateTimeLocal; return true; }
bool DateComponents::parseMonth(const String& src, unsigned start, unsigned& end) { unsigned index; if (!parseYear(src, start, index)) return false; if (index >= src.length() || src[index] != '-') return false; ++index; int month; if (!toInt(src, index, 2, month) || month < 1 || month > 12) return false; --month; if (!withinHTMLDateLimits(m_year, month)) return false; m_month = month; end = index + 2; m_type = Month; return true; }
bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end) { ASSERT(src); unsigned index; if (!parseDate(src, length, start, index)) return false; if (index >= length) return false; if (src[index] != 'T') return false; ++index; if (!parseTime(src, length, index, index)) return false; if (!parseTimeZone(src, length, index, end)) return false; if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond)) return false; m_type = DateTime; return true; }
bool DateComponents::parseDate(const String& src, unsigned start, unsigned& end) { unsigned index; if (!parseMonth(src, start, index)) return false; // '-' and 2-digits are needed. if (index + 2 >= src.length()) return false; if (src[index] != '-') return false; ++index; int day; if (!toInt(src, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month)) return false; if (!withinHTMLDateLimits(m_year, m_month, day)) return false; m_monthDay = day; end = index + 2; m_type = Date; return true; }