From 5b9d43767c2233028f68fe038bd892b478305ea8 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 24 Aug 2020 09:24:44 -0400 Subject: LibCore: Make DateTime::create() and set_time() handle out-of-range values Set member variables after calling mktime(), which canonicalizes out-of-range values. With this, DateTime::create(2020, 13, ...) will return a DateTime on Jan 2021 (assuming the other parameters are in range). --- Libraries/LibCore/DateTime.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Libraries/LibCore/DateTime.cpp b/Libraries/LibCore/DateTime.cpp index fee56d5ee3..38fa3eafbd 100644 --- a/Libraries/LibCore/DateTime.cpp +++ b/Libraries/LibCore/DateTime.cpp @@ -96,13 +96,6 @@ bool DateTime::is_leap_year() const void DateTime::set_time(unsigned year, unsigned month, unsigned day, unsigned hour, unsigned minute, unsigned second) { - m_year = year; - m_month = month; - m_day = day; - m_hour = hour; - m_minute = minute; - m_second = second; - struct tm tm = {}; tm.tm_sec = (int)second; tm.tm_min = (int)minute; @@ -110,9 +103,17 @@ void DateTime::set_time(unsigned year, unsigned month, unsigned day, unsigned ho tm.tm_mday = (int)day; tm.tm_mon = (int)month - 1; tm.tm_year = (int)year - 1900; - tm.tm_wday = (int)weekday(); - tm.tm_yday = (int)day_of_year(); + // mktime() doesn't read tm.tm_wday and tm.tm_yday, no need to fill them in. + m_timestamp = mktime(&tm); + + // mktime() normalizes the components to the right ranges (Jan 32 -> Feb 1 etc), so read fields back out from tm. + m_year = tm.tm_year + 1900; + m_month = tm.tm_mon + 1; + m_day = tm.tm_mday; + m_hour = tm.tm_hour; + m_minute = tm.tm_min; + m_second = tm.tm_sec; } String DateTime::to_string(const String& format) const -- cgit v1.2.3