summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-08-24 09:24:44 -0400
committerAndreas Kling <kling@serenityos.org>2020-08-24 18:20:07 +0200
commit5b9d43767c2233028f68fe038bd892b478305ea8 (patch)
treeac55f3648ac0610ff2788b7a363386ccffa0850a
parent593b0b9fccbd275ba47b9be9be0f7e63ae58f2ab (diff)
downloadserenity-5b9d43767c2233028f68fe038bd892b478305ea8.zip
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).
-rw-r--r--Libraries/LibCore/DateTime.cpp19
1 files 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