mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibTimeZone+Userland: Change timezone functions to use UnixDateTime
This incurs a whole host of changes in, among others, JavaScript Intl and Date.
This commit is contained in:
parent
939600d2d4
commit
82c681e44b
Notes:
sideshowbarker
2024-07-17 01:10:58 +09:00
Author: https://github.com/kleinesfilmroellchen Commit: https://github.com/SerenityOS/serenity/commit/82c681e44b Pull-request: https://github.com/SerenityOS/serenity/pull/17842 Reviewed-by: https://github.com/me-minus Reviewed-by: https://github.com/timschumi
13 changed files with 43 additions and 43 deletions
|
@ -110,7 +110,7 @@ struct AK::Formatter<DaylightSavingsOffset> : Formatter<FormatString> {
|
|||
ErrorOr<void> format(FormatBuilder& builder, DaylightSavingsOffset const& dst_offset)
|
||||
{
|
||||
auto format_time = [&](auto year) {
|
||||
return DeprecatedString::formatted("AK::Duration::from_timestamp({}, 1, 1, 0, 0, 0, 0)", year);
|
||||
return DeprecatedString::formatted("AK::UnixDateTime::from_unix_time_parts({}, 1, 1, 0, 0, 0, 0)", year);
|
||||
};
|
||||
|
||||
static DeprecatedString max_year_as_time("max_year_as_time"sv);
|
||||
|
@ -494,13 +494,13 @@ static ErrorOr<void> generate_time_zone_data_implementation(Core::InputBufferedF
|
|||
|
||||
namespace TimeZone {
|
||||
|
||||
static constexpr auto max_year_as_time = AK::Duration::from_timestamp(NumericLimits<u16>::max(), 1, 1, 0, 0, 0, 0);
|
||||
static constexpr auto max_year_as_time = AK::UnixDateTime::from_unix_time_parts(NumericLimits<u16>::max(), 1, 1, 0, 0, 0, 0);
|
||||
|
||||
struct DateTime {
|
||||
AK::Duration time_since_epoch() const
|
||||
AK::UnixDateTime time_since_epoch() const
|
||||
{
|
||||
// FIXME: This implementation does not take last_weekday, after_weekday, or before_weekday into account.
|
||||
return AK::Duration::from_timestamp(year, month, day, hour, minute, second, 0);
|
||||
return AK::UnixDateTime::from_unix_time_parts(year, month, day, hour, minute, second, 0);
|
||||
}
|
||||
|
||||
u16 year { 0 };
|
||||
|
@ -530,17 +530,17 @@ struct TimeZoneOffset {
|
|||
};
|
||||
|
||||
struct DaylightSavingsOffset {
|
||||
AK::Duration time_in_effect(AK::Duration time) const
|
||||
AK::UnixDateTime time_in_effect(AK::UnixDateTime time) const
|
||||
{
|
||||
auto in_effect = this->in_effect;
|
||||
in_effect.year = seconds_since_epoch_to_year(time.to_seconds());
|
||||
in_effect.year = seconds_since_epoch_to_year(time.seconds_since_epoch());
|
||||
|
||||
return in_effect.time_since_epoch();
|
||||
}
|
||||
|
||||
i64 offset { 0 };
|
||||
AK::Duration year_from {};
|
||||
AK::Duration year_to {};
|
||||
AK::UnixDateTime year_from {};
|
||||
AK::UnixDateTime year_to {};
|
||||
DateTime in_effect {};
|
||||
|
||||
@string_index_type@ format { 0 };
|
||||
|
@ -635,7 +635,7 @@ static constexpr Array<Location, @size@> s_time_zone_locations { {
|
|||
TRY(append_string_conversions("Region"sv, "region"sv, time_zone_data.time_zone_region_names));
|
||||
|
||||
generator.append(R"~~~(
|
||||
static Array<DaylightSavingsOffset const*, 2> find_dst_offsets(TimeZoneOffset const& time_zone_offset, AK::Duration time)
|
||||
static Array<DaylightSavingsOffset const*, 2> find_dst_offsets(TimeZoneOffset const& time_zone_offset, AK::UnixDateTime time)
|
||||
{
|
||||
auto const& dst_rules = s_dst_offsets[time_zone_offset.dst_rule];
|
||||
|
||||
|
@ -677,7 +677,7 @@ static Array<DaylightSavingsOffset const*, 2> find_dst_offsets(TimeZoneOffset co
|
|||
return { standard_offset, daylight_offset ? daylight_offset : standard_offset };
|
||||
}
|
||||
|
||||
static Offset get_active_dst_offset(TimeZoneOffset const& time_zone_offset, AK::Duration time)
|
||||
static Offset get_active_dst_offset(TimeZoneOffset const& time_zone_offset, AK::UnixDateTime time)
|
||||
{
|
||||
auto offsets = find_dst_offsets(time_zone_offset, time);
|
||||
if (offsets[0] == offsets[1])
|
||||
|
@ -697,7 +697,7 @@ static Offset get_active_dst_offset(TimeZoneOffset const& time_zone_offset, AK::
|
|||
return { offsets[1]->offset, InDST::Yes };
|
||||
}
|
||||
|
||||
static TimeZoneOffset const& find_time_zone_offset(TimeZone time_zone, AK::Duration time)
|
||||
static TimeZoneOffset const& find_time_zone_offset(TimeZone time_zone, AK::UnixDateTime time)
|
||||
{
|
||||
auto const& time_zone_offsets = s_time_zone_offsets[to_underlying(time_zone)];
|
||||
|
||||
|
@ -713,7 +713,7 @@ static TimeZoneOffset const& find_time_zone_offset(TimeZone time_zone, AK::Durat
|
|||
return time_zone_offsets[index];
|
||||
}
|
||||
|
||||
Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::Duration time)
|
||||
Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::UnixDateTime time)
|
||||
{
|
||||
auto const& time_zone_offset = find_time_zone_offset(time_zone, time);
|
||||
|
||||
|
@ -729,7 +729,7 @@ Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::Duration time)
|
|||
return dst_offset;
|
||||
}
|
||||
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(TimeZone time_zone, AK::Duration time)
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(TimeZone time_zone, AK::UnixDateTime time)
|
||||
{
|
||||
auto const& time_zone_offset = find_time_zone_offset(time_zone, time);
|
||||
Array<NamedOffset, 2> named_offsets;
|
||||
|
|
|
@ -72,7 +72,7 @@ TEST_CASE(time_zone_name)
|
|||
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortGeneric, "Africa/Accra"sv, "غرينتش"sv },
|
||||
};
|
||||
|
||||
constexpr auto jan_1_2022 = AK::Duration::from_seconds(1640995200); // Saturday, January 1, 2022 12:00:00 AM
|
||||
constexpr auto jan_1_2022 = AK::UnixDateTime::from_seconds_since_epoch(1640995200); // Saturday, January 1, 2022 12:00:00 AM
|
||||
|
||||
for (auto const& test : test_data) {
|
||||
auto time_zone = MUST(Locale::format_time_zone(test.locale, test.time_zone, test.style, jan_1_2022));
|
||||
|
@ -122,7 +122,7 @@ TEST_CASE(time_zone_name_dst)
|
|||
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "Africa/Accra"sv, "غرينتش"sv },
|
||||
};
|
||||
|
||||
constexpr auto sep_19_2022 = AK::Duration::from_seconds(1663553728); // Monday, September 19, 2022 2:15:28 AM
|
||||
constexpr auto sep_19_2022 = AK::UnixDateTime::from_seconds_since_epoch(1663553728); // Monday, September 19, 2022 2:15:28 AM
|
||||
|
||||
for (auto const& test : test_data) {
|
||||
auto time_zone = MUST(Locale::format_time_zone(test.locale, test.time_zone, test.style, sep_19_2022));
|
||||
|
@ -132,13 +132,13 @@ TEST_CASE(time_zone_name_dst)
|
|||
|
||||
TEST_CASE(format_time_zone_offset)
|
||||
{
|
||||
constexpr auto jan_1_1833 = AK::Duration::from_seconds(-4323283200); // Tuesday, January 1, 1833 12:00:00 AM
|
||||
constexpr auto jan_1_2022 = AK::Duration::from_seconds(1640995200); // Saturday, January 1, 2022 12:00:00 AM
|
||||
constexpr auto jan_1_1833 = AK::UnixDateTime::from_seconds_since_epoch(-4323283200); // Tuesday, January 1, 1833 12:00:00 AM
|
||||
constexpr auto jan_1_2022 = AK::UnixDateTime::from_seconds_since_epoch(1640995200); // Saturday, January 1, 2022 12:00:00 AM
|
||||
|
||||
struct TestData {
|
||||
StringView locale;
|
||||
Locale::CalendarPatternStyle style;
|
||||
AK::Duration time;
|
||||
AK::UnixDateTime time;
|
||||
StringView time_zone;
|
||||
StringView expected_result;
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ using enum TimeZone::InDST;
|
|||
|
||||
static void test_offset(StringView time_zone, i64 time, i64 expected_offset, TimeZone::InDST expected_in_dst)
|
||||
{
|
||||
auto actual_offset = TimeZone::get_time_zone_offset(time_zone, AK::Duration::from_seconds(time));
|
||||
auto actual_offset = TimeZone::get_time_zone_offset(time_zone, AK::UnixDateTime::from_seconds_since_epoch(time));
|
||||
VERIFY(actual_offset.has_value());
|
||||
EXPECT_EQ(actual_offset->seconds, expected_offset);
|
||||
EXPECT_EQ(actual_offset->in_dst, expected_in_dst);
|
||||
|
@ -183,7 +183,7 @@ TEST_CASE(get_time_zone_offset_with_dst)
|
|||
TEST_CASE(get_named_time_zone_offsets)
|
||||
{
|
||||
auto test_named_offsets = [](auto time_zone, i64 time, i64 expected_standard_offset, i64 expected_daylight_offset, auto expected_standard_name, auto expected_daylight_name) {
|
||||
auto actual_offsets = TimeZone::get_named_time_zone_offsets(time_zone, AK::Duration::from_seconds(time));
|
||||
auto actual_offsets = TimeZone::get_named_time_zone_offsets(time_zone, AK::UnixDateTime::from_seconds_since_epoch(time));
|
||||
VERIFY(actual_offsets.has_value());
|
||||
|
||||
EXPECT_EQ(actual_offsets->at(0).seconds, expected_standard_offset);
|
||||
|
|
|
@ -133,7 +133,7 @@ void TimeZoneSettingsWidget::set_time_zone_location()
|
|||
m_time_zone_location = compute_time_zone_location();
|
||||
|
||||
auto locale = Locale::default_locale();
|
||||
auto now = AK::Duration::now_realtime();
|
||||
auto now = AK::UnixDateTime::now();
|
||||
|
||||
auto name = Locale::format_time_zone(locale, m_time_zone, Locale::CalendarPatternStyle::Long, now).release_value_but_fixme_should_propagate_errors();
|
||||
auto offset = Locale::format_time_zone(locale, m_time_zone, Locale::CalendarPatternStyle::LongOffset, now).release_value_but_fixme_should_propagate_errors();
|
||||
|
|
|
@ -117,7 +117,7 @@ static struct tm* time_to_tm(struct tm* tm, time_t t, StringView time_zone)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto offset = TimeZone::get_time_zone_offset(time_zone, AK::Duration::from_seconds(t)); offset.has_value()) {
|
||||
if (auto offset = TimeZone::get_time_zone_offset(time_zone, AK::UnixDateTime::from_seconds_since_epoch(t)); offset.has_value()) {
|
||||
tm->tm_isdst = offset->in_dst == TimeZone::InDST::Yes;
|
||||
t += offset->seconds;
|
||||
}
|
||||
|
@ -171,12 +171,12 @@ static time_t tm_to_time(struct tm* tm, StringView time_zone)
|
|||
auto timestamp = ((days_since_epoch * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
|
||||
|
||||
if (tm->tm_isdst < 0) {
|
||||
if (auto offset = TimeZone::get_time_zone_offset(time_zone, AK::Duration::from_seconds(timestamp)); offset.has_value())
|
||||
if (auto offset = TimeZone::get_time_zone_offset(time_zone, AK::UnixDateTime::from_seconds_since_epoch(timestamp)); offset.has_value())
|
||||
timestamp -= offset->seconds;
|
||||
} else {
|
||||
auto index = tm->tm_isdst == 0 ? 0 : 1;
|
||||
|
||||
if (auto offsets = TimeZone::get_named_time_zone_offsets(time_zone, AK::Duration::from_seconds(timestamp)); offsets.has_value())
|
||||
if (auto offsets = TimeZone::get_named_time_zone_offsets(time_zone, AK::UnixDateTime::from_seconds_since_epoch(timestamp)); offsets.has_value())
|
||||
timestamp -= offsets->at(index).seconds;
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ void tzset()
|
|||
tzname[1] = const_cast<char*>(__utc);
|
||||
};
|
||||
|
||||
if (auto offsets = TimeZone::get_named_time_zone_offsets(__tzname, AK::Duration::now_realtime()); offsets.has_value()) {
|
||||
if (auto offsets = TimeZone::get_named_time_zone_offsets(__tzname, AK::UnixDateTime::now()); offsets.has_value()) {
|
||||
if (!offsets->at(0).name.copy_characters_to_buffer(__tzname_standard, TZNAME_MAX))
|
||||
return set_default_values();
|
||||
if (!offsets->at(1).name.copy_characters_to_buffer(__tzname_daylight, TZNAME_MAX))
|
||||
|
|
|
@ -314,7 +314,7 @@ static i64 clip_bigint_to_sane_time(Crypto::SignedBigInteger const& value)
|
|||
Vector<Crypto::SignedBigInteger> get_named_time_zone_epoch_nanoseconds(StringView time_zone_identifier, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond)
|
||||
{
|
||||
auto local_nanoseconds = get_utc_epoch_nanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond);
|
||||
auto local_time = Duration::from_nanoseconds(clip_bigint_to_sane_time(local_nanoseconds));
|
||||
auto local_time = UnixDateTime::from_nanoseconds_since_epoch(clip_bigint_to_sane_time(local_nanoseconds));
|
||||
|
||||
// FIXME: LibTimeZone does not behave exactly as the spec expects. It does not consider repeated or skipped time points.
|
||||
auto offset = TimeZone::get_time_zone_offset(time_zone_identifier, local_time);
|
||||
|
@ -332,10 +332,10 @@ i64 get_named_time_zone_offset_nanoseconds(StringView time_zone_identifier, Cryp
|
|||
auto time_zone = TimeZone::time_zone_from_string(time_zone_identifier);
|
||||
VERIFY(time_zone.has_value());
|
||||
|
||||
// Since Duration::from_seconds() and Duration::from_nanoseconds() both take an i64, converting to
|
||||
// Since UnixDateTime::from_seconds_since_epoch() and UnixDateTime::from_nanoseconds_since_epoch() both take an i64, converting to
|
||||
// seconds first gives us a greater range. The TZDB doesn't have sub-second offsets.
|
||||
auto seconds = epoch_nanoseconds.divided_by(s_one_billion_bigint).quotient;
|
||||
auto time = Duration::from_seconds(clip_bigint_to_sane_time(seconds));
|
||||
auto time = UnixDateTime::from_seconds_since_epoch(clip_bigint_to_sane_time(seconds));
|
||||
|
||||
auto offset = TimeZone::get_time_zone_offset(*time_zone, time);
|
||||
VERIFY(offset.has_value());
|
||||
|
|
|
@ -1164,7 +1164,7 @@ DeprecatedString time_zone_string(double time)
|
|||
auto tz_name = TimeZone::current_time_zone();
|
||||
|
||||
// Most implementations seem to prefer the long-form display name of the time zone. Not super important, but we may as well match that behavior.
|
||||
if (auto maybe_offset = TimeZone::get_time_zone_offset(tz_name, AK::Duration::from_milliseconds(time)); maybe_offset.has_value()) {
|
||||
if (auto maybe_offset = TimeZone::get_time_zone_offset(tz_name, AK::UnixDateTime::from_milliseconds_since_epoch(time)); maybe_offset.has_value()) {
|
||||
if (auto long_name = Locale::get_time_zone_name(Locale::default_locale(), tz_name, Locale::CalendarPatternStyle::Long, maybe_offset->in_dst); long_name.has_value())
|
||||
tz_name = long_name.release_value();
|
||||
}
|
||||
|
|
|
@ -162,9 +162,9 @@ enum class OptionDefaults {
|
|||
// Table 8: Record returned by ToLocalTime, https://tc39.es/ecma402/#table-datetimeformat-tolocaltime-record
|
||||
// Note: [[InDST]] is not included here - it is handled by LibUnicode / LibTimeZone.
|
||||
struct LocalTime {
|
||||
AK::Duration time_since_epoch() const
|
||||
AK::UnixDateTime time_since_epoch() const
|
||||
{
|
||||
return AK::Duration::from_timestamp(year, month + 1, day + 1, hour, minute, second, millisecond);
|
||||
return AK::UnixDateTime::from_unix_time_parts(year, month + 1, day + 1, hour, minute, second, millisecond);
|
||||
}
|
||||
|
||||
int weekday { 0 }; // [[Weekday]]
|
||||
|
|
|
@ -301,7 +301,7 @@ static ErrorOr<Optional<String>> format_time_zone_offset(StringView locale, Cale
|
|||
}
|
||||
|
||||
// https://unicode.org/reports/tr35/tr35-dates.html#Time_Zone_Format_Terminology
|
||||
ErrorOr<String> format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::Duration time)
|
||||
ErrorOr<String> format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::UnixDateTime time)
|
||||
{
|
||||
auto offset = TimeZone::get_time_zone_offset(time_zone, time);
|
||||
if (!offset.has_value())
|
||||
|
|
|
@ -226,7 +226,7 @@ ErrorOr<Optional<StringView>> get_calendar_weekday_symbol(StringView locale, Str
|
|||
ErrorOr<Optional<StringView>> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, DayPeriod value);
|
||||
ErrorOr<Optional<StringView>> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour);
|
||||
|
||||
ErrorOr<String> format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::Duration time);
|
||||
ErrorOr<String> format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::UnixDateTime time);
|
||||
Optional<StringView> get_time_zone_name(StringView locale, StringView time_zone, CalendarPatternStyle style, TimeZone::InDST in_dst);
|
||||
Optional<TimeZoneFormat> get_time_zone_format(StringView locale);
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ Optional<StringView> canonicalize_time_zone(StringView time_zone)
|
|||
Optional<DaylightSavingsRule> __attribute__((weak)) daylight_savings_rule_from_string(StringView) { return {}; }
|
||||
StringView __attribute__((weak)) daylight_savings_rule_to_string(DaylightSavingsRule) { return {}; }
|
||||
|
||||
Optional<Offset> __attribute__((weak)) get_time_zone_offset([[maybe_unused]] TimeZone time_zone, AK::Duration)
|
||||
Optional<Offset> __attribute__((weak)) get_time_zone_offset([[maybe_unused]] TimeZone time_zone, AK::UnixDateTime)
|
||||
{
|
||||
#if !ENABLE_TIME_ZONE_DATA
|
||||
VERIFY(time_zone == TimeZone::UTC);
|
||||
|
@ -196,14 +196,14 @@ Optional<Offset> __attribute__((weak)) get_time_zone_offset([[maybe_unused]] Tim
|
|||
#endif
|
||||
}
|
||||
|
||||
Optional<Offset> get_time_zone_offset(StringView time_zone, AK::Duration time)
|
||||
Optional<Offset> get_time_zone_offset(StringView time_zone, AK::UnixDateTime time)
|
||||
{
|
||||
if (auto maybe_time_zone = time_zone_from_string(time_zone); maybe_time_zone.has_value())
|
||||
return get_time_zone_offset(*maybe_time_zone, time);
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<Array<NamedOffset, 2>> __attribute__((weak)) get_named_time_zone_offsets([[maybe_unused]] TimeZone time_zone, AK::Duration)
|
||||
Optional<Array<NamedOffset, 2>> __attribute__((weak)) get_named_time_zone_offsets([[maybe_unused]] TimeZone time_zone, AK::UnixDateTime)
|
||||
{
|
||||
#if !ENABLE_TIME_ZONE_DATA
|
||||
VERIFY(time_zone == TimeZone::UTC);
|
||||
|
@ -217,7 +217,7 @@ Optional<Array<NamedOffset, 2>> __attribute__((weak)) get_named_time_zone_offset
|
|||
#endif
|
||||
}
|
||||
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(StringView time_zone, AK::Duration time)
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(StringView time_zone, AK::UnixDateTime time)
|
||||
{
|
||||
if (auto maybe_time_zone = time_zone_from_string(time_zone); maybe_time_zone.has_value())
|
||||
return get_named_time_zone_offsets(*maybe_time_zone, time);
|
||||
|
|
|
@ -61,11 +61,11 @@ Optional<StringView> canonicalize_time_zone(StringView time_zone);
|
|||
Optional<DaylightSavingsRule> daylight_savings_rule_from_string(StringView daylight_savings_rule);
|
||||
StringView daylight_savings_rule_to_string(DaylightSavingsRule daylight_savings_rule);
|
||||
|
||||
Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::Duration time);
|
||||
Optional<Offset> get_time_zone_offset(StringView time_zone, AK::Duration time);
|
||||
Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::UnixDateTime time);
|
||||
Optional<Offset> get_time_zone_offset(StringView time_zone, AK::UnixDateTime time);
|
||||
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(TimeZone time_zone, AK::Duration time);
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(StringView time_zone, AK::Duration time);
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(TimeZone time_zone, AK::UnixDateTime time);
|
||||
Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(StringView time_zone, AK::UnixDateTime time);
|
||||
|
||||
Optional<Location> get_time_zone_location(TimeZone time_zone);
|
||||
Optional<Location> get_time_zone_location(StringView time_zone);
|
||||
|
|
|
@ -88,7 +88,7 @@ static void parse_time(StringView input_time, timespec& atime, timespec& mtime)
|
|||
month = parameters.take_last();
|
||||
|
||||
if (validate_timestamp(year, month, day, hour, minute, second))
|
||||
atime = mtime = AK::Duration::from_timestamp(year, month, day, hour, minute, second, 0).to_timespec();
|
||||
atime = mtime = AK::UnixDateTime::from_unix_time_parts(year, month, day, hour, minute, second, 0).to_timespec();
|
||||
else
|
||||
err("invalid time format '{}'", input_time);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ static void parse_datetime(StringView input_datetime, timespec& atime, timespec&
|
|||
}
|
||||
|
||||
if (validate_timestamp(year, month, day, hour, minute, second)) {
|
||||
auto timestamp = AK::Duration::from_timestamp(year, month, day, hour, minute, second, millisecond);
|
||||
auto timestamp = AK::UnixDateTime::from_unix_time_parts(year, month, day, hour, minute, second, millisecond);
|
||||
auto time = timestamp.to_timespec();
|
||||
if (time_zone.is_empty() && TimeZone::system_time_zone() != "UTC") {
|
||||
auto offset = TimeZone::get_time_zone_offset(TimeZone::system_time_zone(), timestamp);
|
||||
|
|
Loading…
Reference in a new issue