mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
AK/Time+LibWeb/HTML: Fix ISO8601 week conversions
This reimplements conversions between unix date times and ISO8601 weeks. The new algorithms also do not use loops, so they should be faster.
This commit is contained in:
parent
ec807d40dd
commit
d25d62e74c
39
AK/Time.cpp
39
AK/Time.cpp
|
|
@ -282,23 +282,34 @@ MonotonicTime MonotonicTime::now_coarse()
|
|||
|
||||
UnixDateTime UnixDateTime::from_iso8601_week(u32 week_year, u32 week)
|
||||
{
|
||||
auto january_1_weekday = day_of_week(week_year, 1, 1);
|
||||
i32 offset_to_monday = (january_1_weekday <= 3) ? -january_1_weekday : 7 - january_1_weekday;
|
||||
i32 first_monday_of_year = 1 + offset_to_monday;
|
||||
i32 day_of_year = (first_monday_of_year + (week - 1) * 7) + 1;
|
||||
auto day_of_week_january_4th = (day_of_week(week_year, 1, 4) + 6) % 7;
|
||||
int ordinal_day = (7 * week) - day_of_week_january_4th - 3;
|
||||
|
||||
// FIXME: There should be a more efficient way to do this that doesn't require a loop.
|
||||
u8 month = 1;
|
||||
while (true) {
|
||||
auto days = days_in_month(week_year, month);
|
||||
if (day_of_year <= days)
|
||||
break;
|
||||
if (ordinal_day < 1)
|
||||
return UnixDateTime::from_ordinal_date(week_year - 1, ordinal_day + days_in_year(week_year - 1));
|
||||
if (auto days_in_week_year = days_in_year(week_year); static_cast<unsigned>(ordinal_day) > days_in_week_year)
|
||||
return UnixDateTime::from_ordinal_date(week_year + 1, ordinal_day - days_in_week_year);
|
||||
return UnixDateTime::from_ordinal_date(week_year, ordinal_day);
|
||||
}
|
||||
|
||||
day_of_year -= days;
|
||||
++month;
|
||||
}
|
||||
UnixDateTime UnixDateTime::from_ordinal_date(u32 year, u32 day)
|
||||
{
|
||||
static constexpr Array<u32, 12> month_starts_normal = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
|
||||
static constexpr Array<u32, 12> month_starts_leap = { 1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336 };
|
||||
|
||||
return UnixDateTime::from_unix_time_parts(week_year, month, static_cast<u8>(day_of_year), 0, 0, 0, 0);
|
||||
auto const& month_starts = is_leap_year(year) ? month_starts_leap : month_starts_normal;
|
||||
|
||||
// Estimate month using integer division (approx 30.6 days per month)
|
||||
auto estimated_month = (day * 12 + 6) / 367; // Gives 0-based month index
|
||||
|
||||
// Correct month if estimate overshot
|
||||
if (day < month_starts[estimated_month])
|
||||
--estimated_month;
|
||||
|
||||
auto month = estimated_month + 1; // convert to 1-based month
|
||||
auto day_of_month = day - month_starts[estimated_month] + 1;
|
||||
|
||||
return UnixDateTime::from_unix_time_parts(year, month, day_of_month, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
UnixDateTime UnixDateTime::now()
|
||||
|
|
|
|||
11
AK/Time.h
11
AK/Time.h
|
|
@ -74,14 +74,14 @@ constexpr int day_of_year(int year, unsigned month, int day)
|
|||
// Month starts at 1. Month must be >= 1 and <= 12.
|
||||
int days_in_month(int year, unsigned month);
|
||||
|
||||
constexpr int days_in_year(int year)
|
||||
constexpr unsigned int days_in_year(int year)
|
||||
{
|
||||
return 365 + (is_leap_year(year) ? 1 : 0);
|
||||
}
|
||||
|
||||
constexpr int weeks_in_year(int year)
|
||||
constexpr unsigned int iso8061_weeks_in_year(int year)
|
||||
{
|
||||
return is_leap_year(year) ? 53 : 52;
|
||||
return day_of_week(year, 12, 31) == 4 || day_of_week(year - 1, 12, 31) == 3 ? 53 : 52;
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
|
|
@ -391,6 +391,9 @@ public:
|
|||
// Creates UNIX time from an ISO 8601 Week, such as 2025-W06, with year 2025 and week 6.
|
||||
[[nodiscard]] static UnixDateTime from_iso8601_week(u32 year, u32 week);
|
||||
|
||||
// Creates UNIX time from an ordinal date, such as 2025-100, with year 2025 and day 100.
|
||||
[[nodiscard]] static UnixDateTime from_ordinal_date(u32 year, u32 day);
|
||||
|
||||
// Creates UNIX time from a unix timestamp.
|
||||
// Note that the returned time is probably not equivalent to the same timestamp in UTC time, since UNIX time does not observe leap seconds.
|
||||
[[nodiscard]] constexpr static UnixDateTime from_unix_time_parts(i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond)
|
||||
|
|
@ -639,6 +642,7 @@ using AK::days_in_month;
|
|||
using AK::days_in_year;
|
||||
using AK::days_since_epoch;
|
||||
using AK::is_leap_year;
|
||||
using AK::iso8061_weeks_in_year;
|
||||
using AK::MonotonicTime;
|
||||
using AK::seconds_since_epoch_to_year;
|
||||
using AK::timespec_add;
|
||||
|
|
@ -649,6 +653,5 @@ using AK::timeval_add;
|
|||
using AK::timeval_sub;
|
||||
using AK::timeval_to_timespec;
|
||||
using AK::UnixDateTime;
|
||||
using AK::weeks_in_year;
|
||||
using AK::years_to_days_since_epoch;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2375,33 +2375,27 @@ static Utf16String convert_number_to_month_string(double input)
|
|||
return Utf16String::formatted("{:04d}-{:02d}", static_cast<int>(year), static_cast<int>(months) + 1);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#week-state-(type=week):concept-input-value-string-number
|
||||
// https://html.spec.whatwg.org/multipage/input.html#concept-input-value-number-string
|
||||
static Utf16String convert_number_to_week_string(double input)
|
||||
{
|
||||
// The algorithm to convert a number to a string, given a number input, is as follows: Return a valid week string that
|
||||
// that represents the week that, in UTC, is current input milliseconds after midnight UTC on the morning of 1970-01-01
|
||||
// (the time represented by the value "1970-01-01T00:00:00.0Z").
|
||||
// The algorithm to convert a number to a string, given a number input, is as follows: Return a valid week string
|
||||
// that represents the week that, in UTC, is current input milliseconds after midnight UTC on the morning of
|
||||
// 1970-01-01 (the time represented by the value "1970-01-01T00:00:00.0Z").
|
||||
|
||||
int days_since_epoch = static_cast<int>(input / AK::ms_per_day);
|
||||
int year = 1970;
|
||||
auto year = JS::year_from_time(input);
|
||||
auto month = JS::month_from_time(input) + 1; // Adjust for zero-based month
|
||||
auto day = JS::date_from_time(input);
|
||||
|
||||
while (true) {
|
||||
auto days = days_in_year(year);
|
||||
if (days_since_epoch < days)
|
||||
break;
|
||||
days_since_epoch -= days;
|
||||
constexpr Array normalYearDays = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
||||
constexpr Array leapYearDays = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
|
||||
|
||||
auto ordinal_day = (is_leap_year(year) ? leapYearDays[month - 1] : normalYearDays[month - 1]) + day;
|
||||
|
||||
unsigned week = (10 + ordinal_day - 1) / 7; // -1 because the day of the week is always monday
|
||||
if (week > iso8061_weeks_in_year(year)) {
|
||||
++year;
|
||||
week = 1;
|
||||
}
|
||||
|
||||
auto january_1_weekday = day_of_week(year, 1, 1);
|
||||
int offset_to_week_start = (january_1_weekday <= 3) ? january_1_weekday : january_1_weekday - 7;
|
||||
int week = (days_since_epoch + offset_to_week_start) / 7 + 1;
|
||||
|
||||
if (week < 0) {
|
||||
--year;
|
||||
week = weeks_in_year(year) + week;
|
||||
}
|
||||
|
||||
return Utf16String::formatted("{:04d}-W{:02d}", year, week);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -554,6 +554,77 @@ TEST_CASE(user_defined_literals)
|
|||
static_assert(1_sec != 2_sec, "NE UDL");
|
||||
}
|
||||
|
||||
TEST_CASE(from_iso8601_week)
|
||||
{
|
||||
// 1970-W01
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(1970, 1).offset_to_epoch(), -259'200, 0);
|
||||
|
||||
// First and last weeks of yearEXPECT_DURATION(UnixDateTime::from_iso8601_week(2000, 1).offset_to_epoch(), 946857600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2000, 2).offset_to_epoch(), 947462400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2000, 51).offset_to_epoch(), 977097600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2000, 52).offset_to_epoch(), 977702400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2001, 1).offset_to_epoch(), 978307200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2001, 2).offset_to_epoch(), 978912000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2001, 51).offset_to_epoch(), 1008547200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2001, 52).offset_to_epoch(), 1009152000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2002, 1).offset_to_epoch(), 1009756800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2002, 2).offset_to_epoch(), 1010361600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2002, 51).offset_to_epoch(), 1039996800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2002, 52).offset_to_epoch(), 1040601600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2003, 1).offset_to_epoch(), 1041206400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2003, 2).offset_to_epoch(), 1041811200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2003, 51).offset_to_epoch(), 1071446400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2003, 52).offset_to_epoch(), 1072051200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2004, 1).offset_to_epoch(), 1072656000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2004, 2).offset_to_epoch(), 1073260800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2004, 51).offset_to_epoch(), 1102896000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2004, 52).offset_to_epoch(), 1103500800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2004, 53).offset_to_epoch(), 1104105600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2005, 1).offset_to_epoch(), 1104710400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2005, 2).offset_to_epoch(), 1105315200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2005, 51).offset_to_epoch(), 1134950400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2005, 52).offset_to_epoch(), 1135555200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2006, 1).offset_to_epoch(), 1136160000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2006, 2).offset_to_epoch(), 1136764800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2006, 51).offset_to_epoch(), 1166400000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2006, 52).offset_to_epoch(), 1167004800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2007, 1).offset_to_epoch(), 1167609600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2007, 2).offset_to_epoch(), 1168214400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2007, 51).offset_to_epoch(), 1197849600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2007, 52).offset_to_epoch(), 1198454400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2008, 1).offset_to_epoch(), 1199059200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2008, 2).offset_to_epoch(), 1199664000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2008, 51).offset_to_epoch(), 1229299200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2008, 52).offset_to_epoch(), 1229904000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2009, 1).offset_to_epoch(), 1230508800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2009, 2).offset_to_epoch(), 1231113600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2009, 51).offset_to_epoch(), 1260748800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2009, 52).offset_to_epoch(), 1261353600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2009, 53).offset_to_epoch(), 1261958400, 0);
|
||||
|
||||
// Some random weeks
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2064, 25).offset_to_epoch(), 2980800000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(1976, 20).offset_to_epoch(), 200534400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2036, 6).offset_to_epoch(), 2085696000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2022, 9).offset_to_epoch(), 1646006400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2049, 19).offset_to_epoch(), 2504217600, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2069, 9).offset_to_epoch(), 3128976000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2015, 46).offset_to_epoch(), 1447027200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2056, 42).offset_to_epoch(), 2738880000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2018, 23).offset_to_epoch(), 1528070400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2047, 2).offset_to_epoch(), 2430432000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2033, 41).offset_to_epoch(), 2012515200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2021, 52).offset_to_epoch(), 1640563200, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(1987, 8).offset_to_epoch(), 540432000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(1982, 13).offset_to_epoch(), 386208000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(1979, 36).offset_to_epoch(), 305164800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2057, 43).offset_to_epoch(), 2770934400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(1988, 35).offset_to_epoch(), 588816000, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2060, 50).offset_to_epoch(), 2869516800, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2013, 14).offset_to_epoch(), 1364774400, 0);
|
||||
EXPECT_DURATION(UnixDateTime::from_iso8601_week(2005, 52).offset_to_epoch(), 1135555200, 0);
|
||||
}
|
||||
|
||||
TEST_CASE(from_unix_time_parts_common_values)
|
||||
{
|
||||
// Non-negative "common" values.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ email threw exception: InvalidStateError: valueAsNumber: Invalid input type used
|
|||
password threw exception: InvalidStateError: valueAsNumber: Invalid input type used
|
||||
date did not throw: 0
|
||||
month did not throw: 100
|
||||
week did not throw: 345600000
|
||||
week did not throw: -259200000
|
||||
time did not throw: 100
|
||||
datetime-local did not throw: 100
|
||||
color threw exception: InvalidStateError: valueAsNumber: Invalid input type used
|
||||
|
|
|
|||
62
Tests/LibWeb/Text/expected/input-week.txt
Normal file
62
Tests/LibWeb/Text/expected/input-week.txt
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
1970-W01 -> -259200000
|
||||
2000-W02 -> 947462400000
|
||||
2000-W51 -> 977097600000
|
||||
2000-W52 -> 977702400000
|
||||
2001-W01 -> 978307200000
|
||||
2001-W02 -> 978912000000
|
||||
2001-W51 -> 1008547200000
|
||||
2001-W52 -> 1009152000000
|
||||
2002-W01 -> 1009756800000
|
||||
2002-W02 -> 1010361600000
|
||||
2002-W51 -> 1039996800000
|
||||
2002-W52 -> 1040601600000
|
||||
2003-W01 -> 1041206400000
|
||||
2003-W02 -> 1041811200000
|
||||
2003-W51 -> 1071446400000
|
||||
2003-W52 -> 1072051200000
|
||||
2004-W01 -> 1072656000000
|
||||
2004-W02 -> 1073260800000
|
||||
2004-W51 -> 1102896000000
|
||||
2004-W52 -> 1103500800000
|
||||
2004-W53 -> 1104105600000
|
||||
2005-W01 -> 1104710400000
|
||||
2005-W02 -> 1105315200000
|
||||
2005-W51 -> 1134950400000
|
||||
2005-W52 -> 1135555200000
|
||||
2006-W01 -> 1136160000000
|
||||
2006-W02 -> 1136764800000
|
||||
2006-W51 -> 1166400000000
|
||||
2006-W52 -> 1167004800000
|
||||
2007-W01 -> 1167609600000
|
||||
2007-W02 -> 1168214400000
|
||||
2007-W51 -> 1197849600000
|
||||
2007-W52 -> 1198454400000
|
||||
2008-W01 -> 1199059200000
|
||||
2008-W02 -> 1199664000000
|
||||
2008-W51 -> 1229299200000
|
||||
2008-W52 -> 1229904000000
|
||||
2009-W01 -> 1230508800000
|
||||
2009-W02 -> 1231113600000
|
||||
2009-W51 -> 1260748800000
|
||||
2009-W52 -> 1261353600000
|
||||
2009-W53 -> 1261958400000
|
||||
2064-W25 -> 2980800000000
|
||||
1976-W20 -> 200534400000
|
||||
2036-W06 -> 2085696000000
|
||||
2022-W09 -> 1646006400000
|
||||
2049-W19 -> 2504217600000
|
||||
2069-W09 -> 3128976000000
|
||||
2015-W46 -> 1447027200000
|
||||
2056-W42 -> 2738880000000
|
||||
2018-W23 -> 1528070400000
|
||||
2047-W02 -> 2430432000000
|
||||
2033-W41 -> 2012515200000
|
||||
2021-W52 -> 1640563200000
|
||||
1987-W08 -> 540432000000
|
||||
1982-W13 -> 386208000000
|
||||
1979-W36 -> 305164800000
|
||||
2057-W43 -> 2770934400000
|
||||
1988-W35 -> 588816000000
|
||||
2060-W50 -> 2869516800000
|
||||
2013-W14 -> 1364774400000
|
||||
2005-W52 -> 1135555200000
|
||||
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
|||
|
||||
Found 28 tests
|
||||
|
||||
24 Pass
|
||||
4 Fail
|
||||
26 Pass
|
||||
2 Fail
|
||||
Pass [INPUT in DATE status] The step attribute is not set
|
||||
Pass [INPUT in DATE status] The value attibute is empty string
|
||||
Pass [INPUT in DATE status] The value must match the step
|
||||
|
|
@ -14,8 +14,8 @@ Pass [INPUT in MONTH status] The value must match the step
|
|||
Pass [INPUT in MONTH status] The value must mismatch the step
|
||||
Pass [INPUT in WEEK status] The step attribute is not set
|
||||
Pass [INPUT in WEEK status] The value attibute is empty string
|
||||
Fail [INPUT in WEEK status] The value must match the step
|
||||
Fail [INPUT in WEEK status] The value must mismatch the step
|
||||
Pass [INPUT in WEEK status] The value must match the step
|
||||
Pass [INPUT in WEEK status] The value must mismatch the step
|
||||
Pass [INPUT in TIME status] The step attribute is not set
|
||||
Pass [INPUT in TIME status] The value attibute is empty string
|
||||
Pass [INPUT in TIME status] The value must match the step
|
||||
|
|
|
|||
83
Tests/LibWeb/Text/input/input-week.html
Normal file
83
Tests/LibWeb/Text/input/input-week.html
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="./include.js"></script>
|
||||
<script>
|
||||
const test_cases = [
|
||||
"1970-W01",
|
||||
|
||||
"2000-W02",
|
||||
"2000-W51",
|
||||
"2000-W52",
|
||||
"2001-W01",
|
||||
"2001-W02",
|
||||
"2001-W51",
|
||||
"2001-W52",
|
||||
"2002-W01",
|
||||
"2002-W02",
|
||||
"2002-W51",
|
||||
"2002-W52",
|
||||
"2003-W01",
|
||||
"2003-W02",
|
||||
"2003-W51",
|
||||
"2003-W52",
|
||||
"2004-W01",
|
||||
"2004-W02",
|
||||
"2004-W51",
|
||||
"2004-W52",
|
||||
"2004-W53",
|
||||
"2005-W01",
|
||||
"2005-W02",
|
||||
"2005-W51",
|
||||
"2005-W52",
|
||||
"2006-W01",
|
||||
"2006-W02",
|
||||
"2006-W51",
|
||||
"2006-W52",
|
||||
"2007-W01",
|
||||
"2007-W02",
|
||||
"2007-W51",
|
||||
"2007-W52",
|
||||
"2008-W01",
|
||||
"2008-W02",
|
||||
"2008-W51",
|
||||
"2008-W52",
|
||||
"2009-W01",
|
||||
"2009-W02",
|
||||
"2009-W51",
|
||||
"2009-W52",
|
||||
"2009-W53",
|
||||
|
||||
"2064-W25",
|
||||
"1976-W20",
|
||||
"2036-W06",
|
||||
"2022-W09",
|
||||
"2049-W19",
|
||||
"2069-W09",
|
||||
"2015-W46",
|
||||
"2056-W42",
|
||||
"2018-W23",
|
||||
"2047-W02",
|
||||
"2033-W41",
|
||||
"2021-W52",
|
||||
"1987-W08",
|
||||
"1982-W13",
|
||||
"1979-W36",
|
||||
"2057-W43",
|
||||
"1988-W35",
|
||||
"2060-W50",
|
||||
"2013-W14",
|
||||
"2005-W52",
|
||||
];
|
||||
|
||||
test(() => {
|
||||
for (const test_case of test_cases) {
|
||||
const input = document.createElement("input");
|
||||
input.type = "week";
|
||||
input.value = test_case;
|
||||
if (input.value === test_case) {
|
||||
println(`${test_case} -> ${input.valueAsNumber}`);
|
||||
} else {
|
||||
println("FAIL");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user