From fe16b1fb5ce32f775086594e94b5fbd668ab18b6 Mon Sep 17 00:00:00 2001 From: Cmdv Date: Tue, 22 Sep 2020 17:37:09 +0100 Subject: [PATCH 1/3] start of adding tests that cover the ecma262 Specs --- test/Test/Main.purs | 335 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) diff --git a/test/Test/Main.purs b/test/Test/Main.purs index efeef62..6e67187 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -22,6 +22,341 @@ import Partial.Unsafe (unsafePartial) import Test.Assert (assert) import Type.Proxy (Proxy(..)) +---------------------------------------------------------------------------------------------- +-- 20.4.1.2 Day Number and Time within Day +---------------------------------------------------------------------------------------------- +-- Day(t) = floor(t / msPerDay) +-- msPerDay = 86400000 +-- +-- The remainder is called the time within the day: +-- TimeWithinDay(t) = t modulo msPerDay + +---------------------------------------------------------------------------------------------- +-- 20.4.1.3 Year Number +---------------------------------------------------------------------------------------------- +-- DaysInYear(y) +-- = 365 if (y modulo 4) ≠ 0 +-- = 366 if (y modulo 4) = 0 and (y modulo 100) ≠ 0 +-- = 365 if (y modulo 100) = 0 and (y modulo 400) ≠ 0 +-- = 366 if (y modulo 400) = 0 +-- +-- All non-leap years have 365 days with the usual number of days per month and leap years have an extra day in February. +-- The day number of the first day of year y is given by: +-- DayFromYear(y) = 365 × (y - 1970) + floor((y - 1969) / 4) - floor((y - 1901) / 100) + floor((y - 1601) / 400) +-- +-- The time value of the start of a year is: +-- TimeFromYear(y) = msPerDay × DayFromYear(y) +-- YearFromTime(t) = the largest integer y (closest to positive infinity) such that TimeFromYear(y) ≤ t +-- +-- InLeapYear(t) +-- = 0 if DaysInYear(YearFromTime(t)) = 365 +-- = 1 if DaysInYear(YearFromTime(t)) = 366 +-- +-- MonthFromTime(t) +-- = 0 if 0 ≤ DayWithinYear(t) < 31 +-- = 1 if 31 ≤ DayWithinYear(t) < 59 + InLeapYear(t) +-- = 2 if 59 + InLeapYear(t) ≤ DayWithinYear(t) < 90 + InLeapYear(t) +-- = 3 if 90 + InLeapYear(t) ≤ DayWithinYear(t) < 120 + InLeapYear(t) +-- = 4 if 120 + InLeapYear(t) ≤ DayWithinYear(t) < 151 + InLeapYear(t) +-- = 5 if 151 + InLeapYear(t) ≤ DayWithinYear(t) < 181 + InLeapYear(t) +-- = 6 if 181 + InLeapYear(t) ≤ DayWithinYear(t) < 212 + InLeapYear(t) +-- = 7 if 212 + InLeapYear(t) ≤ DayWithinYear(t) < 243 + InLeapYear(t) +-- = 8 if 243 + InLeapYear(t) ≤ DayWithinYear(t) < 273 + InLeapYear(t) +-- = 9 if 273 + InLeapYear(t) ≤ DayWithinYear(t) < 304 + InLeapYear(t) +-- = 10 if 304 + InLeapYear(t) ≤ DayWithinYear(t) < 334 + InLeapYear(t) +-- = 11 if 334 + InLeapYear(t) ≤ DayWithinYear(t) < 365 + InLeapYear(t) +-- +-- DayWithinYear(t) = Day(t) - DayFromYear(YearFromTime(t)) +-- Note that MonthFromTime(0) = 0, corresponding to Thursday, 01 January, 1970. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.5 Date Number +---------------------------------------------------------------------------------------------- +-- DateFromTime(t) +-- = DayWithinYear(t) + 1 if MonthFromTime(t) = 0 +-- = DayWithinYear(t) - 30 if MonthFromTime(t) = 1 +-- = DayWithinYear(t) - 58 - InLeapYear(t) if MonthFromTime(t) = 2 +-- = DayWithinYear(t) - 89 - InLeapYear(t) if MonthFromTime(t) = 3 +-- = DayWithinYear(t) - 119 - InLeapYear(t) if MonthFromTime(t) = 4 +-- = DayWithinYear(t) - 150 - InLeapYear(t) if MonthFromTime(t) = 5 +-- = DayWithinYear(t) - 180 - InLeapYear(t) if MonthFromTime(t) = 6 +-- = DayWithinYear(t) - 211 - InLeapYear(t) if MonthFromTime(t) = 7 +-- = DayWithinYear(t) - 242 - InLeapYear(t) if MonthFromTime(t) = 8 +-- = DayWithinYear(t) - 272 - InLeapYear(t) if MonthFromTime(t) = 9 +-- = DayWithinYear(t) - 303 - InLeapYear(t) if MonthFromTime(t) = 10 +-- = DayWithinYear(t) - 333 - InLeapYear(t) if MonthFromTime(t) = 11 + +---------------------------------------------------------------------------------------------- +-- 20.4.1.6 Week Day +---------------------------------------------------------------------------------------------- +-- WeekDay(t) = (Day(t) + 4) modulo 7 +-- A weekday value of +-- 0 specifies Sunday; +-- 1 specifies Monday; +-- 2 specifies Tuesday; +-- 3 specifies Wednesday; +-- 4 specifies Thursday; +-- 5 specifies Friday; +-- 6 specifies Saturday. +-- Note that WeekDay(0) = 4, corresponding to Thursday, 01 January, 1970. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.7 LocalTZA ( t, isUTC ) ??? +---------------------------------------------------------------------------------------------- +-- https://tc39.es/ecma262/#sec-local-time-zone-adjustment +-- returns the local time zone adjustment, or offset, in milliseconds +-- LocalTZA( t :: UTC, true ) = should return the offset of the local time zone from UTC measured in milliseconds +-- at time represented by time value t :: UTC. When the result is added to t :: UTC, it should yield +-- the corresponding Number t :: local. +-- LocalTZA( t :: local, false ) = should return the offset of the local time zone from UTC measured in +-- milliseconds at local time represented by Number tlocal. +-- When the result is subtracted from t :: local, it should yield the corresponding +-- time value t :: UTC. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.8 LocalTime ( t ) +---------------------------------------------------------------------------------------------- +-- Return t + LocalTZA(t, true) + +---------------------------------------------------------------------------------------------- +-- 20.4.1.9 UTC ( t ) +---------------------------------------------------------------------------------------------- +-- Return t - LocalTZA(t, false). + +---------------------------------------------------------------------------------------------- +-- 20.4.1.10 Hours, Minutes, Second, and Milliseconds +---------------------------------------------------------------------------------------------- +-- HourFromTime(t) = floor(t / msPerHour) modulo HoursPerDay +-- MinFromTime(t) = floor(t / msPerMinute) modulo MinutesPerHour +-- SecFromTime(t) = floor(t / msPerSecond) modulo SecondsPerMinute +-- msFromTime(t) = t modulo msPerSecond +-- +-- HoursPerDay = 24 +-- MinutesPerHour = 60 +-- SecondsPerMinute = 60 +-- msPerSecond = 1000 +-- msPerMinute = 60000 = msPerSecond × SecondsPerMinute +-- msPerHour = 3600000 = msPerMinute × MinutesPerHour + +---------------------------------------------------------------------------------------------- +-- 20.4.1.11 MakeTime ( hour, min, sec, ms ) +---------------------------------------------------------------------------------------------- +-- If hour is not finite or min is not finite or sec is not finite or ms is not finite, return NaN. +-- h = ! ToInteger(hour). +-- m = ! ToInteger(min). +-- s = ! ToInteger(sec). +-- milli = ! ToInteger(ms). +-- t = h * msPerHour + m * msPerMinute + s * msPerSecond + milli +-- (performing the arithmetic according to IEEE 754-2019 rules (that is, as if using the ECMAScript operators * and +)) +-- Return t. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.12 MakeDay ( year, month, date ) +---------------------------------------------------------------------------------------------- +-- If year is not finite or month is not finite or date is not finite, return NaN. +-- y = ! ToInteger(year). +-- m = ! ToInteger(month). +-- dt = ! ToInteger(date). +-- ym = y + floor(m / 12). +-- mn = m modulo 12. +-- Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn and DateFromTime(t) is 1; +-- but if this is not possible (because some argument is out of range), return NaN. +-- Return Day(t) + dt - 1. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.13 MakeDate ( day, time ) +---------------------------------------------------------------------------------------------- +-- If day is not finite or time is not finite, return NaN. +-- Return day × msPerDay + time. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.14 TimeClip ( time ) +---------------------------------------------------------------------------------------------- +-- If time is not finite, return NaN. +-- If abs(time) > 8.64 × 10^15, return NaN. +-- Return ! ToInteger(time). + +---------------------------------------------------------------------------------------------- +-- 20.4.1.15 Date Time String Format +---------------------------------------------------------------------------------------------- +-- YYYY-MM-DDTHH:mm:ss.sssZ +-- ISO 8601 calendar date extended format. + +---------------------------------------------------------------------------------------------- +-- 20.4.1.15.1 Expanded Years +---------------------------------------------------------------------------------------------- + +---------------------------------------------------------------------------------------------- +-- 20.4.2.1 Date ( year, month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ) +---------------------------------------------------------------------------------------------- +-- If NewTarget is undefined, then +-- Let `now` be the Number that is the time value (UTC) identifying the current time. +-- Return ToDateString(now). +-- Else +-- y = ToNumber(year). +-- m = ToNumber(month). +-- If date is present, let dt be ? ToNumber(date); else let dt be 1. +-- If hours is present, let h be ? ToNumber(hours); else let h be 0. +-- If minutes is present, let min be ? ToNumber(minutes); else let min be 0. +-- If seconds is present, let s be ? ToNumber(seconds); else let s be 0. +-- If ms is present, let milli be ? ToNumber(ms); else let milli be 0. +-- If y is NaN, let yr be NaN. +-- Else, +-- Let yi be ! ToInteger(y). +-- If 0 ≤ yi ≤ 99, let yr be 1900 + yi; otherwise, let yr be y. +-- finalDate = MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)). +-- O = OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »). +-- Set O.[[DateValue]] to TimeClip(UTC(finalDate)). +-- Return O. + +---------------------------------------------------------------------------------------------- +-- 20.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ) +---------------------------------------------------------------------------------------------- +-- y = ToNumber(year). +-- If month is present then m = ToNumber(month); else m = 0. +-- If date is present, then dt = ToNumber(date); else dt = 1. +-- If hours is present, then h = ToNumber(hours); else h = 0. +-- If minutes is present, then min = ToNumber(minutes); min = 0. +-- If seconds is present, then s = ToNumber(seconds); else s = 0. +-- If ms is present, then milli = ToNumber(ms); else milli = 0. +-- If y is NaN, let yr be NaN. +-- Else, +-- Let yi be ! ToInteger(y). +-- If 0 ≤ yi ≤ 99, +-- then yr = 1900 + yi; +-- otherwise, yr = y. +-- Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.2 getDate ( ) +---------------------------------------------------------------------------------------------- +-- t = thisTimeValue(this value). +-- If t is NaN, return NaN. +-- Return DateFromTime(LocalTime(t)). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.3 getDay ( ) +---------------------------------------------------------------------------------------------- +-- Return WeekDay(LocalTime(t)). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.4 getFullYear ( ) +---------------------------------------------------------------------------------------------- +-- Return YearFromTime(LocalTime(t)). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.5 getHours ( ) +---------------------------------------------------------------------------------------------- +-- Return HourFromTime(LocalTime(t)). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.6 getMilliseconds ( ) +---------------------------------------------------------------------------------------------- +-- Return msFromTime(LocalTime(t)). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.7 getMinutes ( ) +---------------------------------------------------------------------------------------------- +-- Return MinFromTime(LocalTime(t)) + +---------------------------------------------------------------------------------------------- +-- 20.4.4.7 getMonth ( ) +---------------------------------------------------------------------------------------------- +-- Return MonthFromTime(LocalTime(t)) + +---------------------------------------------------------------------------------------------- +-- 20.4.4.9 getSeconds ( ) +---------------------------------------------------------------------------------------------- +-- Return SecFromTime(LocalTime(t)). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.10 getTime ( ) +---------------------------------------------------------------------------------------------- +-- Return ? thisTimeValue(this value). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.11 getTimezoneOffset ( ) +---------------------------------------------------------------------------------------------- +-- Return (t - LocalTime(t)) / msPerMinute. + +---------------------------------------------------------------------------------------------- +-- 20.4.4.12 getUTCDate ( ) +---------------------------------------------------------------------------------------------- +-- Return DateFromTime(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.13 getUTCDay ( ) +---------------------------------------------------------------------------------------------- +-- Return WeekDay(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.14 getUTCFullYear ( ) +---------------------------------------------------------------------------------------------- +-- Return YearFromTime(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.15 getUTCHours ( ) +---------------------------------------------------------------------------------------------- +-- Return HourFromTime(t) + +---------------------------------------------------------------------------------------------- +-- 20.4.4.16 getUTCMilliseconds ( ) +---------------------------------------------------------------------------------------------- +-- Return msFromTime(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.17 getUTCMinutes ( ) +---------------------------------------------------------------------------------------------- +-- Return MinFromTime(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.18 getUTCMonth ( ) +---------------------------------------------------------------------------------------------- +-- Return MonthFromTime(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.19 getUTCSeconds ( ) +---------------------------------------------------------------------------------------------- +-- Return SecFromTime(t). + +---------------------------------------------------------------------------------------------- +-- 20.4.4.20 setDate ( date ) +---------------------------------------------------------------------------------------------- +-- t = LocalTime(thisTimeValue(this value)). +-- dt = ToNumber(date). +-- newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)). +-- u = TimeClip(UTC(newDate)). +-- Set the [[DateValue]] internal slot of this Date object to u. +-- Return u. + +---------------------------------------------------------------------------------------------- +-- 20.4.4.21 setFullYear ( year [ , month [ , date ] ] ) +---------------------------------------------------------------------------------------------- +-- t = thisTimeValue(this value). +-- If t is NaN, set t to +0; otherwise, set t to LocalTime(t). +-- y = ToNumber(year). +-- If month is not present, m = MonthFromTime(t); otherwise, m = ToNumber(month). +-- If date is not present, dt = DateFromTime(t); otherwise, dt = ToNumber(date). +-- newDate = MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)). +-- u = TimeClip(UTC(newDate)). +-- Set the [[DateValue]] internal slot of this Date object to u. +-- Return u. + +---------------------------------------------------------------------------------------------- +-- 20.4.4.22 setHours ( hour [ , min [ , sec [ , ms ] ] ] ) +---------------------------------------------------------------------------------------------- +-- t = LocalTime(thisTimeValue(this value)). +-- h = ToNumber(hour). +-- If min is not present, m = MinFromTime(t); otherwise, m = ToNumber(min). +-- If sec is not present, s = SecFromTime(t); otherwise, s = ToNumber(sec). +-- If ms is not present, milli = msFromTime(t); otherwise, milli = ToNumber(ms). +-- date = MakeDate(Day(t), MakeTime(h, m, s, milli)). +-- u = TimeClip(UTC(date)). +-- Set the [[DateValue]] internal slot of this Date object to u. +-- Return u. + +-- got bored can refer to them if implementing functions !! + main :: Effect Unit main = do log "check Duration monoid" From 93c3750f59fb2f0909c167fd42f49d7a024f60b1 Mon Sep 17 00:00:00 2001 From: Cmdv Date: Tue, 22 Sep 2020 19:18:07 +0100 Subject: [PATCH 2/3] split out the tests into files & clean up --- test/Test/Date.purs | 72 ++++++++++++++ test/Test/DateTime.purs | 36 +++++++ test/Test/Duration.purs | 32 +++++++ test/Test/Helpers.purs | 108 +++++++++++++++++++++ test/Test/Instant.purs | 35 +++++++ test/Test/Main.purs | 203 ++-------------------------------------- test/Test/Time.purs | 47 ++++++++++ 7 files changed, 340 insertions(+), 193 deletions(-) create mode 100644 test/Test/Date.purs create mode 100644 test/Test/DateTime.purs create mode 100644 test/Test/Duration.purs create mode 100644 test/Test/Helpers.purs create mode 100644 test/Test/Instant.purs create mode 100644 test/Test/Time.purs diff --git a/test/Test/Date.purs b/test/Test/Date.purs new file mode 100644 index 0000000..b362f23 --- /dev/null +++ b/test/Test/Date.purs @@ -0,0 +1,72 @@ +module Test.Date where + +import Prelude + +import Data.Date as Date +import Data.Enum (toEnum) +import Data.Maybe (Maybe(..), fromJust) +import Data.Time.Duration as Duration +import Effect (Effect) +import Effect.Console (log) +import Partial.Unsafe (unsafePartial) +import Test.Assert (assert) +import Test.Helpers (checkBounded, checkBoundedEnum, epochDate) +import Type.Proxy (Proxy(..)) + +dateTests :: Effect Unit +dateTests = do + log "--------- Date Tests ---------" + log "Check that Year is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Date.Year) + + log "Check that Month is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Date.Month) + + log "Check that Day is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Date.Day) + + log "Check that Date is a good Bounded" + checkBounded (Proxy :: Proxy Date.Date) + + log "Check that the earliest date is a valid date" + assert $ Just bottom == Date.exactDate bottom bottom bottom + + log "Check that the latest date is a valid date" + assert $ Just top == Date.exactDate top top top + + log "Check that weekday behaves as expected" + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 6) == Date.Monday + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 7) == Date.Tuesday + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 8) == Date.Wednesday + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 9) == Date.Thursday + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 10) == Date.Friday + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 11) == Date.Saturday + assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 12) == Date.Sunday + + let d1 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.January <*> toEnum 1 + let d2 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.February <*> toEnum 1 + let d3 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.March <*> toEnum 1 + let d4 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2018 <*> pure Date.September <*> toEnum 26 + let d5 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 1988 <*> pure Date.August <*> toEnum 15 + + log "Check that diff behaves as expected" + assert $ Date.diff d2 d1 == Duration.Days 31.0 + assert $ Date.diff d3 d2 == Duration.Days 29.0 + + let unsafeYear = unsafePartial fromJust <<< toEnum + log "Check that isLeapYear behaves as expected" + assert $ not $ Date.isLeapYear (unsafeYear 2017) + assert $ Date.isLeapYear (unsafeYear 2016) + + log "Check that epoch is correctly constructed" + assert $ Just (Date.year epochDate) == toEnum 1 + assert $ Date.month epochDate == bottom + assert $ Date.day epochDate == bottom + + log "Check that adjust behaves as expected" + assert $ Date.adjust (Duration.Days 31.0) d1 == Just d2 + assert $ Date.adjust (Duration.Days 999.0) d1 == Just d4 + assert $ Date.adjust (Duration.Days 10000.0) d5 == Just d1 + assert $ Date.adjust (Duration.Days (-31.0)) d2 == Just d1 + assert $ Date.adjust (Duration.Days (- 999.0)) d4 == Just d1 + assert $ Date.adjust (Duration.Days (-10000.0)) d1 == Just d5 diff --git a/test/Test/DateTime.purs b/test/Test/DateTime.purs new file mode 100644 index 0000000..72979e4 --- /dev/null +++ b/test/Test/DateTime.purs @@ -0,0 +1,36 @@ +module Test.DateTime + ( dateTimeTests + ) where + +import Prelude + +import Data.Date as Date +import Data.DateTime as DateTime +import Data.Enum (toEnum) +import Data.Maybe (Maybe(..)) +import Data.Newtype (over) +import Data.Time.Duration as Duration +import Effect (Effect) +import Effect.Console (log) +import Math (floor) +import Test.Assert (assert) +import Test.Helpers (dateTime1, dateTime2, dateTime3, dateTime4, dateTime5, epochDateTime) + +dateTimeTests :: Effect Unit +dateTimeTests = do + log "--------- DateTime Tests ---------" + log "Check that adjust behaves as expected" + assert $ DateTime.adjust (Duration.fromDuration (Duration.Days 31.0) <> Duration.fromDuration (Duration.Minutes 40.0)) dateTime1 == Just dateTime4 + assert $ (Date.year <<< DateTime.date <$> + (DateTime.adjust (Duration.Days 735963.0) epochDateTime)) + == toEnum 2016 + + log "Check that diff behaves as expected" + assert $ DateTime.diff dateTime2 dateTime1 == Duration.Minutes 40.0 + assert $ DateTime.diff dateTime1 dateTime2 == Duration.Minutes (-40.0) + assert $ DateTime.diff dateTime3 dateTime1 == Duration.Days 31.0 + assert $ DateTime.diff dateTime5 dateTime3 == Duration.Days 29.0 + assert $ DateTime.diff dateTime1 dateTime3 == Duration.Days (-31.0) + assert $ DateTime.diff dateTime4 dateTime1 == Duration.fromDuration (Duration.Days 31.0) <> Duration.fromDuration (Duration.Minutes 40.0) + assert $ over Duration.Days floor (DateTime.diff dateTime1 epochDateTime) + == Duration.Days 735963.0 diff --git a/test/Test/Duration.purs b/test/Test/Duration.purs new file mode 100644 index 0000000..1ba7bad --- /dev/null +++ b/test/Test/Duration.purs @@ -0,0 +1,32 @@ +module Test.Duration + ( durationTests + ) where + +import Prelude + +import Effect (Effect) +import Effect.Console (log) +import Data.Either (Either(..), isRight) +import Data.Interval as Interval +import Data.Interval.Duration.Iso as IsoDuration +import Test.Assert (assert) + +durationTests :: Effect Unit +durationTests = do + log "--------- Durations Tests ---------" + log "check Duration monoid" + assert $ Interval.year 1.0 == mempty <> Interval.year 2.0 <> Interval.year 1.0 <> Interval.year (-2.0) + assert $ Interval.second 0.5 == Interval.millisecond 500.0 + assert $ IsoDuration.mkIsoDuration (Interval.week 1.2 <> Interval.week 1.2) + == IsoDuration.mkIsoDuration (Interval.week 2.4) + assert $ isRight $ IsoDuration.mkIsoDuration (Interval.day 1.2 <> mempty) + assert $ isRight $ IsoDuration.mkIsoDuration (Interval.day 1.2 <> Interval.second 0.0) + assert $ isRight $ IsoDuration.mkIsoDuration (Interval.year 2.0 <> Interval.day 1.0) + assert $ IsoDuration.mkIsoDuration (Interval.year 2.5 <> Interval.day 1.0) + == Left (pure (IsoDuration.InvalidFractionalUse Interval.Year)) + log $ show $ IsoDuration.mkIsoDuration (Interval.year 2.5 <> Interval.week 1.0) + == Left (pure IsoDuration.InvalidWeekComponentUsage <> pure (IsoDuration.InvalidFractionalUse Interval.Year)) + assert $ IsoDuration.mkIsoDuration (Interval.year 2.0 <> Interval.day (-1.0)) + == Left (pure (IsoDuration.ContainsNegativeValue Interval.Day)) + assert $ IsoDuration.mkIsoDuration (mempty) + == Left (pure IsoDuration.IsEmpty) diff --git a/test/Test/Helpers.purs b/test/Test/Helpers.purs new file mode 100644 index 0000000..e6e5fbc --- /dev/null +++ b/test/Test/Helpers.purs @@ -0,0 +1,108 @@ +module Test.Helpers + ( checkBounded + , checkBoundedEnum + , date1 + , date2 + , date3 + , date4 + , date5 + , dateTime1 + , dateTime2 + , dateTime3 + , dateTime4 + , dateTime5 + , epochDate + , epochDateTime + , epochMillis + , time1 + , time2 + , time3 + , time4 + , time5 + ) where + +import Prelude + +import Data.Array as Array +import Data.Date as Date +import Data.DateTime as DateTime +import Data.Enum (class BoundedEnum, Cardinality, toEnum, enumFromTo, cardinality, succ, fromEnum, pred) +import Data.Maybe (Maybe(..), fromJust) +import Data.Newtype (unwrap) +import Data.Time as Time +import Effect (Effect) +import Partial.Unsafe (unsafePartial) +import Test.Assert (assert) +import Type.Proxy (Proxy) + +checkBounded :: forall e. Bounded e => Proxy e -> Effect Unit +checkBounded _ = do + assert $ Just (bottom :: Time.Hour) == toEnum (fromEnum (bottom :: Time.Hour)) + assert $ pred (bottom :: Time.Hour) == Nothing + assert $ Just (top :: Time.Hour) == toEnum (fromEnum (top :: Time.Hour)) + assert $ succ (top :: Time.Hour) == Nothing + +checkBoundedEnum :: forall e. BoundedEnum e => Proxy e -> Effect Unit +checkBoundedEnum p = do + checkBounded p + let card = unwrap (cardinality :: Cardinality e) + assert $ Array.length (enumFromTo bottom (top :: e)) == card + + +date1 :: Date.Date +date1 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.January <*> toEnum 1 + +date2 :: Date.Date +date2 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.February <*> toEnum 1 + +date3 :: Date.Date +date3 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.March <*> toEnum 1 + +date4 :: Date.Date +date4 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2018 <*> pure Date.September <*> toEnum 26 + +date5 :: Date.Date +date5 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 1988 <*> pure Date.August <*> toEnum 15 + + +dateTime1 :: DateTime.DateTime +dateTime1 = DateTime.DateTime date1 time1 + +dateTime2 :: DateTime.DateTime +dateTime2 = DateTime.DateTime date1 time2 + +dateTime3 :: DateTime.DateTime +dateTime3 = DateTime.DateTime date2 time1 + +dateTime4 :: DateTime.DateTime +dateTime4 = DateTime.DateTime date2 time2 + +dateTime5 :: DateTime.DateTime +dateTime5 = DateTime.DateTime date3 time1 + +epochDate :: Date.Date +epochDate = unsafePartial fromJust $ Date.canonicalDate + <$> toEnum 1 + <*> pure bottom + <*> pure bottom + +epochDateTime :: DateTime.DateTime +epochDateTime = DateTime.DateTime epochDate bottom + +epochMillis :: Number +epochMillis = -62135596800000.0 + +time1 :: Time.Time +time1 = unsafePartial $ fromJust $ Time.Time <$> toEnum 17 <*> toEnum 42 <*> toEnum 16 <*> toEnum 362 + +time2 :: Time.Time +time2 = unsafePartial $ fromJust $ Time.Time <$> toEnum 18 <*> toEnum 22 <*> toEnum 16 <*> toEnum 362 + +time3 :: Time.Time +time3 = unsafePartial $ fromJust $ Time.Time <$> toEnum 17 <*> toEnum 2 <*> toEnum 16 <*> toEnum 362 + +time4 :: Time.Time +time4 = unsafePartial $ fromJust $ Time.Time <$> toEnum 23 <*> toEnum 0 <*> toEnum 0 <*> toEnum 0 + +time5 :: Time.Time +time5 = unsafePartial $ fromJust $ Time.Time <$> toEnum 1 <*> toEnum 0 <*> toEnum 0 <*> toEnum 0 diff --git a/test/Test/Instant.purs b/test/Test/Instant.purs new file mode 100644 index 0000000..9d83f02 --- /dev/null +++ b/test/Test/Instant.purs @@ -0,0 +1,35 @@ +module Test.Instant + ( instantTests + ) where + +import Prelude + +import Data.DateTime.Instant as Instant +import Data.Maybe (Maybe(..)) +import Data.Time.Duration as Duration +import Effect (Effect) +import Effect.Console (log) +import Test.Assert (assert) +import Test.Helpers (dateTime1, dateTime2, dateTime3, dateTime4, epochDateTime, epochMillis) + +instantTests :: Effect Unit +instantTests = do + log "--------- Instant Tests ---------" + log "Check that the earliest date is a valid Instant" + let bottomInstant = Instant.fromDateTime bottom + assert $ Just bottomInstant == Instant.instant (Instant.unInstant bottomInstant) + + log "Check that the latest date is a valid Instant" + let topInstant = Instant.fromDateTime top + assert $ Just topInstant == Instant.instant (Instant.unInstant topInstant) + + log "Check that an Instant can be constructed from epoch" + assert $ (Instant.unInstant $ Instant.fromDateTime epochDateTime) == Duration.Milliseconds epochMillis + + log "Check that instant/datetime conversion is bijective" + assert $ Instant.toDateTime (Instant.fromDateTime bottom) == bottom + assert $ Instant.toDateTime (Instant.fromDateTime top) == top + assert $ Instant.toDateTime (Instant.fromDateTime dateTime1) == dateTime1 + assert $ Instant.toDateTime (Instant.fromDateTime dateTime2) == dateTime2 + assert $ Instant.toDateTime (Instant.fromDateTime dateTime3) == dateTime3 + assert $ Instant.toDateTime (Instant.fromDateTime dateTime4) == dateTime4 diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 6e67187..e3fec78 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -4,23 +4,11 @@ import Prelude import Effect (Effect) import Effect.Console (log) -import Data.Array as Array -import Data.Date as Date -import Data.DateTime as DateTime -import Data.DateTime.Instant as Instant -import Data.Either (Either(..), isRight) -import Data.Enum (class BoundedEnum, Cardinality, toEnum, enumFromTo, cardinality, succ, fromEnum, pred) -import Data.Interval as Interval -import Data.Interval.Duration.Iso as IsoDuration -import Data.Maybe (Maybe(..), fromJust) -import Data.Newtype (over, unwrap) -import Data.Time as Time -import Data.Time.Duration as Duration -import Data.Tuple (Tuple(..), snd) -import Math (floor) -import Partial.Unsafe (unsafePartial) -import Test.Assert (assert) -import Type.Proxy (Proxy(..)) +import Test.Date (dateTests) +import Test.DateTime (dateTimeTests) +import Test.Duration (durationTests) +import Test.Instant (instantTests) +import Test.Time (timeTests) ---------------------------------------------------------------------------------------------- -- 20.4.1.2 Day Number and Time within Day @@ -359,180 +347,9 @@ import Type.Proxy (Proxy(..)) main :: Effect Unit main = do - log "check Duration monoid" - assert $ Interval.year 1.0 == mempty <> Interval.year 2.0 <> Interval.year 1.0 <> Interval.year (-2.0) - assert $ Interval.second 0.5 == Interval.millisecond 500.0 - assert $ IsoDuration.mkIsoDuration (Interval.week 1.2 <> Interval.week 1.2) - == IsoDuration.mkIsoDuration (Interval.week 2.4) - assert $ isRight $ IsoDuration.mkIsoDuration (Interval.day 1.2 <> mempty) - assert $ isRight $ IsoDuration.mkIsoDuration (Interval.day 1.2 <> Interval.second 0.0) - assert $ isRight $ IsoDuration.mkIsoDuration (Interval.year 2.0 <> Interval.day 1.0) - assert $ IsoDuration.mkIsoDuration (Interval.year 2.5 <> Interval.day 1.0) - == Left (pure (IsoDuration.InvalidFractionalUse Interval.Year)) - log $ show $ IsoDuration.mkIsoDuration (Interval.year 2.5 <> Interval.week 1.0) - == Left (pure IsoDuration.InvalidWeekComponentUsage <> pure (IsoDuration.InvalidFractionalUse Interval.Year)) - assert $ IsoDuration.mkIsoDuration (Interval.year 2.0 <> Interval.day (-1.0)) - == Left (pure (IsoDuration.ContainsNegativeValue Interval.Day)) - assert $ IsoDuration.mkIsoDuration (mempty) - == Left (pure IsoDuration.IsEmpty) - - let epochDate = unsafePartial fromJust $ Date.canonicalDate - <$> toEnum 1 - <*> pure bottom - <*> pure bottom - let epochDateTime = DateTime.DateTime epochDate bottom - let epochMillis = -62135596800000.0 - -- time -------------------------------------------------------------------- - - log "Check that Hour is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Time.Hour) - - log "Check that Minute is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Time.Minute) - - log "Check that Second is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Time.Second) - - log "Check that Millisecond is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Time.Millisecond) - - log "Check that Time is a good Bounded" - checkBounded (Proxy :: Proxy Time.Time) - - let t1 = unsafePartial $ fromJust $ Time.Time <$> toEnum 17 <*> toEnum 42 <*> toEnum 16 <*> toEnum 362 - let t2 = unsafePartial $ fromJust $ Time.Time <$> toEnum 18 <*> toEnum 22 <*> toEnum 16 <*> toEnum 362 - let t3 = unsafePartial $ fromJust $ Time.Time <$> toEnum 17 <*> toEnum 2 <*> toEnum 16 <*> toEnum 362 - let t4 = unsafePartial $ fromJust $ Time.Time <$> toEnum 23 <*> toEnum 0 <*> toEnum 0 <*> toEnum 0 - let t5 = unsafePartial $ fromJust $ Time.Time <$> toEnum 1 <*> toEnum 0 <*> toEnum 0 <*> toEnum 0 - - log "Check that adjust behaves as expected" - assert $ Time.adjust (Duration.Milliseconds 1.0) top == Tuple (Duration.Days 1.0) bottom - assert $ Time.adjust (Duration.Milliseconds (-1.0)) bottom == Tuple (Duration.Days (-1.0)) top - assert $ Time.adjust (Duration.Minutes 40.0) t1 == Tuple (Duration.Days 0.0) t2 - assert $ Time.adjust (Duration.Days 40.0) t1 == Tuple (Duration.Days 40.0) t1 - assert $ Time.adjust (Duration.fromDuration (Duration.Days 2.0) <> Duration.fromDuration (Duration.Minutes 40.0)) t1 == Tuple (Duration.Days 2.0) t2 - assert $ Time.adjust (Duration.fromDuration (Duration.Days 2.0) <> Duration.fromDuration (Duration.Minutes (-40.0))) t1 == Tuple (Duration.Days 2.0) t3 - assert $ snd (Time.adjust (Duration.fromDuration (Duration.Days 3.872)) t1) == snd (Time.adjust (Duration.fromDuration (Duration.Days 0.872)) t1) - assert $ Time.adjust (Duration.Hours 2.0) t4 == Tuple (Duration.Days 1.0) t5 - - log "Check that diff behaves as expected" - assert $ Time.diff t2 t1 == Duration.Minutes 40.0 - assert $ Time.diff t1 t2 == Duration.Minutes (-40.0) - assert $ Time.diff t4 t5 == Duration.Hours 22.0 - - -- date -------------------------------------------------------------------- - - log "Check that Year is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Date.Year) - - log "Check that Month is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Date.Month) - - log "Check that Day is a good BoundedEnum" - checkBoundedEnum (Proxy :: Proxy Date.Day) - - log "Check that Date is a good Bounded" - checkBounded (Proxy :: Proxy Date.Date) - - log "Check that the earliest date is a valid date" - assert $ Just bottom == Date.exactDate bottom bottom bottom - - log "Check that the latest date is a valid date" - assert $ Just top == Date.exactDate top top top - - log "Check that weekday behaves as expected" - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 6) == Date.Monday - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 7) == Date.Tuesday - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 8) == Date.Wednesday - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 9) == Date.Thursday - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 10) == Date.Friday - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 11) == Date.Saturday - assert $ Date.weekday (unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.June <*> toEnum 12) == Date.Sunday - - let d1 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.January <*> toEnum 1 - let d2 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.February <*> toEnum 1 - let d3 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2016 <*> pure Date.March <*> toEnum 1 - let d4 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 2018 <*> pure Date.September <*> toEnum 26 - let d5 = unsafePartial fromJust $ Date.canonicalDate <$> toEnum 1988 <*> pure Date.August <*> toEnum 15 - - log "Check that diff behaves as expected" - assert $ Date.diff d2 d1 == Duration.Days 31.0 - assert $ Date.diff d3 d2 == Duration.Days 29.0 - - let unsafeYear = unsafePartial fromJust <<< toEnum - log "Check that isLeapYear behaves as expected" - assert $ not $ Date.isLeapYear (unsafeYear 2017) - assert $ Date.isLeapYear (unsafeYear 2016) - - log "Check that epoch is correctly constructed" - assert $ Just (Date.year epochDate) == toEnum 1 - assert $ Date.month epochDate == bottom - assert $ Date.day epochDate == bottom - - log "Check that adjust behaves as expected" - assert $ Date.adjust (Duration.Days 31.0) d1 == Just d2 - assert $ Date.adjust (Duration.Days 999.0) d1 == Just d4 - assert $ Date.adjust (Duration.Days 10000.0) d5 == Just d1 - assert $ Date.adjust (Duration.Days (-31.0)) d2 == Just d1 - assert $ Date.adjust (Duration.Days (- 999.0)) d4 == Just d1 - assert $ Date.adjust (Duration.Days (-10000.0)) d1 == Just d5 - - -- datetime ---------------------------------------------------------------- - - let dt1 = DateTime.DateTime d1 t1 - let dt2 = DateTime.DateTime d1 t2 - let dt3 = DateTime.DateTime d2 t1 - let dt4 = DateTime.DateTime d2 t2 - let dt5 = DateTime.DateTime d3 t1 - - log "Check that adjust behaves as expected" - assert $ DateTime.adjust (Duration.fromDuration (Duration.Days 31.0) <> Duration.fromDuration (Duration.Minutes 40.0)) dt1 == Just dt4 - assert $ (Date.year <<< DateTime.date <$> - (DateTime.adjust (Duration.Days 735963.0) epochDateTime)) - == toEnum 2016 - - log "Check that diff behaves as expected" - assert $ DateTime.diff dt2 dt1 == Duration.Minutes 40.0 - assert $ DateTime.diff dt1 dt2 == Duration.Minutes (-40.0) - assert $ DateTime.diff dt3 dt1 == Duration.Days 31.0 - assert $ DateTime.diff dt5 dt3 == Duration.Days 29.0 - assert $ DateTime.diff dt1 dt3 == Duration.Days (-31.0) - assert $ DateTime.diff dt4 dt1 == Duration.fromDuration (Duration.Days 31.0) <> Duration.fromDuration (Duration.Minutes 40.0) - assert $ over Duration.Days floor (DateTime.diff dt1 epochDateTime) - == Duration.Days 735963.0 - - -- instant ----------------------------------------------------------------- - - log "Check that the earliest date is a valid Instant" - let bottomInstant = Instant.fromDateTime bottom - assert $ Just bottomInstant == Instant.instant (Instant.unInstant bottomInstant) - - log "Check that the latest date is a valid Instant" - let topInstant = Instant.fromDateTime top - assert $ Just topInstant == Instant.instant (Instant.unInstant topInstant) - - log "Check that an Instant can be constructed from epoch" - assert $ (Instant.unInstant $ Instant.fromDateTime epochDateTime) == Duration.Milliseconds epochMillis - - log "Check that instant/datetime conversion is bijective" - assert $ Instant.toDateTime (Instant.fromDateTime bottom) == bottom - assert $ Instant.toDateTime (Instant.fromDateTime top) == top - assert $ Instant.toDateTime (Instant.fromDateTime dt1) == dt1 - assert $ Instant.toDateTime (Instant.fromDateTime dt2) == dt2 - assert $ Instant.toDateTime (Instant.fromDateTime dt3) == dt3 - assert $ Instant.toDateTime (Instant.fromDateTime dt4) == dt4 - + durationTests + timeTests + dateTests + dateTimeTests + instantTests log "All tests done" - -checkBounded :: forall e. Bounded e => Proxy e -> Effect Unit -checkBounded _ = do - assert $ Just (bottom :: Time.Hour) == toEnum (fromEnum (bottom :: Time.Hour)) - assert $ pred (bottom :: Time.Hour) == Nothing - assert $ Just (top :: Time.Hour) == toEnum (fromEnum (top :: Time.Hour)) - assert $ succ (top :: Time.Hour) == Nothing - -checkBoundedEnum :: forall e. BoundedEnum e => Proxy e -> Effect Unit -checkBoundedEnum p = do - checkBounded p - let card = unwrap (cardinality :: Cardinality e) - assert $ Array.length (enumFromTo bottom (top :: e)) == card diff --git a/test/Test/Time.purs b/test/Test/Time.purs new file mode 100644 index 0000000..68bfec5 --- /dev/null +++ b/test/Test/Time.purs @@ -0,0 +1,47 @@ +module Test.Time + ( timeTests + ) where + +import Prelude + +import Data.Time as Time +import Data.Time.Duration as Duration +import Data.Tuple (Tuple(..), snd) +import Effect (Effect) +import Effect.Console (log) +import Test.Assert (assert) +import Test.Helpers (checkBounded, checkBoundedEnum, time1, time2, time3, time4, time5) +import Type.Proxy (Proxy(..)) + +timeTests :: Effect Unit +timeTests = do + log "--------- Time Tests ---------" + log "Check that Hour is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Time.Hour) + + log "Check that Minute is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Time.Minute) + + log "Check that Second is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Time.Second) + + log "Check that Millisecond is a good BoundedEnum" + checkBoundedEnum (Proxy :: Proxy Time.Millisecond) + + log "Check that Time is a good Bounded" + checkBounded (Proxy :: Proxy Time.Time) + + log "Check that adjust behaves as expected" + assert $ Time.adjust (Duration.Milliseconds 1.0) top == Tuple (Duration.Days 1.0) bottom + assert $ Time.adjust (Duration.Milliseconds (-1.0)) bottom == Tuple (Duration.Days (-1.0)) top + assert $ Time.adjust (Duration.Minutes 40.0) time1 == Tuple (Duration.Days 0.0) time2 + assert $ Time.adjust (Duration.Days 40.0) time1 == Tuple (Duration.Days 40.0) time1 + assert $ Time.adjust (Duration.fromDuration (Duration.Days 2.0) <> Duration.fromDuration (Duration.Minutes 40.0)) time1 == Tuple (Duration.Days 2.0) time2 + assert $ Time.adjust (Duration.fromDuration (Duration.Days 2.0) <> Duration.fromDuration (Duration.Minutes (-40.0))) time1 == Tuple (Duration.Days 2.0) time3 + assert $ snd (Time.adjust (Duration.fromDuration (Duration.Days 3.872)) time1) == snd (Time.adjust (Duration.fromDuration (Duration.Days 0.872)) time1) + assert $ Time.adjust (Duration.Hours 2.0) time4 == Tuple (Duration.Days 1.0) time5 + + log "Check that diff behaves as expected" + assert $ Time.diff time2 time1 == Duration.Minutes 40.0 + assert $ Time.diff time1 time2 == Duration.Minutes (-40.0) + assert $ Time.diff time4 time5 == Duration.Hours 22.0 From becc338366e3bd427dbaa37ef943d7d4a68f3c70 Mon Sep 17 00:00:00 2001 From: Cmdv Date: Tue, 22 Sep 2020 19:31:04 +0100 Subject: [PATCH 3/3] make a Spec.md for copy of specs --- test/Test/Main.purs | 335 -------------------------------------------- test/Test/Spec.md | 334 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+), 335 deletions(-) create mode 100644 test/Test/Spec.md diff --git a/test/Test/Main.purs b/test/Test/Main.purs index e3fec78..d85f46d 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -10,341 +10,6 @@ import Test.Duration (durationTests) import Test.Instant (instantTests) import Test.Time (timeTests) ----------------------------------------------------------------------------------------------- --- 20.4.1.2 Day Number and Time within Day ----------------------------------------------------------------------------------------------- --- Day(t) = floor(t / msPerDay) --- msPerDay = 86400000 --- --- The remainder is called the time within the day: --- TimeWithinDay(t) = t modulo msPerDay - ----------------------------------------------------------------------------------------------- --- 20.4.1.3 Year Number ----------------------------------------------------------------------------------------------- --- DaysInYear(y) --- = 365 if (y modulo 4) ≠ 0 --- = 366 if (y modulo 4) = 0 and (y modulo 100) ≠ 0 --- = 365 if (y modulo 100) = 0 and (y modulo 400) ≠ 0 --- = 366 if (y modulo 400) = 0 --- --- All non-leap years have 365 days with the usual number of days per month and leap years have an extra day in February. --- The day number of the first day of year y is given by: --- DayFromYear(y) = 365 × (y - 1970) + floor((y - 1969) / 4) - floor((y - 1901) / 100) + floor((y - 1601) / 400) --- --- The time value of the start of a year is: --- TimeFromYear(y) = msPerDay × DayFromYear(y) --- YearFromTime(t) = the largest integer y (closest to positive infinity) such that TimeFromYear(y) ≤ t --- --- InLeapYear(t) --- = 0 if DaysInYear(YearFromTime(t)) = 365 --- = 1 if DaysInYear(YearFromTime(t)) = 366 --- --- MonthFromTime(t) --- = 0 if 0 ≤ DayWithinYear(t) < 31 --- = 1 if 31 ≤ DayWithinYear(t) < 59 + InLeapYear(t) --- = 2 if 59 + InLeapYear(t) ≤ DayWithinYear(t) < 90 + InLeapYear(t) --- = 3 if 90 + InLeapYear(t) ≤ DayWithinYear(t) < 120 + InLeapYear(t) --- = 4 if 120 + InLeapYear(t) ≤ DayWithinYear(t) < 151 + InLeapYear(t) --- = 5 if 151 + InLeapYear(t) ≤ DayWithinYear(t) < 181 + InLeapYear(t) --- = 6 if 181 + InLeapYear(t) ≤ DayWithinYear(t) < 212 + InLeapYear(t) --- = 7 if 212 + InLeapYear(t) ≤ DayWithinYear(t) < 243 + InLeapYear(t) --- = 8 if 243 + InLeapYear(t) ≤ DayWithinYear(t) < 273 + InLeapYear(t) --- = 9 if 273 + InLeapYear(t) ≤ DayWithinYear(t) < 304 + InLeapYear(t) --- = 10 if 304 + InLeapYear(t) ≤ DayWithinYear(t) < 334 + InLeapYear(t) --- = 11 if 334 + InLeapYear(t) ≤ DayWithinYear(t) < 365 + InLeapYear(t) --- --- DayWithinYear(t) = Day(t) - DayFromYear(YearFromTime(t)) --- Note that MonthFromTime(0) = 0, corresponding to Thursday, 01 January, 1970. - ----------------------------------------------------------------------------------------------- --- 20.4.1.5 Date Number ----------------------------------------------------------------------------------------------- --- DateFromTime(t) --- = DayWithinYear(t) + 1 if MonthFromTime(t) = 0 --- = DayWithinYear(t) - 30 if MonthFromTime(t) = 1 --- = DayWithinYear(t) - 58 - InLeapYear(t) if MonthFromTime(t) = 2 --- = DayWithinYear(t) - 89 - InLeapYear(t) if MonthFromTime(t) = 3 --- = DayWithinYear(t) - 119 - InLeapYear(t) if MonthFromTime(t) = 4 --- = DayWithinYear(t) - 150 - InLeapYear(t) if MonthFromTime(t) = 5 --- = DayWithinYear(t) - 180 - InLeapYear(t) if MonthFromTime(t) = 6 --- = DayWithinYear(t) - 211 - InLeapYear(t) if MonthFromTime(t) = 7 --- = DayWithinYear(t) - 242 - InLeapYear(t) if MonthFromTime(t) = 8 --- = DayWithinYear(t) - 272 - InLeapYear(t) if MonthFromTime(t) = 9 --- = DayWithinYear(t) - 303 - InLeapYear(t) if MonthFromTime(t) = 10 --- = DayWithinYear(t) - 333 - InLeapYear(t) if MonthFromTime(t) = 11 - ----------------------------------------------------------------------------------------------- --- 20.4.1.6 Week Day ----------------------------------------------------------------------------------------------- --- WeekDay(t) = (Day(t) + 4) modulo 7 --- A weekday value of --- 0 specifies Sunday; --- 1 specifies Monday; --- 2 specifies Tuesday; --- 3 specifies Wednesday; --- 4 specifies Thursday; --- 5 specifies Friday; --- 6 specifies Saturday. --- Note that WeekDay(0) = 4, corresponding to Thursday, 01 January, 1970. - ----------------------------------------------------------------------------------------------- --- 20.4.1.7 LocalTZA ( t, isUTC ) ??? ----------------------------------------------------------------------------------------------- --- https://tc39.es/ecma262/#sec-local-time-zone-adjustment --- returns the local time zone adjustment, or offset, in milliseconds --- LocalTZA( t :: UTC, true ) = should return the offset of the local time zone from UTC measured in milliseconds --- at time represented by time value t :: UTC. When the result is added to t :: UTC, it should yield --- the corresponding Number t :: local. --- LocalTZA( t :: local, false ) = should return the offset of the local time zone from UTC measured in --- milliseconds at local time represented by Number tlocal. --- When the result is subtracted from t :: local, it should yield the corresponding --- time value t :: UTC. - ----------------------------------------------------------------------------------------------- --- 20.4.1.8 LocalTime ( t ) ----------------------------------------------------------------------------------------------- --- Return t + LocalTZA(t, true) - ----------------------------------------------------------------------------------------------- --- 20.4.1.9 UTC ( t ) ----------------------------------------------------------------------------------------------- --- Return t - LocalTZA(t, false). - ----------------------------------------------------------------------------------------------- --- 20.4.1.10 Hours, Minutes, Second, and Milliseconds ----------------------------------------------------------------------------------------------- --- HourFromTime(t) = floor(t / msPerHour) modulo HoursPerDay --- MinFromTime(t) = floor(t / msPerMinute) modulo MinutesPerHour --- SecFromTime(t) = floor(t / msPerSecond) modulo SecondsPerMinute --- msFromTime(t) = t modulo msPerSecond --- --- HoursPerDay = 24 --- MinutesPerHour = 60 --- SecondsPerMinute = 60 --- msPerSecond = 1000 --- msPerMinute = 60000 = msPerSecond × SecondsPerMinute --- msPerHour = 3600000 = msPerMinute × MinutesPerHour - ----------------------------------------------------------------------------------------------- --- 20.4.1.11 MakeTime ( hour, min, sec, ms ) ----------------------------------------------------------------------------------------------- --- If hour is not finite or min is not finite or sec is not finite or ms is not finite, return NaN. --- h = ! ToInteger(hour). --- m = ! ToInteger(min). --- s = ! ToInteger(sec). --- milli = ! ToInteger(ms). --- t = h * msPerHour + m * msPerMinute + s * msPerSecond + milli --- (performing the arithmetic according to IEEE 754-2019 rules (that is, as if using the ECMAScript operators * and +)) --- Return t. - ----------------------------------------------------------------------------------------------- --- 20.4.1.12 MakeDay ( year, month, date ) ----------------------------------------------------------------------------------------------- --- If year is not finite or month is not finite or date is not finite, return NaN. --- y = ! ToInteger(year). --- m = ! ToInteger(month). --- dt = ! ToInteger(date). --- ym = y + floor(m / 12). --- mn = m modulo 12. --- Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn and DateFromTime(t) is 1; --- but if this is not possible (because some argument is out of range), return NaN. --- Return Day(t) + dt - 1. - ----------------------------------------------------------------------------------------------- --- 20.4.1.13 MakeDate ( day, time ) ----------------------------------------------------------------------------------------------- --- If day is not finite or time is not finite, return NaN. --- Return day × msPerDay + time. - ----------------------------------------------------------------------------------------------- --- 20.4.1.14 TimeClip ( time ) ----------------------------------------------------------------------------------------------- --- If time is not finite, return NaN. --- If abs(time) > 8.64 × 10^15, return NaN. --- Return ! ToInteger(time). - ----------------------------------------------------------------------------------------------- --- 20.4.1.15 Date Time String Format ----------------------------------------------------------------------------------------------- --- YYYY-MM-DDTHH:mm:ss.sssZ --- ISO 8601 calendar date extended format. - ----------------------------------------------------------------------------------------------- --- 20.4.1.15.1 Expanded Years ----------------------------------------------------------------------------------------------- - ----------------------------------------------------------------------------------------------- --- 20.4.2.1 Date ( year, month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ) ----------------------------------------------------------------------------------------------- --- If NewTarget is undefined, then --- Let `now` be the Number that is the time value (UTC) identifying the current time. --- Return ToDateString(now). --- Else --- y = ToNumber(year). --- m = ToNumber(month). --- If date is present, let dt be ? ToNumber(date); else let dt be 1. --- If hours is present, let h be ? ToNumber(hours); else let h be 0. --- If minutes is present, let min be ? ToNumber(minutes); else let min be 0. --- If seconds is present, let s be ? ToNumber(seconds); else let s be 0. --- If ms is present, let milli be ? ToNumber(ms); else let milli be 0. --- If y is NaN, let yr be NaN. --- Else, --- Let yi be ! ToInteger(y). --- If 0 ≤ yi ≤ 99, let yr be 1900 + yi; otherwise, let yr be y. --- finalDate = MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)). --- O = OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »). --- Set O.[[DateValue]] to TimeClip(UTC(finalDate)). --- Return O. - ----------------------------------------------------------------------------------------------- --- 20.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ) ----------------------------------------------------------------------------------------------- --- y = ToNumber(year). --- If month is present then m = ToNumber(month); else m = 0. --- If date is present, then dt = ToNumber(date); else dt = 1. --- If hours is present, then h = ToNumber(hours); else h = 0. --- If minutes is present, then min = ToNumber(minutes); min = 0. --- If seconds is present, then s = ToNumber(seconds); else s = 0. --- If ms is present, then milli = ToNumber(ms); else milli = 0. --- If y is NaN, let yr be NaN. --- Else, --- Let yi be ! ToInteger(y). --- If 0 ≤ yi ≤ 99, --- then yr = 1900 + yi; --- otherwise, yr = y. --- Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))). - ----------------------------------------------------------------------------------------------- --- 20.4.4.2 getDate ( ) ----------------------------------------------------------------------------------------------- --- t = thisTimeValue(this value). --- If t is NaN, return NaN. --- Return DateFromTime(LocalTime(t)). - ----------------------------------------------------------------------------------------------- --- 20.4.4.3 getDay ( ) ----------------------------------------------------------------------------------------------- --- Return WeekDay(LocalTime(t)). - ----------------------------------------------------------------------------------------------- --- 20.4.4.4 getFullYear ( ) ----------------------------------------------------------------------------------------------- --- Return YearFromTime(LocalTime(t)). - ----------------------------------------------------------------------------------------------- --- 20.4.4.5 getHours ( ) ----------------------------------------------------------------------------------------------- --- Return HourFromTime(LocalTime(t)). - ----------------------------------------------------------------------------------------------- --- 20.4.4.6 getMilliseconds ( ) ----------------------------------------------------------------------------------------------- --- Return msFromTime(LocalTime(t)). - ----------------------------------------------------------------------------------------------- --- 20.4.4.7 getMinutes ( ) ----------------------------------------------------------------------------------------------- --- Return MinFromTime(LocalTime(t)) - ----------------------------------------------------------------------------------------------- --- 20.4.4.7 getMonth ( ) ----------------------------------------------------------------------------------------------- --- Return MonthFromTime(LocalTime(t)) - ----------------------------------------------------------------------------------------------- --- 20.4.4.9 getSeconds ( ) ----------------------------------------------------------------------------------------------- --- Return SecFromTime(LocalTime(t)). - ----------------------------------------------------------------------------------------------- --- 20.4.4.10 getTime ( ) ----------------------------------------------------------------------------------------------- --- Return ? thisTimeValue(this value). - ----------------------------------------------------------------------------------------------- --- 20.4.4.11 getTimezoneOffset ( ) ----------------------------------------------------------------------------------------------- --- Return (t - LocalTime(t)) / msPerMinute. - ----------------------------------------------------------------------------------------------- --- 20.4.4.12 getUTCDate ( ) ----------------------------------------------------------------------------------------------- --- Return DateFromTime(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.13 getUTCDay ( ) ----------------------------------------------------------------------------------------------- --- Return WeekDay(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.14 getUTCFullYear ( ) ----------------------------------------------------------------------------------------------- --- Return YearFromTime(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.15 getUTCHours ( ) ----------------------------------------------------------------------------------------------- --- Return HourFromTime(t) - ----------------------------------------------------------------------------------------------- --- 20.4.4.16 getUTCMilliseconds ( ) ----------------------------------------------------------------------------------------------- --- Return msFromTime(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.17 getUTCMinutes ( ) ----------------------------------------------------------------------------------------------- --- Return MinFromTime(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.18 getUTCMonth ( ) ----------------------------------------------------------------------------------------------- --- Return MonthFromTime(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.19 getUTCSeconds ( ) ----------------------------------------------------------------------------------------------- --- Return SecFromTime(t). - ----------------------------------------------------------------------------------------------- --- 20.4.4.20 setDate ( date ) ----------------------------------------------------------------------------------------------- --- t = LocalTime(thisTimeValue(this value)). --- dt = ToNumber(date). --- newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)). --- u = TimeClip(UTC(newDate)). --- Set the [[DateValue]] internal slot of this Date object to u. --- Return u. - ----------------------------------------------------------------------------------------------- --- 20.4.4.21 setFullYear ( year [ , month [ , date ] ] ) ----------------------------------------------------------------------------------------------- --- t = thisTimeValue(this value). --- If t is NaN, set t to +0; otherwise, set t to LocalTime(t). --- y = ToNumber(year). --- If month is not present, m = MonthFromTime(t); otherwise, m = ToNumber(month). --- If date is not present, dt = DateFromTime(t); otherwise, dt = ToNumber(date). --- newDate = MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)). --- u = TimeClip(UTC(newDate)). --- Set the [[DateValue]] internal slot of this Date object to u. --- Return u. - ----------------------------------------------------------------------------------------------- --- 20.4.4.22 setHours ( hour [ , min [ , sec [ , ms ] ] ] ) ----------------------------------------------------------------------------------------------- --- t = LocalTime(thisTimeValue(this value)). --- h = ToNumber(hour). --- If min is not present, m = MinFromTime(t); otherwise, m = ToNumber(min). --- If sec is not present, s = SecFromTime(t); otherwise, s = ToNumber(sec). --- If ms is not present, milli = msFromTime(t); otherwise, milli = ToNumber(ms). --- date = MakeDate(Day(t), MakeTime(h, m, s, milli)). --- u = TimeClip(UTC(date)). --- Set the [[DateValue]] internal slot of this Date object to u. --- Return u. - --- got bored can refer to them if implementing functions !! - main :: Effect Unit main = do durationTests diff --git a/test/Test/Spec.md b/test/Test/Spec.md new file mode 100644 index 0000000..c8aeba0 --- /dev/null +++ b/test/Test/Spec.md @@ -0,0 +1,334 @@ +-------------------------------------------------------------------------------------------- + 20.4.1.2 Day Number and Time within Day +-------------------------------------------------------------------------------------------- + Day(t) = floor(t / msPerDay) + msPerDay = 86400000 + + The remainder is called the time within the day: + TimeWithinDay(t) = t modulo msPerDay + +-------------------------------------------------------------------------------------------- + 20.4.1.3 Year Number +-------------------------------------------------------------------------------------------- + DaysInYear(y) + = 365 if (y modulo 4) ≠ 0 + = 366 if (y modulo 4) = 0 and (y modulo 100) ≠ 0 + = 365 if (y modulo 100) = 0 and (y modulo 400) ≠ 0 + = 366 if (y modulo 400) = 0 + + All non-leap years have 365 days with the usual number of days per month and leap years have an extra day in February. + The day number of the first day of year y is given by: + DayFromYear(y) = 365 × (y - 1970) + floor((y - 1969) / 4) - floor((y - 1901) / 100) + floor((y - 1601) / 400) + + The time value of the start of a year is: + TimeFromYear(y) = msPerDay × DayFromYear(y) + YearFromTime(t) = the largest integer y (closest to positive infinity) such that TimeFromYear(y) ≤ t + + InLeapYear(t) + = 0 if DaysInYear(YearFromTime(t)) = 365 + = 1 if DaysInYear(YearFromTime(t)) = 366 + + MonthFromTime(t) + = 0 if 0 ≤ DayWithinYear(t) < 31 + = 1 if 31 ≤ DayWithinYear(t) < 59 + InLeapYear(t) + = 2 if 59 + InLeapYear(t) ≤ DayWithinYear(t) < 90 + InLeapYear(t) + = 3 if 90 + InLeapYear(t) ≤ DayWithinYear(t) < 120 + InLeapYear(t) + = 4 if 120 + InLeapYear(t) ≤ DayWithinYear(t) < 151 + InLeapYear(t) + = 5 if 151 + InLeapYear(t) ≤ DayWithinYear(t) < 181 + InLeapYear(t) + = 6 if 181 + InLeapYear(t) ≤ DayWithinYear(t) < 212 + InLeapYear(t) + = 7 if 212 + InLeapYear(t) ≤ DayWithinYear(t) < 243 + InLeapYear(t) + = 8 if 243 + InLeapYear(t) ≤ DayWithinYear(t) < 273 + InLeapYear(t) + = 9 if 273 + InLeapYear(t) ≤ DayWithinYear(t) < 304 + InLeapYear(t) + = 10 if 304 + InLeapYear(t) ≤ DayWithinYear(t) < 334 + InLeapYear(t) + = 11 if 334 + InLeapYear(t) ≤ DayWithinYear(t) < 365 + InLeapYear(t) + + DayWithinYear(t) = Day(t) - DayFromYear(YearFromTime(t)) + Note that MonthFromTime(0) = 0, corresponding to Thursday, 01 January, 1970. + +-------------------------------------------------------------------------------------------- + 20.4.1.5 Date Number +-------------------------------------------------------------------------------------------- + DateFromTime(t) + = DayWithinYear(t) + 1 if MonthFromTime(t) = 0 + = DayWithinYear(t) - 30 if MonthFromTime(t) = 1 + = DayWithinYear(t) - 58 - InLeapYear(t) if MonthFromTime(t) = 2 + = DayWithinYear(t) - 89 - InLeapYear(t) if MonthFromTime(t) = 3 + = DayWithinYear(t) - 119 - InLeapYear(t) if MonthFromTime(t) = 4 + = DayWithinYear(t) - 150 - InLeapYear(t) if MonthFromTime(t) = 5 + = DayWithinYear(t) - 180 - InLeapYear(t) if MonthFromTime(t) = 6 + = DayWithinYear(t) - 211 - InLeapYear(t) if MonthFromTime(t) = 7 + = DayWithinYear(t) - 242 - InLeapYear(t) if MonthFromTime(t) = 8 + = DayWithinYear(t) - 272 - InLeapYear(t) if MonthFromTime(t) = 9 + = DayWithinYear(t) - 303 - InLeapYear(t) if MonthFromTime(t) = 10 + = DayWithinYear(t) - 333 - InLeapYear(t) if MonthFromTime(t) = 11 + +-------------------------------------------------------------------------------------------- + 20.4.1.6 Week Day +-------------------------------------------------------------------------------------------- + WeekDay(t) = (Day(t) + 4) modulo 7 + A weekday value of + 0 specifies Sunday; + 1 specifies Monday; + 2 specifies Tuesday; + 3 specifies Wednesday; + 4 specifies Thursday; + 5 specifies Friday; + 6 specifies Saturday. + Note that WeekDay(0) = 4, corresponding to Thursday, 01 January, 1970. + +-------------------------------------------------------------------------------------------- + 20.4.1.7 LocalTZA ( t, isUTC ) ??? +-------------------------------------------------------------------------------------------- + https://tc39.es/ecma262/#sec-local-time-zone-adjustment + returns the local time zone adjustment, or offset, in milliseconds + LocalTZA( t :: UTC, true ) = should return the offset of the local time zone from UTC measured in milliseconds + at time represented by time value t :: UTC. When the result is added to t :: UTC, it should yield + the corresponding Number t :: local. + LocalTZA( t :: local, false ) = should return the offset of the local time zone from UTC measured in + milliseconds at local time represented by Number tlocal. + When the result is subtracted from t :: local, it should yield the corresponding + time value t :: UTC. + +-------------------------------------------------------------------------------------------- + 20.4.1.8 LocalTime ( t ) +-------------------------------------------------------------------------------------------- + Return t + LocalTZA(t, true) + +-------------------------------------------------------------------------------------------- + 20.4.1.9 UTC ( t ) +-------------------------------------------------------------------------------------------- + Return t - LocalTZA(t, false). + +-------------------------------------------------------------------------------------------- + 20.4.1.10 Hours, Minutes, Second, and Milliseconds +-------------------------------------------------------------------------------------------- + HourFromTime(t) = floor(t / msPerHour) modulo HoursPerDay + MinFromTime(t) = floor(t / msPerMinute) modulo MinutesPerHour + SecFromTime(t) = floor(t / msPerSecond) modulo SecondsPerMinute + msFromTime(t) = t modulo msPerSecond + + HoursPerDay = 24 + MinutesPerHour = 60 + SecondsPerMinute = 60 + msPerSecond = 1000 + msPerMinute = 60000 = msPerSecond × SecondsPerMinute + msPerHour = 3600000 = msPerMinute × MinutesPerHour + +-------------------------------------------------------------------------------------------- + 20.4.1.11 MakeTime ( hour, min, sec, ms ) +-------------------------------------------------------------------------------------------- + If hour is not finite or min is not finite or sec is not finite or ms is not finite, return NaN. + h = ! ToInteger(hour). + m = ! ToInteger(min). + s = ! ToInteger(sec). + milli = ! ToInteger(ms). + t = h * msPerHour + m * msPerMinute + s * msPerSecond + milli + (performing the arithmetic according to IEEE 754-2019 rules (that is, as if using the ECMAScript operators * and +)) + Return t. + +-------------------------------------------------------------------------------------------- + 20.4.1.12 MakeDay ( year, month, date ) +-------------------------------------------------------------------------------------------- + If year is not finite or month is not finite or date is not finite, return NaN. + y = ! ToInteger(year). + m = ! ToInteger(month). + dt = ! ToInteger(date). + ym = y + floor(m / 12). + mn = m modulo 12. + Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn and DateFromTime(t) is 1; + but if this is not possible (because some argument is out of range), return NaN. + Return Day(t) + dt - 1. + +-------------------------------------------------------------------------------------------- + 20.4.1.13 MakeDate ( day, time ) +-------------------------------------------------------------------------------------------- + If day is not finite or time is not finite, return NaN. + Return day × msPerDay + time. + +-------------------------------------------------------------------------------------------- + 20.4.1.14 TimeClip ( time ) +-------------------------------------------------------------------------------------------- + If time is not finite, return NaN. + If abs(time) > 8.64 × 10^15, return NaN. + Return ! ToInteger(time). + +-------------------------------------------------------------------------------------------- + 20.4.1.15 Date Time String Format +-------------------------------------------------------------------------------------------- + YYYY-MM-DDTHH:mm:ss.sssZ + ISO 8601 calendar date extended format. + +-------------------------------------------------------------------------------------------- + 20.4.1.15.1 Expanded Years +-------------------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------------------- + 20.4.2.1 Date ( year, month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ) +-------------------------------------------------------------------------------------------- + If NewTarget is undefined, then + Let `now` be the Number that is the time value (UTC) identifying the current time. + Return ToDateString(now). + Else + y = ToNumber(year). + m = ToNumber(month). + If date is present, let dt be ? ToNumber(date); else let dt be 1. + If hours is present, let h be ? ToNumber(hours); else let h be 0. + If minutes is present, let min be ? ToNumber(minutes); else let min be 0. + If seconds is present, let s be ? ToNumber(seconds); else let s be 0. + If ms is present, let milli be ? ToNumber(ms); else let milli be 0. + If y is NaN, let yr be NaN. + Else, + Let yi be ! ToInteger(y). + If 0 ≤ yi ≤ 99, let yr be 1900 + yi; otherwise, let yr be y. + finalDate = MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)). + O = OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »). + Set O.[[DateValue]] to TimeClip(UTC(finalDate)). + Return O. + +-------------------------------------------------------------------------------------------- + 20.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ) +-------------------------------------------------------------------------------------------- + y = ToNumber(year). + If month is present then m = ToNumber(month); else m = 0. + If date is present, then dt = ToNumber(date); else dt = 1. + If hours is present, then h = ToNumber(hours); else h = 0. + If minutes is present, then min = ToNumber(minutes); min = 0. + If seconds is present, then s = ToNumber(seconds); else s = 0. + If ms is present, then milli = ToNumber(ms); else milli = 0. + If y is NaN, let yr be NaN. + Else, + Let yi be ! ToInteger(y). + If 0 ≤ yi ≤ 99, + then yr = 1900 + yi; + otherwise, yr = y. + Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))). + +-------------------------------------------------------------------------------------------- + 20.4.4.2 getDate ( ) +-------------------------------------------------------------------------------------------- + t = thisTimeValue(this value). + If t is NaN, return NaN. + Return DateFromTime(LocalTime(t)). + +-------------------------------------------------------------------------------------------- + 20.4.4.3 getDay ( ) +-------------------------------------------------------------------------------------------- + Return WeekDay(LocalTime(t)). + +-------------------------------------------------------------------------------------------- + 20.4.4.4 getFullYear ( ) +-------------------------------------------------------------------------------------------- + Return YearFromTime(LocalTime(t)). + +-------------------------------------------------------------------------------------------- + 20.4.4.5 getHours ( ) +-------------------------------------------------------------------------------------------- + Return HourFromTime(LocalTime(t)). + +-------------------------------------------------------------------------------------------- + 20.4.4.6 getMilliseconds ( ) +-------------------------------------------------------------------------------------------- + Return msFromTime(LocalTime(t)). + +-------------------------------------------------------------------------------------------- + 20.4.4.7 getMinutes ( ) +-------------------------------------------------------------------------------------------- + Return MinFromTime(LocalTime(t)) + +-------------------------------------------------------------------------------------------- + 20.4.4.7 getMonth ( ) +-------------------------------------------------------------------------------------------- + Return MonthFromTime(LocalTime(t)) + +-------------------------------------------------------------------------------------------- + 20.4.4.9 getSeconds ( ) +-------------------------------------------------------------------------------------------- + Return SecFromTime(LocalTime(t)). + +-------------------------------------------------------------------------------------------- + 20.4.4.10 getTime ( ) +-------------------------------------------------------------------------------------------- + Return ? thisTimeValue(this value). + +-------------------------------------------------------------------------------------------- + 20.4.4.11 getTimezoneOffset ( ) +-------------------------------------------------------------------------------------------- + Return (t - LocalTime(t)) / msPerMinute. + +-------------------------------------------------------------------------------------------- + 20.4.4.12 getUTCDate ( ) +-------------------------------------------------------------------------------------------- + Return DateFromTime(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.13 getUTCDay ( ) +-------------------------------------------------------------------------------------------- + Return WeekDay(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.14 getUTCFullYear ( ) +-------------------------------------------------------------------------------------------- + Return YearFromTime(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.15 getUTCHours ( ) +-------------------------------------------------------------------------------------------- + Return HourFromTime(t) + +-------------------------------------------------------------------------------------------- + 20.4.4.16 getUTCMilliseconds ( ) +-------------------------------------------------------------------------------------------- + Return msFromTime(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.17 getUTCMinutes ( ) +-------------------------------------------------------------------------------------------- + Return MinFromTime(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.18 getUTCMonth ( ) +-------------------------------------------------------------------------------------------- + Return MonthFromTime(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.19 getUTCSeconds ( ) +-------------------------------------------------------------------------------------------- + Return SecFromTime(t). + +-------------------------------------------------------------------------------------------- + 20.4.4.20 setDate ( date ) +-------------------------------------------------------------------------------------------- + t = LocalTime(thisTimeValue(this value)). + dt = ToNumber(date). + newDate = MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)). + u = TimeClip(UTC(newDate)). + Set the [[DateValue]] internal slot of this Date object to u. + Return u. + +-------------------------------------------------------------------------------------------- + 20.4.4.21 setFullYear ( year [ , month [ , date ] ] ) +-------------------------------------------------------------------------------------------- + t = thisTimeValue(this value). + If t is NaN, set t to +0; otherwise, set t to LocalTime(t). + y = ToNumber(year). + If month is not present, m = MonthFromTime(t); otherwise, m = ToNumber(month). + If date is not present, dt = DateFromTime(t); otherwise, dt = ToNumber(date). + newDate = MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)). + u = TimeClip(UTC(newDate)). + Set the [[DateValue]] internal slot of this Date object to u. + Return u. + +-------------------------------------------------------------------------------------------- + 20.4.4.22 setHours ( hour [ , min [ , sec [ , ms ] ] ] ) +-------------------------------------------------------------------------------------------- + t = LocalTime(thisTimeValue(this value)). + h = ToNumber(hour). + If min is not present, m = MinFromTime(t); otherwise, m = ToNumber(min). + If sec is not present, s = SecFromTime(t); otherwise, s = ToNumber(sec). + If ms is not present, milli = msFromTime(t); otherwise, milli = ToNumber(ms). + date = MakeDate(Day(t), MakeTime(h, m, s, milli)). + u = TimeClip(UTC(date)). + Set the [[DateValue]] internal slot of this Date object to u. + Return u. + + got bored can refer to them if implementing functions !!