Adding DateTime part functions (#3669)

- Added `Zone`, `Date_Time` and `Time_Of_Day` to `Standard.Base`.
- Renamed `Zone` to `Time_Zone`.
- Added `century`.
- Added `is_leap_year`.
- Added `length_of_year`.
- Added `length_of_month`.
- Added `quarter`.
- Added `day_of_year`.
- Added `Day_Of_Week` type and `day_of_week` function.
- Updated `week_of_year` to support ISO.

# Important Notes
- Had to pass locale to formatter for date/time tests to work on my PC.
- Changed default of `week_of_year` to use ISO.
This commit is contained in:
James Dunkerley 2022-08-26 16:47:58 +01:00 committed by GitHub
parent fd318cfa96
commit a20d43390e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 635 additions and 360 deletions

View File

@ -59,7 +59,7 @@
"zombie" state, where processes were started but not visible to user. They
could cause issues with starting further IDE instances.
- [New nodes are created in the project source when the searcher is opened
and a new node is created.][5250]
and a new node is created.][3645]
#### EnsoGL (rendering engine)
@ -185,6 +185,7 @@
- [Expanded `Table.at` to support index access and added `Table.column_count`
method.][3644]
- [Removed `Array.set_at`.][3634]
- [Added various date part functions to `Date` and `Date_Time`.][3669]
[debug-shortcuts]:
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
@ -287,11 +288,13 @@
[3617]: https://github.com/enso-org/enso/pull/3617
[3628]: https://github.com/enso-org/enso/pull/3628
[3629]: https://github.com/enso-org/enso/pull/3629
[3641]: https://github.com/enso-org/enso/pull/3641
[3643]: https://github.com/enso-org/enso/pull/3643
[3644]: https://github.com/enso-org/enso/pull/3644
[3645]: https://github.com/enso-org/enso/pull/3645
[3648]: https://github.com/enso-org/enso/pull/3648
[5250]: https://github.com/enso-org/enso/pull/5250
[3634]: https://github.com/enso-org/enso/pull/3634
[3669]: https://github.com/enso-org/enso/pull/3669
#### Enso Compiler

View File

@ -1,9 +0,0 @@
type Time_Error
## UNSTABLE
An error produced while working with time- and date-related methods.
Arguments:
- error_message: The message for the error.
type Time_Error error_message

View File

@ -1,13 +1,13 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
import Standard.Base.Polyglot
from Standard.Base.Error.Common import Time_Error
polyglot java import org.enso.base.Time_Utils
polyglot java import java.time.temporal.ChronoField
polyglot java import java.time.temporal.IsoFields
## Obtains the current date from the system clock in the system timezone.
@ -41,7 +41,7 @@ today = now
> Example
Create a new local date at Unix epoch.
import Standard.Base.Data.Time.Date
from Standard.Base import Date
example_new = Date.new 1970
@ -50,7 +50,7 @@ today = now
example_new = Date.new 1986 8 5
new : Integer -> Integer -> Integer -> Date ! Time.Time_Error
new : Integer -> Integer -> Integer -> Date ! Time_Error
new year (month = 1) (day = 1) =
## TODO This is left using the old error handling approach, because
magically, changing this to the `catch_java` (which is now preferred way
@ -60,7 +60,7 @@ new year (month = 1) (day = 1) =
https://github.com/enso-org/enso/pull/3559
Then this should be switched to use `Panic.catch_java`.
Panic.recover Any (Date.internal_new year month day) . catch Any e-> case e of
Polyglot_Error err -> Error.throw (Time.Time_Error err.getMessage)
Polyglot_Error err -> Error.throw (Time_Error err.getMessage)
ex -> ex
## ALIAS Date from Text
@ -96,41 +96,43 @@ new year (month = 1) (day = 1) =
> Example
Parse the date of 23rd December 2020.
import Standard.Base.Data.Time.Date
from Standard.Base import Date
example_parse = Date.parse "2020-12-23"
> Example
Recover from an error due to a wrong format.
import Standard.Base.Data.Time
from Standard.Base import Date
from Standard.Base.Error.Common import Time_Error
example_parse_err = Date.parse "my birthday" . catch Time.Time_Error _->
example_parse_err = Date.parse "my birthday" . catch Time_Error _->
Date.new 2000 1 1
> Example
Parse "1999-1-1" as Date using a custom format.
import Standard.Base.Data.Time.Date
from Standard.Base import Date
example_parse = Date.parse "1999-1-1" "yyyy-M-d"
> Example
Recover from the parse error.
import Standard.base.Data.Time
from Standard.Base import Date
from Standard.Base.Error.Common import Time_Error
example_parse_err =
date = Date.parse "1999-1-1" "yyyy-MM-dd"
date.catch Time.Time_Error (_->Date.new 2000 1 1)
parse : Text -> (Text | Nothing) -> Date ! Time.Time_Error
date.catch Time_Error (_->Date.new 2000 1 1)
parse : Text -> (Text | Nothing) -> Date ! Time_Error
parse text pattern=Nothing =
result = Panic.recover Any <| case pattern of
Nothing -> Date.internal_parse text 0
Text -> Date.internal_parse text pattern
_ -> Panic.throw (Time.Time_Error "An invalid pattern was provided.")
_ -> Panic.throw (Time_Error "An invalid pattern was provided.")
result . map_error <| case _ of
Polyglot_Error err -> Time.Time_Error err.getMessage
Polyglot_Error err -> Time_Error err.getMessage
ex -> ex
type Date
@ -154,7 +156,7 @@ type Date
> Example
Get the current year.
import Standard.Base.Data.Time.Date
from Standard.Base import Date
example_year = Date.now.year
year : Integer
@ -174,7 +176,7 @@ type Date
> Example
Get the current day.
import Standard.Base.Data.Time.Date
from Standard.Base import Date
example_day = Date.now.day
day : Integer
@ -184,6 +186,7 @@ type Date
Arguments:
- locale: the locale used to define the notion of weeks of year.
If no locale is provided, then the ISO 8601 week of year is used.
! Locale Dependency
Note that this operation is locale-specific. It varies both by the
@ -193,8 +196,40 @@ type Date
other hand, the first day of the week is Monday, and week 1 is the week
containing the first Thursday of the year. Therefore it is important to
properly specify the `locale` argument.
week_of_year : Locale.Locale -> Integer
week_of_year self locale=Locale.default = Time_Utils.week_of_year_localdate self locale.java_locale
week_of_year : (Locale.Locale | Nothing) -> Integer
week_of_year self locale=Nothing =
if locale.is_nothing then Time_Utils.get_field_as_localdate self IsoFields.WEEK_OF_WEEK_BASED_YEAR else
Time_Utils.week_of_year_localdate self locale.java_locale
## Returns if the date is in a leap year.
is_leap_year : Boolean
is_leap_year self = Time_Utils.is_leap_year self
## Returns the number of days in the year represented by this date.
length_of_year : Integer
length_of_year self = if self.is_leap_year then 366 else 365
## Returns the century of the date.
century : Integer
century self = if self.year > 0 then (self.year - 1).div 100 + 1 else
Error.throw (Illegal_Argument_Error "Century can only be given for AD years.")
## Returns the quarter of the year the date falls into.
quarter : Integer
quarter self = Time_Utils.get_field_as_localdate self IsoFields.QUARTER_OF_YEAR
## Returns the number of days in the month represented by this date.
length_of_month : Integer
length_of_month self = Time_Utils.length_of_month self
## Returns the day of the year.
day_of_year : Integer
day_of_year self = Time_Utils.get_field_as_localdate self ChronoField.DAY_OF_YEAR
## Returns the day of the week.
day_of_week : Day_Of_Week
day_of_week self =
Day_Of_Week.from (Time_Utils.get_field_as_localdate self ChronoField.DAY_OF_WEEK) Day_Of_Week.Monday
## ALIAS Date to Time
@ -207,12 +242,11 @@ type Date
> Example
Convert this date to midnight UTC time.
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
from Standard.Base import Date, Time_Of_Day, Time_Zone
example_to_time = Date.new 2020 2 3 . to_time Time_Of_Day.new Zone.utc
to_time : Time_Of_Day -> Zone -> Date_Time
to_time self time_of_day (zone=Zone.system) = self.to_time_builtin time_of_day zone
example_to_time = Date.new 2020 2 3 . to_time Time_Of_Day.new Time_Zone.utc
to_time : Time_Of_Day -> Time_Zone -> Date_Time
to_time self time_of_day (zone=Time_Zone.system) = self.to_time_builtin time_of_day zone
## Add the specified amount of time to this instant to get another date.
@ -226,7 +260,7 @@ type Date
example_add = Date.new 2020 + 6.months
+ : Duration -> Date
+ self amount = if amount.is_time then Error.throw (Time.Time_Error "Date does not support time intervals") else
+ self amount = if amount.is_time then Error.throw (Time_Error "Date does not support time intervals") else
(Time_Utils.date_adjust self Time_Utils.AdjustOp.PLUS amount.internal_period) . internal_local_date
## Subtract the specified amount of time from this instant to get another
@ -238,12 +272,12 @@ type Date
> Example
Subtract 7 days from a local date.
import Standard.Base.Data.Time.Date
from Standard.Base import Date
import Standard.Base.Data.Time.Duration
example_subtract = Date.new 2020 - 7.days
- : Duration -> Date
- self amount = if amount.is_time then Error.throw (Time.Time_Error "Date does not support time intervals") else
- self amount = if amount.is_time then Error.throw (Time_Error "Date does not support time intervals") else
(Time_Utils.date_adjust self Time_Utils.AdjustOp.MINUS amount.internal_period) . internal_local_date
@ -268,7 +302,7 @@ type Date
> Example
Format "2020-06-02" as "2 June 2020"
import Standard.Base.Data.Time.Date
from Standard.Base import Date
example_format = Date.new 2020 6 2 . format "d MMMM yyyy"

View File

@ -1,12 +1,12 @@
from Standard.Base import all
from Standard.Base.Data.Time import Time_Error
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
from Standard.Base.Error.Common import Time_Error
polyglot java import java.time.format.DateTimeFormatter
polyglot java import java.time.ZonedDateTime
polyglot java import java.time.temporal.ChronoField
polyglot java import java.time.temporal.IsoFields
polyglot java import org.enso.base.Time_Utils
## ALIAS Current Time
@ -16,7 +16,7 @@ polyglot java import org.enso.base.Time_Utils
> Example
Get the current time
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_now = Date_Time.now
now : Date_Time
@ -40,20 +40,18 @@ now = @Builtin_Method "Date_Time.now"
> Example
Create a new zoned date time at Unix epoch.
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Zone
from Standard.Base import Date_Time, Time_Zone
example_new = Date_Time.new 1970 (zone = Zone.utc)
example_new = Date_Time.new 1970 (zone = Time_Zone.utc)
> Example
Get the 5 August 1986 at midnight.
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Zone
from Standard.Base import Date_Time, Time_Zone
example_new = Date_Time.new 1986 8 5
new : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Zone -> Date_Time ! Time_Error
new year (month = 1) (day = 1) (hour = 0) (minute = 0) (second = 0) (nanosecond = 0) (zone = Zone.system) =
new : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Time_Zone -> Date_Time ! Time_Error
new year (month = 1) (day = 1) (hour = 0) (minute = 0) (second = 0) (nanosecond = 0) (zone = Time_Zone.system) =
Panic.catch_java Any (Date_Time.new_builtin year month day hour minute second nanosecond zone) java_exception->
Error.throw (Time_Error java_exception.getMessage)
@ -89,49 +87,49 @@ new year (month = 1) (day = 1) (hour = 0) (minute = 0) (second = 0) (nanosecond
> Example
Parse UTC time.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Date_Time.parse "2020-10-01T04:11:12Z"
> Example
Parse UTC-04:00 time.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Date_Time.parse "2020-10-01T04:11:12-04:00"
> Example
Parse UTC-04:00 time specifying New York timezone.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Date_Time.parse "2020-10-01T04:11:12-04:00[America/New_York]"
> Example
Parse UTC-04:00 time with nanoseconds.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Date_Time.parse "2020-10-01T04:11:12.177528-04:00"
> Example
Recover from the parse error.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Date_Time.parse "2020-10-01" . catch Time_Error (_->Date_Time.now)
> Example
Parse "2020-05-06 04:30:20" as Date_Time
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Date.parse "2020-05-06 04:30:20" "yyyy-MM-dd HH:mm:ss"
example_parse = Date_Time.parse "2020-05-06 04:30:20" "yyyy-MM-dd HH:mm:ss"
> Example
Parse "06 of May 2020 at 04:30AM" as Date_Tme
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse =
Date_Time.parse "06 of May 2020 at 04:30AM" "dd 'of' MMMM yyyy 'at' hh:mma"
@ -164,7 +162,7 @@ type Date_Time
> Example
Get the current year.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_year = Date_Time.now.year
year : Integer
@ -175,7 +173,7 @@ type Date_Time
> Example
Get the current month.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_month = Date_Time.now.month
month : Integer
@ -186,7 +184,7 @@ type Date_Time
> Example
Get the current day.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_day = Date_Time.now.day
day : Integer
@ -197,7 +195,7 @@ type Date_Time
> Example
Get the current hour.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_hour = Date_Time.now.hour
hour : Integer
@ -208,7 +206,7 @@ type Date_Time
> Example
Get the current minute.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_minute = Date_Time.now.minute
minute : Integer
@ -219,7 +217,7 @@ type Date_Time
> Example
Get the current second.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_second = Date_Time.now.second
second : Integer
@ -230,7 +228,7 @@ type Date_Time
> Example
Get the current nanosecond.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_nanosecond = Date_Time.now.nanosecond
nanosecond : Integer
@ -241,10 +239,10 @@ type Date_Time
> Example
Get the current timezone.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_zone = Date_Time.now.zone
zone : Zone
zone : Time_Zone
zone self = @Builtin_Method "Date_Time.zone"
## Return the number of seconds from the Unix epoch.
@ -252,7 +250,7 @@ type Date_Time
> Example
Get the current number of seconds from the Unix epoch.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_epoch = Date_Time.now.to_epoch_seconds
to_epoch_seconds : Integer
@ -263,7 +261,7 @@ type Date_Time
> Example
Get the current number of milliseconds from the unix epoch.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_epoch = Date_Time.now.to_epoch_milliseconds
to_epoch_milliseconds : Integer
@ -275,7 +273,7 @@ type Date_Time
> Example
Convert the current time to a time of day.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_time_of_day = Date_Time.now.time_of_day
time_of_day : Time_Of_Day
@ -285,6 +283,7 @@ type Date_Time
Arguments:
- locale: the locale used to define the notion of weeks of year.
If no locale is provided, then the ISO 8601 week of year is used.
! Locale Dependency
Note that this operation is locale-specific. It varies both by the
@ -294,8 +293,39 @@ type Date_Time
other hand, the first day of the week is Monday, and week 1 is the week
containing the first Thursday of the year. Therefore it is important to
properly specify the `locale` argument.
week_of_year : Locale.Locale -> Integer
week_of_year self locale=Locale.default = Time_Utils.week_of_year_zoneddatetime self locale.java_locale
week_of_year : (Locale.Locale | Nothing) -> Integer
week_of_year self locale=Nothing =
if locale.is_nothing then Time_Utils.get_field_as_zoneddatetime self IsoFields.WEEK_OF_WEEK_BASED_YEAR else
Time_Utils.week_of_year_zoneddatetime self locale.java_locale
## Returns if the date is in a leap year.
is_leap_year : Boolean
is_leap_year self = self.date.is_leap_year
## Returns the number of days in the year represented by this date.
length_of_year : Integer
length_of_year self = self.date.length_of_year
## Returns the century of the date.
century : Integer
century self = self.date.century
## Returns the quarter of the year the date falls into.
quarter : Integer
quarter self = Time_Utils.get_field_as_zoneddatetime self IsoFields.QUARTER_OF_YEAR
## Returns the number of days in the month represented by this date.
length_of_month : Integer
length_of_month self = self.date.length_of_month
## Returns the day of the year.
day_of_year : Integer
day_of_year self = Time_Utils.get_field_as_zoneddatetime self ChronoField.DAY_OF_YEAR
## Returns the day of the week.
day_of_week : Day_Of_Week
day_of_week self =
Day_Of_Week.from (Time_Utils.get_field_as_zoneddatetime self ChronoField.DAY_OF_WEEK) Day_Of_Week.Monday
## ALIAS Time to Date
@ -305,7 +335,7 @@ type Date_Time
> Example
Convert the current time to a date.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_date = Date_Time.now.date
date : Date
@ -321,11 +351,10 @@ type Date_Time
> Example
Convert time instance to -04:00 timezone.
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Zone
from Standard.Base import Date_Time, Time_Zone
example_at_zone = Date_Time.new 2020 . at_zone (Zone.new -4)
at_zone : Zone -> Date_Time
example_at_zone = Date_Time.new 2020 . at_zone (Time_Zone.new -4)
at_zone : Time_Zone -> Date_Time
at_zone self zone = @Builtin_Method "Date_Time.at_zone"
## Add the specified amount of time to this instant to produce a new instant.
@ -336,7 +365,7 @@ type Date_Time
> Example
Add 15 years and 3 hours to a zoned date time.
import Standard.Base.Data.Time.Date_Time
from Standard.Base import Date_Time
import Standard.Base.Data.Time.Duration
example_plus = Date_Time.new 2020 + 15.years + 3.hours
@ -353,7 +382,7 @@ type Date_Time
> Example
Subtract 1 year and 9 months from a zoned date time.
import Standard.Base.Data.Time.Date_Time
from Standard.Base import Date_Time
import Standard.Base.Data.Time.Duration
example_minus = Date_Time.new 2020 - 1.year - 9.months
@ -366,7 +395,7 @@ type Date_Time
> Example
Convert the current time to text.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_to_text = Date_Time.now.to_text
to_text : Text
@ -377,7 +406,7 @@ type Date_Time
> Example
Convert the current time to JSON.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_to_json = Date_Time.now.to_json
to_json : Json.Object
@ -438,7 +467,7 @@ type Date_Time
Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as
"2020-10-08T16:41:13+03:00[Europe/Moscow]".
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_format =
Date_Time.parse "2020-10-08T16:41:13+03:00[Europe/Moscow]" . format "yyyy-MM-dd'T'HH:mm:ssZZZZ'['VV']'"
@ -446,7 +475,7 @@ type Date_Time
> Example
Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as
"Thursday October 8 4:41 PM".
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_format =
Date_Time.parse "2020-10-08T16:41:13+03:00[Europe/Moscow]" . format "EEEE MMMM d h:mm a"
@ -455,7 +484,7 @@ type Date_Time
Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as
"Thu Oct 8 (16:41)".
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_format =
Date_Time.parse "2020-10-08T16:41:13+03:00[Europe/Moscow]" . format "EEE MMM d (HH:mm)"

View File

@ -0,0 +1,57 @@
from Standard.Base import all
type Day_Of_Week
type Sunday
type Monday
type Tuesday
type Wednesday
type Thursday
type Friday
type Saturday
## Convert the Day_Of_Week to an Integer
Arguments:
- `first_day`: The first day of the week.
- `start_at_zero`: If True, first day of the week is 0 otherwise is 1.
to_integer : Day_Of_Week -> Boolean -> Integer
to_integer self first_day=Sunday start_at_zero=False =
day_number = case self of
Sunday -> 0
Monday -> 1
Tuesday -> 2
Wednesday -> 3
Thursday -> 4
Friday -> 5
Saturday -> 6
shifted = if first_day == Day_Of_Week.Sunday then day_number else
(day_number + 7 - (first_day.to_integer start_at_zero=True)) % 7
shifted + if start_at_zero then 0 else 1
## Convert from an integer to a Day_Of_Week
Arguments:
- `that`: The first day of the week.
- `first_day`: The first day of the week.
- `start_at_zero`: If True, first day of the week is 0 otherwise is 1.
Day_Of_Week.from (that : Integer) (first_day:Day_Of_Week=Sunday) (start_at_zero:Boolean=False) =
shifted = if start_at_zero then that else that - 1
case (shifted < 0) || (shifted > 6) of
True ->
valid_range = if start_at_zero then "0-6" else "1-7"
message = "Invalid day of week (must be " + valid_range + ")."
Error.throw (Illegal_Argument_Error message)
False ->
day_number = if first_day == Day_Of_Week.Sunday then shifted else
(shifted + (first_day.to_integer start_at_zero=True)) % 7
[Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday].at day_number

View File

@ -1,6 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.System
polyglot java import java.time.Duration as Java_Duration
@ -17,8 +15,8 @@ polyglot java import org.enso.base.Time_Utils
> Example
An hour interval between two points in time.
from Standard.Base import Date_Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Date_Time
example_between = Duration.between Date_Time.now (Date_Time.new 2010 10 20)
between : Date_Time -> Date_Time -> Duration

View File

@ -1,8 +1,7 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Zone
from Standard.Base.Error.Common import Time_Error
polyglot java import java.time.format.DateTimeFormatter
polyglot java import java.time.Instant
@ -14,7 +13,7 @@ polyglot java import org.enso.base.Time_Utils
> Example
Get the current time in the default time zone.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_now = Time_Of_Day.now
now : Time_Of_Day
@ -34,20 +33,20 @@ now = @Builtin_Method "Time_Of_Day.now"
> Example
Create a new local time at Unix epoch.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_epoch = Time_Of_Day.new
> Example
Get the local time at 9:30.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_epoch = Time_Of_Day.new hour=9 minute=30
new : Integer -> Integer -> Integer -> Integer -> Time_Of_Day ! Time.Time_Error
new : Integer -> Integer -> Integer -> Integer -> Time_Of_Day ! Time_Error
new (hour = 0) (minute = 0) (second = 0) (nanosecond = 0) =
Panic.catch_java Any (Time_Of_Day.new_builtin hour minute second nanosecond) java_exception->
Error.throw (Time.Time_Error java_exception.getMessage)
Error.throw (Time_Error java_exception.getMessage)
## Obtains an instance of `Time_Of_Day` from a text such as "10:15".
@ -84,35 +83,35 @@ new (hour = 0) (minute = 0) (second = 0) (nanosecond = 0) =
> Example
Get the time 15:05:30.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_parse = Time_Of_Day.parse "15:05:30"
> Example
Recover from the parse error.
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
from Standard.Base.Error.Common import Time_Error
example_parse = Time_Of_Day.parse "half twelve" . catch Time.Time_Error _->
example_parse = Time_Of_Day.parse "half twelve" . catch Time_Error _->
Time_Of_Day.new
> Example
Parse "04:30:20" as Time_Of_Day.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_parse = Time_Of_Day.parse "04:30:20" "HH:mm:ss"
> Example
Parse "4:30AM" as Time_Of_Day
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_parse = Time_Of_Day.parse "4:30AM" "h:mma"
parse : Text -> Text | Nothing -> Locale -> Time_Of_Day ! Time.Time_Error
parse : Text -> Text | Nothing -> Locale -> Time_Of_Day ! Time_Error
parse text pattern=Nothing locale=Locale.default =
Panic.catch_java Any handler=(java_exception -> Error.throw (Time.Time_Error java_exception.getMessage)) <|
Panic.catch_java Any handler=(java_exception -> Error.throw (Time_Error java_exception.getMessage)) <|
case pattern of
Nothing -> Time_Of_Day.parse_builtin text
Text -> Time_Utils.parse_time text pattern locale.java_locale
@ -134,7 +133,7 @@ type Time_Of_Day
> Example
Get the current hour.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_hour = Time_Of_Day.now.hour
hour : Integer
@ -145,7 +144,7 @@ type Time_Of_Day
> Example
Get the current minute.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_minute = Time_Of_Day.now.minute
minute : Integer
@ -156,7 +155,7 @@ type Time_Of_Day
> Example
Get the current second.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_second = Time_Of_Day.now.second
second : Integer
@ -167,7 +166,7 @@ type Time_Of_Day
> Example
Get the current nanosecond.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_nanosecond = Time_Of_Day.now.nanosecond
nanosecond : Integer
@ -178,7 +177,7 @@ type Time_Of_Day
> Example
Convert the current time into elapsed seconds in the day.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_to_seconds = Time_Of_Day.now.to_seconds
to_seconds : Integer
@ -193,11 +192,11 @@ type Time_Of_Day
> Example
Convert local time to 1st January 2020 12:30 at system timezone.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_to_time = Time_Of_Day.new 12 30 . to_time (Date.new 2020)
to_time : Date -> Zone -> Time
to_time self date (zone=Zone.system) = self.to_time_builtin date zone
to_time : Date -> Time_Zone -> Time
to_time self date (zone=Time_Zone.system) = self.to_time_builtin date zone
## Add the specified amount of time to this instant to get a new instant.
@ -206,12 +205,12 @@ type Time_Of_Day
> Example
from Standard.Base import Time_Of_Day
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day
example_plus = Time_Of_Day.new + 3.seconds
+ : Duration -> Time_Of_Day
+ self amount = if amount.is_date then Error.throw (Time.Time_Error "Time_Of_Day does not support date intervals") else
+ self amount = if amount.is_date then Error.throw (Time_Error "Time_Of_Day does not support date intervals") else
Time_Utils.time_adjust self Time_Utils.AdjustOp.PLUS amount.internal_duration
## Subtract the specified amount of time from this instant to get a new
@ -223,12 +222,12 @@ type Time_Of_Day
> Example
Subtract 12 hours from a local time.
from Standard.Base import Time_Of_Day
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day
example_minus = Time_Of_Day.now - 12.hours
- : Duration -> Time_Of_Day
- self amount = if amount.is_date then Error.throw (Time.Time_Error "Time_Of_Day does not support date intervals") else
- self amount = if amount.is_date then Error.throw (Time_Error "Time_Of_Day does not support date intervals") else
Time_Utils.time_adjust self Time_Utils.AdjustOp.MINUS amount.internal_duration
## Format this time of day as text using the default formatter.
@ -236,7 +235,7 @@ type Time_Of_Day
> Example
Convert the current time to text.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_to_text = Time_Of_Day.now.to_text
to_text : Text
@ -247,7 +246,7 @@ type Time_Of_Day
> Example
Convert the current time to JSON.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_to_json = Time_Of_Day.now.to_text
to_json : Json.Object
@ -268,35 +267,35 @@ type Time_Of_Day
> Example
Format "16:21:10" as "16:21:00.1234"
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_format = Time_Of_Day.new 16 21 10 . format "HH:mm:ss.SSSS"
> Example
Format "16:21:10" as "16:21:00.123456789"
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_format = Time_Of_Day.new 16 21 10 . format "HH:mm:ss.n"
> Example
Format "16:21:10" as "4:21pm"
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_format = Time_Of_Day.new 16 21 10 . format "h:mma"
> Example
Format "16:21:10" as "04:21:10pm"
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_format = Time_Of_Day.new 16 21 10 . format "hh:mm:ssa"
> Example
Format "16:21:10" as "hour:4"
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_format = Time_Of_Day.new 16 21 10 . format "'hour:'h"
format : Text -> Text
@ -310,7 +309,7 @@ type Time_Of_Day
> Example
Compare two times for their ordering.
import Standard.Base.Data.Time.Time_Of_Day
from Standard.Base import Time_Of_Day
example_compare_to =
time_1 = Time_Of_Day.new hour=2 minute=30

View File

@ -1,6 +1,5 @@
from Standard.Base import all
import Standard.Base.Data.Time
from Standard.Base.Error.Common import Time_Error
polyglot java import java.time.ZoneId
polyglot java import java.time.ZoneOffset
@ -11,11 +10,11 @@ polyglot java import org.enso.base.Time_Utils
> Example
Get the system default timezone.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_system = Zone.system
system : Zone
system = @Builtin_Method "Zone.system"
example_system = Time_Zone.system
system : Time_Zone
system = @Builtin_Method "Time_Zone.system"
## ALIAS Current Time Zone
@ -24,10 +23,10 @@ system = @Builtin_Method "Zone.system"
> Example
Get the system's local timezone.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_local = Zone.local
local : Zone
example_local = Time_Zone.local
local : Time_Zone
local = system
## ALIAS UTC Time Zone
@ -37,13 +36,13 @@ local = system
> Example
Get the UTC timezone.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_utc = Zone.utc
utc : Zone
example_utc = Time_Zone.utc
utc : Time_Zone
utc = parse "UTC"
## Obtains an instance of `Zone` using an offset in hours, minutes and seconds
## Obtains an instance of `Time_Zone` using an offset in hours, minutes and seconds
from the UTC zone.
Arguments:
@ -56,16 +55,16 @@ utc = parse "UTC"
> Example
Get time zone 1 hour 1 minute and 50 seconds from UTC.
import Standard.Base.Data.Time.Zone
from Standard.Base import Zone
example_new = Zone.new 1 1 50
new : Integer -> Integer -> Integer -> Zone
new : Integer -> Integer -> Integer -> Time_Zone
new (hours = 0) (minutes = 0) (seconds = 0) =
Zone.new_builtin hours minutes seconds
Time_Zone.new_builtin hours minutes seconds
## ALIAS Time Zone from Text
This method parses the ID producing a `Zone`.
This method parses the ID producing a `Time_Zone`.
Arguments:
- text: The text representing a zone identifier.
@ -73,36 +72,36 @@ new (hours = 0) (minutes = 0) (seconds = 0) =
> Example
Get Central European Time.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_parse = Zone.parse "CET"
example_parse = Time_Zone.parse "CET"
> Example
Get Moscow time.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_parse = Zone.parse "Europe/Moscow"
example_parse = Time_Zone.parse "Europe/Moscow"
> Example
Get time zone -06:00.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_parse = Zone.parse "-06:00"
example_parse = Time_Zone.parse "-06:00"
> Example
Get custom offset +03:02:01 of 3 hours 2 minutes an 1 second.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_parse = Zone.parse "+03:02:01"
parse : Text -> Zone
example_parse = Time_Zone.parse "+03:02:01"
parse : Text -> Time_Zone
parse text =
Panic.catch_java Any handler=(java_exception -> Error.throw (Time.Time_Error java_exception.getMessage)) <|
Zone.parse_builtin text
Panic.catch_java Any handler=(java_exception -> Error.throw (Time_Error java_exception.getMessage)) <|
Time_Zone.parse_builtin text
type Zone
type Time_Zone
## PRIVATE
@ -115,30 +114,30 @@ type Zone
A time zone can be eiter offset-based like "-06:00" or id-based like
"Europe/Paris".
@Builtin_Type
type Zone
type Time_Zone
## Get the unique timezone ID.
> Example
Get the unique identifier for your system's current timezone.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_zone_id = Zone.system.zone_id
example_zone_id = Time_Zone.system.zone_id
zone_id : Text
zone_id self = @Builtin_Method "Zone.zone_id"
zone_id self = @Builtin_Method "Time_Zone.zone_id"
## Convert the time zone to JSON.
> Example
Convert your system's current timezone to JSON.
import Standard.Base.Data.Time.Zone
from Standard.Base import Time_Zone
example_to_json = Zone.system.to_json
example_to_json = Time_Zone.system.to_json
to_json : Json.Object
to_json self = Json.from_pairs [["type", "Zone"], ["id", self.zone_id]]
to_json self = Json.from_pairs [["type", "Time_Zone"], ["id", self.zone_id]]
## Compares two Zones for equality.
== : Zone -> Boolean
== : Time_Zone -> Boolean
== self that = Time_Utils.equals_zone self that

View File

@ -645,3 +645,13 @@ Unimplemented_Error.to_display_text self = "An implementation is missing: " + se
example_unimplemented = Errors.unimplemented
unimplemented : Text -> Void
unimplemented message="" = Panic.throw (Unimplemented_Error message)
type Time_Error
## UNSTABLE
An error produced while working with time- and date-related methods.
Arguments:
- error_message: The message for the error.
type Time_Error error_message

View File

@ -25,6 +25,10 @@ import project.Data.Text.Matching
import project.Data.Text.Text_Ordering
import project.Data.Text.Span
import project.Data.Time.Date
import project.Data.Time.Date_Time
import project.Data.Time.Time_Of_Day
import project.Data.Time.Time_Zone
import project.Data.Time.Day_Of_Week
import project.Data.Vector
import project.Error.Common
import project.Error.Problem_Behavior
@ -60,6 +64,10 @@ export project.Data.Statistics.Rank_Method
export project.Data.Text.Regex
export project.Data.Text.Regex.Mode as Regex_Mode
export project.Data.Time.Date
export project.Data.Time.Date_Time
export project.Data.Time.Time_Of_Day
export project.Data.Time.Time_Zone
export project.Data.Time.Day_Of_Week
export project.Data.Vector
export project.Error.Problem_Behavior
export project.IO

View File

@ -1,7 +1,8 @@
from Standard.Base import all
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time
from Standard.Base.Error.Common import Time_Error
import Standard.Base.Network.Http.Form
import Standard.Base.Network.Http.Header
import Standard.Base.Network.Http.Method
@ -658,7 +659,7 @@ type Http
internal_http_client self =
builder = HttpClient.newBuilder
# timeout
if self.timeout.is_date then Panic.throw (Time.Time_Error "Connection timeout does not support date intervals") else
if self.timeout.is_date then Panic.throw (Time_Error "Connection timeout does not support date intervals") else
builder.connectTimeout self.timeout.internal_duration
# redirect
redirect = HttpClient.Redirect

View File

@ -6,7 +6,6 @@ import Standard.Base.Data.Text.Text_Sub_Range
from Standard.Base.Error.Problem_Behavior import Report_Warning
import Standard.Base.Runtime.Resource
from Standard.Base.Runtime.Resource import Managed_Resource
from Standard.Base.Data.Time import Time
polyglot java import org.enso.base.Array_Utils
polyglot java import org.enso.base.Encoding_Utils

View File

@ -1,9 +1,8 @@
from Standard.Base import all
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Network.Http
import Standard.Base.System.Platform
import Standard.Base.Data.Time.Duration
import Standard.Base.Network.URI
import Standard.Base.Data.Text.Regex.Engine.Default as Default_Engine

View File

@ -7,28 +7,27 @@
> Example
Get the current time
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_now = Date_Time.now
> Example
Parse UTC time.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_parse = Time.parse "2020-10-01T04:11:12Z"
example_parse = Date_Time.parse "2020-10-01T04:11:12Z"
> Example
Convert time instance to -04:00 timezone.
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Zone
from Standard.Base import Date_Time, Time_Zone
exaomple_at_zone = Date_Time.new 2020 . at_zone (Zone.new -4)
exaomple_at_zone = Date_Time.new 2020 . at_zone (Time_Zone.new -4)
> Example
Convert the current time to a date.
import Standard.Base.Data.Time
from Standard.Base import Date_Time
example_date = Date_Time.now.date

View File

@ -1,5 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Time
## The type representing inferring the column type automatically based on values
present in the column.
@ -9,7 +8,7 @@ import Standard.Base.Data.Time
- if all values are decimals or integers, `Decimal` is chosen,
- if all values are booleans, `Boolean` is chosen,
- if the values are all the same time type (a date, a time or a date-time),
the corresponding type is chosen, `Date`, `Time_Of_Day` or `Time`,
the corresponding type is chosen, `Date`, `Time_Of_Day` or `Date_Time`,
respectively,
- otherwise, `Text` is chosen as a fallback and the column is kept as-is
without parsing.
@ -22,4 +21,4 @@ type Auto
index.
- datatype: The desired datatype for the column or `Auto` to infer the type
from the data.
type Column_Type_Selection (column:Text|Integer) datatype:(Auto|Integer|Decimal|Date|Time|Time_Of_Day|Boolean)=Auto
type Column_Type_Selection (column:Text|Integer) datatype:(Auto|Integer|Decimal|Date|Date_Time|Time_Of_Day|Boolean)=Auto

View File

@ -1,7 +1,4 @@
from Standard.Base import all
from Standard.Base.Data.Time import Date_Time
from Standard.Base.Data.Time.Time_Of_Day import Time_Of_Day
import Standard.Base.Error.Common as Errors
from Standard.Table.Data.Column_Type_Selection import Auto

View File

@ -1,5 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Runtime.State
import Standard.Base.System

View File

@ -322,7 +322,7 @@ public abstract class InvokeMethodNode extends BaseNode {
guards = {
"!methods.hasFunctionalDispatch(self)",
"!methods.hasSpecialDispatch(self)",
"getPolyglotCallType(self, symbol.getName(), interop) == CONVERT_TO_ZONE"
"getPolyglotCallType(self, symbol.getName(), interop) == CONVERT_TO_TIME_ZONE"
})
Stateful doConvertZone(
VirtualFrame frame,
@ -336,7 +336,7 @@ public abstract class InvokeMethodNode extends BaseNode {
var ctx = Context.get(this);
try {
var hostZone = interop.asTimeZone(self);
var dateTime = new EnsoZone(hostZone);
var dateTime = new EnsoTimeZone(hostZone);
Function function = dateDispatch.getFunctionalDispatch(dateTime, symbol);
arguments[0] = dateTime;
return invokeFunctionNode.execute(function, frame, state, arguments);

View File

@ -50,12 +50,12 @@ public abstract class HostMethodCallNode extends Node {
CONVERT_TO_DATE,
/**
* The method call should be handled by converting {@code self} to a {@code
* Standard.Base.Data.DateTime} and dispatching natively.
* Standard.Base.Data.Time.Date_Time} and dispatching natively.
*/
CONVERT_TO_ZONED_DATE_TIME,
/**
* The method call should be handled by converting {@code self} to a {@code
* Standard.Base.Data.DateTime} with a system Zone and dispatching natively.
* Standard.Base.Data.Time.Date_Time} with a system Time_Zone and dispatching natively.
*/
CONVERT_TO_DATE_TIME,
/**
@ -65,9 +65,9 @@ public abstract class HostMethodCallNode extends Node {
CONVERT_TO_TIME_OF_DAY,
/**
* The method call should be handled by converting {@code self} to a {@code
* Standard.Base.Data.Time.Zone} and dispatching natively.
* Standard.Base.Data.Time.Time_Zone} and dispatching natively.
*/
CONVERT_TO_ZONE,
CONVERT_TO_TIME_ZONE,
/** The method call should be handled by dispatching through the {@code Any} type. */
NOT_SUPPORTED;
@ -85,7 +85,7 @@ public abstract class HostMethodCallNode extends Node {
&& this != CONVERT_TO_DATE_TIME
&& this != CONVERT_TO_ZONED_DATE_TIME
&& this != CONVERT_TO_TIME_OF_DAY
&& this != CONVERT_TO_ZONE;
&& this != CONVERT_TO_TIME_ZONE;
}
}
@ -119,7 +119,7 @@ public abstract class HostMethodCallNode extends Node {
} else if (library.isTime(self)) {
return PolyglotCallType.CONVERT_TO_TIME_OF_DAY;
} else if (library.isTimeZone(self)) {
return PolyglotCallType.CONVERT_TO_ZONE;
return PolyglotCallType.CONVERT_TO_TIME_ZONE;
} else if (library.isString(self)) {
return PolyglotCallType.CONVERT_TO_TEXT;
} else if (library.isMemberInvocable(self, methodName)) {

View File

@ -78,7 +78,7 @@ public class Builtins {
private final BuiltinAtomConstructor date;
private final BuiltinAtomConstructor dateTime;
private final BuiltinAtomConstructor timeOfDay;
private final BuiltinAtomConstructor zone;
private final BuiltinAtomConstructor timeZone;
private final BuiltinAtomConstructor warning;
/**
@ -126,9 +126,9 @@ public class Builtins {
timeOfDay =
new BuiltinAtomConstructor(
this, org.enso.interpreter.node.expression.builtin.date.TimeOfDay.class);
zone =
timeZone =
new BuiltinAtomConstructor(
this, org.enso.interpreter.node.expression.builtin.date.Zone.class);
this, org.enso.interpreter.node.expression.builtin.date.TimeZone.class);
special = new Special(language);
warning = new BuiltinAtomConstructor(this, Warning.class);
}
@ -452,21 +452,21 @@ public class Builtins {
}
/**
* Returns the {@code Zone} atom constructor.
* Returns the {@code TimeOfDay} atom constructor.
*
* @return the {@code Zone} atom constructor
* @return the {@code TimeOfDay} atom constructor
*/
public AtomConstructor timeOfDay() {
return timeOfDay.constructor();
}
/**
* Returns the {@code Zone} atom constructor.
* Returns the {@code TimeZone} atom constructor.
*
* @return the {@code Zone} atom constructor
* @return the {@code TimeZone} atom constructor
*/
public AtomConstructor zone() {
return zone.constructor();
public AtomConstructor timeZone() {
return timeZone.constructor();
}
/**

View File

@ -74,7 +74,7 @@ public final class EnsoDate implements TruffleObject {
}
@Builtin.Method(name = "to_time_builtin", description = "Combine this day with time to create a point in time.")
public EnsoDateTime toTime(EnsoTimeOfDay timeOfDay, EnsoZone zone) {
public EnsoDateTime toTime(EnsoTimeOfDay timeOfDay, EnsoTimeZone zone) {
return new EnsoDateTime(date.atTime(timeOfDay.asTime()).atZone(zone.asTimeZone()));
}

View File

@ -43,7 +43,7 @@ public final class EnsoDateTime implements TruffleObject {
* <p>Accepts:
*
* <ul>
* <li>Local date time, such as '2011-12-03T10:15:30' adding system dafault timezone.
* <li>Local date time, such as '2011-12-03T10:15:30' adding system default timezone.
* <li>Offset date time, such as '2011-12-03T10:15:30+01:00' parsing offset as a timezone.
* <li>Zoned date time, such as '2011-12-03T10:15:30+01:00[Europe/Paris]' with optional region
* id in square brackets.
@ -82,7 +82,7 @@ public final class EnsoDateTime implements TruffleObject {
long minute,
long second,
long nanosecond,
EnsoZone zone) {
EnsoTimeZone zone) {
return new EnsoDateTime(
ZonedDateTime.of(
Math.toIntExact(year),
@ -138,8 +138,8 @@ public final class EnsoDateTime implements TruffleObject {
}
@Builtin.Method(name = "zone", description = "Gets the zone")
public EnsoZone zone() {
return new EnsoZone(dateTime.getZone());
public EnsoTimeZone zone() {
return new EnsoTimeZone(dateTime.getZone());
}
@Builtin.Method(description = "Return the number of seconds from the Unix epoch.")
@ -169,14 +169,14 @@ public final class EnsoDateTime implements TruffleObject {
}
@Builtin.Method(description = "Return this datetime in the provided time zone.")
public EnsoDateTime atZone(EnsoZone zone) {
public EnsoDateTime atZone(EnsoTimeZone zone) {
return new EnsoDateTime(dateTime.withZoneSameInstant(zone.asTimeZone()));
}
@Builtin.Method(
name = "to_time_builtin",
description = "Combine this day with time to create a point in time.")
public EnsoDateTime toTime(EnsoTimeOfDay timeOfDay, EnsoZone zone) {
public EnsoDateTime toTime(EnsoTimeOfDay timeOfDay, EnsoTimeZone zone) {
return new EnsoDateTime(
dateTime.toLocalDate().atTime(timeOfDay.asTime()).atZone(zone.asTimeZone()));
}

View File

@ -89,7 +89,7 @@ public class EnsoTimeOfDay implements TruffleObject {
@Builtin.Method(
name = "to_time_builtin",
description = "Combine this time of day with a date to create a point in time.")
public EnsoDateTime toTime(EnsoDate date, EnsoZone zone) {
public EnsoDateTime toTime(EnsoDate date, EnsoTimeZone zone) {
return new EnsoDateTime(localTime.atDate(date.asDate()).atZone(zone.asTimeZone()));
}

View File

@ -19,16 +19,15 @@ import org.enso.interpreter.runtime.library.dispatch.MethodDispatchLibrary;
import java.time.DateTimeException;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeParseException;
import java.time.zone.ZoneRulesException;
@ExportLibrary(InteropLibrary.class)
@ExportLibrary(MethodDispatchLibrary.class)
@Builtin(pkg = "date", name = "Zone", stdlibName = "Standard.Base.Data.Time.Zone")
public final class EnsoZone implements TruffleObject {
@Builtin(pkg = "date", name = "TimeZone", stdlibName = "Standard.Base.Data.Time.Time_Zone")
public final class EnsoTimeZone implements TruffleObject {
private final ZoneId zone;
public EnsoZone(ZoneId zone) {
public EnsoTimeZone(ZoneId zone) {
this.zone = zone;
}
@ -37,30 +36,30 @@ public final class EnsoZone implements TruffleObject {
return Text.create(this.zone.getId());
}
@Builtin.Method(name = "parse_builtin", description = "Parse the ID producing EnsoZone.")
@Builtin.Method(name = "parse_builtin", description = "Parse the ID producing a Time_Zone.")
@Builtin.Specialize
@Builtin.WrapException(
from = ZoneRulesException.class,
to = PolyglotError.class,
propagate = true)
public static EnsoZone parse(String text) {
return new EnsoZone(ZoneId.of(text));
public static EnsoTimeZone parse(String text) {
return new EnsoTimeZone(ZoneId.of(text));
}
@Builtin.Method(
name = "new_builtin",
description =
"Obtains an instance of `Zone` using an offset in hours, minutes and seconds from the UTC zone.")
"Obtains an instance of `Time_Zone` using an offset in hours, minutes and seconds from the UTC zone.")
@Builtin.WrapException(from = DateTimeException.class, to = PolyglotError.class, propagate = true)
public static EnsoZone create(long hours, long minutes, long seconds) {
return new EnsoZone(
public static EnsoTimeZone create(long hours, long minutes, long seconds) {
return new EnsoTimeZone(
ZoneOffset.ofHoursMinutesSeconds(
Math.toIntExact(hours), Math.toIntExact(minutes), Math.toIntExact(seconds)));
}
@Builtin.Method(name = "system", description = "The system default timezone.")
public static EnsoZone system() {
return new EnsoZone(ZoneId.systemDefault());
public static EnsoTimeZone system() {
return new EnsoTimeZone(ZoneId.systemDefault());
}
@ExportMessage
@ -83,14 +82,14 @@ public final class EnsoZone implements TruffleObject {
@CompilerDirectives.TruffleBoundary
static Function doResolve(InteropLibrary my, UnresolvedSymbol symbol) {
Context context = Context.get(my);
return symbol.resolveFor(context.getBuiltins().zone(), context.getBuiltins().any());
return symbol.resolveFor(context.getBuiltins().timeZone(), context.getBuiltins().any());
}
@Specialization(
guards = {"cachedSymbol == symbol", "function != null"},
limit = "3")
static Function resolveCached(
EnsoZone self,
EnsoTimeZone self,
UnresolvedSymbol symbol,
@Cached("symbol") UnresolvedSymbol cachedSymbol,
@CachedLibrary("self") InteropLibrary mySelf,
@ -100,7 +99,7 @@ public final class EnsoZone implements TruffleObject {
@Specialization(replaces = "resolveCached")
static Function resolve(
EnsoZone self, UnresolvedSymbol symbol, @CachedLibrary("self") InteropLibrary mySelf)
EnsoTimeZone self, UnresolvedSymbol symbol, @CachedLibrary("self") InteropLibrary mySelf)
throws MethodDispatchLibrary.NoSuchMethodException {
Function function = doResolve(mySelf, symbol);
if (function == null) {

View File

@ -53,7 +53,7 @@ import org.enso.polyglot.data.TypeGraph;
EnsoDate.class,
EnsoDateTime.class,
EnsoTimeOfDay.class,
EnsoZone.class,
EnsoTimeZone.class,
})
public class Types {
@ -227,7 +227,7 @@ public class Types {
graph.insert(ConstantsGen.DATE, ConstantsGen.ANY);
graph.insert(ConstantsGen.DATE_TIME, ConstantsGen.ANY);
graph.insert(ConstantsGen.TIME_OF_DAY, ConstantsGen.ANY);
graph.insert(ConstantsGen.ZONE, ConstantsGen.ANY);
graph.insert(ConstantsGen.TIME_ZONE, ConstantsGen.ANY);
graph.insertWithoutParent(ConstantsGen.PANIC);
graph.insertWithoutParent(Constants.THUNK);
graph.insertWithoutParent(Constants.UNRESOLVED_SYMBOL);

View File

@ -45,7 +45,7 @@ public record TypeWithKind(String baseType, TypeKind kind) {
"org.enso.interpreter.runtime.data.EnsoDate",
"org.enso.interpreter.runtime.data.EnsoDateTime",
"org.enso.interpreter.runtime.data.EnsoTimeOfDay",
"org.enso.interpreter.runtime.data.EnsoZone",
"org.enso.interpreter.runtime.data.EnsoTimeZone",
"org.enso.interpreter.runtime.data.ManagedResource",
"org.enso.interpreter.runtime.data.Ref",
"org.enso.interpreter.runtime.data.text.Text",

View File

@ -4,6 +4,7 @@ import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.Locale;
@ -97,6 +98,22 @@ public class Time_Utils {
}
}
public static int get_field_as_localdate(LocalDate date, TemporalField field) {
return date.get(field);
}
public static int get_field_as_zoneddatetime(ZonedDateTime date, TemporalField field) {
return date.get(field);
}
public static boolean is_leap_year(LocalDate date) {
return date.isLeapYear();
}
public static int length_of_month(LocalDate date) {
return date.lengthOfMonth();
}
public static long week_of_year_localdate(LocalDate date, Locale locale) {
return WeekFields.of(locale).weekOfYear().getFrom(date);
}

View File

@ -1,8 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
import Standard.Table
from Standard.Table import Column, Data_Formatter, Quote_Style
@ -140,15 +136,15 @@ spec =
formatter = Data_Formatter
formatter.format (Date.new 2022) . should_equal "2022-01-01"
formatter.format (Date_Time.new 1999) . should_equal "1999-01-01 00:00:00"
formatter.format (Date_Time.new 1999 zone=Zone.utc) . should_equal "1999-01-01 00:00:00"
formatter.format (Date_Time.new 1999 zone=(Zone.parse "America/Los_Angeles")) . should_equal "1999-01-01 00:00:00"
formatter.format (Date_Time.new 1999 zone=Time_Zone.utc) . should_equal "1999-01-01 00:00:00"
formatter.format (Date_Time.new 1999 zone=(Time_Zone.parse "America/Los_Angeles")) . should_equal "1999-01-01 00:00:00"
formatter.format (Time_Of_Day.new) . should_equal "00:00:00"
Test.specify "should allow custom date formats" <|
formatter = Data_Formatter date_formats=["E, d MMM y", "d MMM y[ G]"] datetime_formats=["dd/MM/yyyy HH:mm [z]"] time_formats=["h:mma"] datetime_locale=Locale.uk
formatter.format (Date.new 2022 06 21) . should_equal "Tue, 21 Jun 2022"
formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=Zone.utc) . should_equal "03/02/1999 04:56 UTC"
formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=(Zone.parse "America/Los_Angeles")) . should_equal "03/02/1999 04:56 GMT-08:00"
formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=Time_Zone.utc) . should_equal "03/02/1999 04:56 UTC"
formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=(Time_Zone.parse "America/Los_Angeles")) . should_equal "03/02/1999 04:56 GMT-08:00"
formatter.format (Time_Of_Day.new 13 55) . should_equal "1:55pm"
Test.specify "should act as identity on Text" <|

View File

@ -1,5 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.System
from Standard.Base.Error.Problem_Behavior import all

View File

@ -1,6 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Table
from Standard.Table import Data_Formatter

View File

@ -1,6 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Text.Line_Ending_Style
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Table
import Standard.Table.Data.Column

View File

@ -1,6 +1,4 @@
from Standard.Base import all
import Standard.Base.Data.Text.Line_Ending_Style
import Standard.Base.Data.Time
import Standard.Table
import Standard.Table.Data.Column

View File

@ -0,0 +1,99 @@
from Standard.Base import all
import Standard.Test
spec name create_new_date =
Test.group (name + "date part tests") <|
Test.specify "should return if a leap year" <|
create_new_date 2022 8 25 . is_leap_year . should_equal False
create_new_date 1999 12 31 . is_leap_year . should_equal False
create_new_date 1996 6 19 . is_leap_year . should_equal True
create_new_date 2000 1 1 . is_leap_year . should_equal True
create_new_date 1900 1 1 . is_leap_year . should_equal False
Test.specify "should return the number of days in the year" <|
create_new_date 2022 8 25 . length_of_year . should_equal 365
create_new_date 1999 12 31 . length_of_year . should_equal 365
create_new_date 1996 6 19 . length_of_year . should_equal 366
create_new_date 2000 1 1 . length_of_year . should_equal 366
create_new_date 1900 1 1 . length_of_year . should_equal 365
Test.specify "should return the century" <|
create_new_date 2022 8 25 . century . should_equal 21
create_new_date 1999 12 31 . century . should_equal 20
create_new_date 2000 1 1 . century . should_equal 20
create_new_date 2001 1 1 . century . should_equal 21
Test.specify "should return the quarter" <|
create_new_date 2022 2 1 . quarter . should_equal 1
create_new_date 1987 1 1 . quarter . should_equal 1
create_new_date 1996 2 29 . quarter . should_equal 1
create_new_date 2000 3 31 . quarter . should_equal 1
create_new_date 2017 5 16 . quarter . should_equal 2
create_new_date 2019 6 30 . quarter . should_equal 2
create_new_date 2019 7 1 . quarter . should_equal 3
create_new_date 2019 9 30 . quarter . should_equal 3
create_new_date 2019 10 1 . quarter . should_equal 4
create_new_date 2019 12 31 . quarter . should_equal 4
Test.specify "should return the number of days in the year" <|
create_new_date 1987 1 1 . length_of_month . should_equal 31
create_new_date 2022 2 1 . length_of_month . should_equal 28
create_new_date 1996 2 2 . length_of_month . should_equal 29
create_new_date 2000 3 31 . length_of_month . should_equal 31
create_new_date 2003 4 12 . length_of_month . should_equal 30
create_new_date 2017 5 16 . length_of_month . should_equal 31
create_new_date 2019 6 30 . length_of_month . should_equal 30
create_new_date 2019 7 5 . length_of_month . should_equal 31
create_new_date 2019 8 28 . length_of_month . should_equal 31
create_new_date 2019 9 30 . length_of_month . should_equal 30
create_new_date 2019 10 22 . length_of_month . should_equal 31
create_new_date 2019 11 7 . length_of_month . should_equal 30
create_new_date 2019 12 31 . length_of_month . should_equal 31
Test.specify "should return the day_of_year" <|
create_new_date 1990 9 18 . day_of_year . should_equal 261
create_new_date 1990 10 13 . day_of_year . should_equal 286
create_new_date 1992 9 28 . day_of_year . should_equal 272
create_new_date 1993 9 10 . day_of_year . should_equal 253
create_new_date 1996 3 15 . day_of_year . should_equal 75
create_new_date 2002 6 15 . day_of_year . should_equal 166
create_new_date 2007 5 4 . day_of_year . should_equal 124
create_new_date 2020 1 9 . day_of_year . should_equal 9
create_new_date 2020 4 9 . day_of_year . should_equal 100
create_new_date 2021 11 25 . day_of_year . should_equal 329
create_new_date 2023 3 21 . day_of_year . should_equal 80
create_new_date 2024 1 13 . day_of_year . should_equal 13
Test.specify "should return the day_of_week" <|
create_new_date 1990 9 18 . day_of_week . should_equal Day_Of_Week.Tuesday
create_new_date 1990 10 13 . day_of_week . should_equal Day_Of_Week.Saturday
create_new_date 1992 9 28 . day_of_week . should_equal Day_Of_Week.Monday
create_new_date 1993 9 10 . day_of_week . should_equal Day_Of_Week.Friday
create_new_date 1996 3 15 . day_of_week . should_equal Day_Of_Week.Friday
create_new_date 2002 6 15 . day_of_week . should_equal Day_Of_Week.Saturday
create_new_date 2007 5 4 . day_of_week . should_equal Day_Of_Week.Friday
create_new_date 2020 1 9 . day_of_week . should_equal Day_Of_Week.Thursday
create_new_date 2020 4 9 . day_of_week . should_equal Day_Of_Week.Thursday
create_new_date 2021 11 25 . day_of_week . should_equal Day_Of_Week.Thursday
create_new_date 2023 3 21 . day_of_week . should_equal Day_Of_Week.Tuesday
create_new_date 2024 1 13 . day_of_week . should_equal Day_Of_Week.Saturday
Test.specify "should return the correct week of year" <|
create_new_date 2021 8 1 . week_of_year Locale.mexico . should_equal 32
create_new_date 2021 1 1 . week_of_year Locale.us . should_equal 1
create_new_date 2021 1 1 . week_of_year Locale.uk . should_equal 0
create_new_date 1990 9 18 . week_of_year . should_equal 38
create_new_date 1990 10 13 . week_of_year . should_equal 41
create_new_date 1992 9 28 . week_of_year . should_equal 40
create_new_date 1993 9 10 . week_of_year . should_equal 36
create_new_date 1996 3 15 . week_of_year . should_equal 11
create_new_date 2002 6 15 . week_of_year . should_equal 24
create_new_date 2007 5 4 . week_of_year . should_equal 18
create_new_date 2020 1 9 . week_of_year . should_equal 2
create_new_date 2020 4 9 . week_of_year . should_equal 15
create_new_date 2021 11 25 . week_of_year . should_equal 47
create_new_date 2023 1 1 . week_of_year . should_equal 52
create_new_date 2024 1 1 . week_of_year . should_equal 1

View File

@ -1,23 +1,23 @@
from Standard.Base import all
import Standard.Base.Data.Text.Text_Sub_Range
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
from Standard.Base.Error.Common import Time_Error
import Standard.Test
import project.Data.Time.Date_Part_Spec
polyglot java import java.time.LocalDate
polyglot java import java.time.format.DateTimeFormatter
spec =
specWith "Date" Date.new Date.parse
specWith "JavaScriptDate" js_date js_parse
specWith "JavaDate" java_date java_parse
specWith "JavaScriptArrayWithADate" js_array_date js_parse
spec_with "Date" Date.new Date.parse
spec_with "JavaScriptDate" js_date js_parse
spec_with "JavaDate" java_date java_parse
spec_with "JavaScriptArrayWithADate" js_array_date js_parse
specWith name create_new_date parse_date =
spec_with name create_new_date parse_date =
Test.group name <|
Test.specify "should create local date" <|
@ -28,7 +28,7 @@ specWith name create_new_date parse_date =
Test.specify "should handle errors when creating local date" <|
case create_new_date 2020 30 30 . catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Invalid value for MonthOfYear (valid values 1 - 12): 30"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -50,7 +50,7 @@ specWith name create_new_date parse_date =
Test.specify "should throw error when parsing invalid date" <|
case parse_date "birthday" . catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Text 'birthday' could not be parsed at index 0"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -70,13 +70,13 @@ specWith name create_new_date parse_date =
Test.specify "should throw error when parsing custom format" <|
date = parse_date "1999-01-01" "yyyy M d"
case date.catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Text '1999-01-01' could not be parsed at index 4"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should convert to time" <|
time = create_new_date 2000 12 21 . to_time (Time_Of_Day.new 12 30 45) Zone.utc
time = create_new_date 2000 12 21 . to_time (Time_Of_Day.new 12 30 45) Time_Zone.utc
time . year . should_equal 2000
time . month . should_equal 12
time . day . should_equal 21
@ -84,7 +84,7 @@ specWith name create_new_date parse_date =
time . minute . should_equal 30
time . second . should_equal 45
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should convert to Json" <|
date = create_new_date 2001 12 21
@ -111,14 +111,14 @@ specWith name create_new_date parse_date =
Test.specify "should throw error when adding time-based interval" <|
case (create_new_date 1970 + 1.hour) . catch of
Time.Time_Error message ->
Time_Error message ->
message . should_equal "Date does not support time intervals"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should throw error when subtracting time-based interval" <|
case (create_new_date 1970 - (1.day - 1.minute)) . catch of
Time.Time_Error message ->
Time_Error message ->
message . should_equal "Date does not support time intervals"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -132,13 +132,7 @@ specWith name create_new_date parse_date =
date_1>date_2 . should_be_true
date_1<date_2 . should_be_false
Test.specify "should return the correct week of year" <|
date_1 = parse_date "2021-08-01"
date_1.week_of_year Locale.mexico . should_equal 32
date_2 = parse_date "2021-01-01"
date_2.week_of_year Locale.us . should_equal 1
date_2.week_of_year Locale.uk . should_equal 0
Date_Part_Spec.spec name create_new_date
main = Test.Suite.run_main spec
@ -151,25 +145,26 @@ js_parse text format=Nothing =
## JSDate is not only a date but also time and timezone.
## Here, we explicitly convert JS ZonedDateTime to LocalDate
js_set_zone local_datetime =
zone = Zone.utc
datetime_with_tz = local_datetime.at_zone(zone)
zone = Time_Zone.utc
datetime_with_tz = local_datetime.at_zone zone
diff = Duration.between datetime_with_tz local_datetime (timezone_aware=False)
(datetime_with_tz + diff).to_localdate_builtin
js_date year month=1 day=1 =
Panic.catch Any (js_set_zone (js_date_impl year month day)) (err -> Error.throw (Time.Time_Error err.payload.cause))
Panic.catch Any (js_set_zone (js_date_impl year month day)) (err -> Error.throw (Time_Error err.payload.cause))
js_array_date year month=1 day=1 =
arr = Panic.catch Any (js_array_dateCreate year month day) (err -> Error.throw (Time.Time_Error err.payload.cause))
arr = Panic.catch Any (js_array_dateCreate year month day) (err -> Error.throw (Time_Error err.payload.cause))
js_set_zone arr.at(0)
java_parse date_text pattern=Nothing =
if pattern == Nothing then Panic.catch Polyglot_Error (LocalDate.parse date_text) (err -> Error.throw (Time.Time_Error err.payload.cause.getMessage)) else
formatter = DateTimeFormatter.ofPattern(pattern)
Panic.catch Polyglot_Error (LocalDate.parse date_text formatter) (err -> Error.throw (Time.Time_Error err.payload.cause.getMessage))
Panic.catch Polyglot_Error handler=(err -> Error.throw (Time_Error err.payload.cause.getMessage)) <|
if pattern.is_nothing then LocalDate.parse date_text else
formatter = DateTimeFormatter.ofPattern pattern
LocalDate.parse date_text formatter
java_date year month=1 day=1 =
Panic.catch Any (LocalDate.of year month day) (err -> Error.throw (Time.Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
Panic.catch Any (LocalDate.of year month day) (err -> Error.throw (Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
foreign js js_date_impl year month=1 day=1 = """
if (month > 12) {

View File

@ -1,27 +1,25 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Date_Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Zone
import Standard.Test
import project.Data.Time.Date_Part_Spec
polyglot java import java.time.ZonedDateTime
polyglot java import java.time.LocalDateTime
polyglot java import java.time.format.DateTimeFormatter
spec =
specWith "Date_Time" Date_Time.new Date_Time.parse
specWith "JavascriptDate" js_datetime js_parse nanoseconds_loss_in_precision=True
specWith "JavaZonedDateTime" java_datetime java_parse
specWith "JavascriptDataInArray" js_array_datetime js_parse nanoseconds_loss_in_precision=True
spec_with "Date_Time" Date_Time.new Date_Time.parse
spec_with "JavascriptDate" js_datetime js_parse nanoseconds_loss_in_precision=True
spec_with "JavaZonedDateTime" java_datetime java_parse
spec_with "JavascriptDataInArray" js_array_datetime js_parse nanoseconds_loss_in_precision=True
specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=False =
spec_with name create_new_datetime parse_datetime nanoseconds_loss_in_precision=False =
Test.group name <|
Test.specify "should create time" <|
time = create_new_datetime 1970 (zone = Zone.utc)
time = create_new_datetime 1970 (zone = Time_Zone.utc)
time . year . should_equal 1970
time . month . should_equal 1
time . day . should_equal 1
@ -29,32 +27,32 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should handle errors when creating time" <|
case create_new_datetime 1970 0 0 . catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Invalid value for MonthOfYear (valid values 1 - 12): 0"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should format using provided pattern" <|
text = create_new_datetime 1970 (zone = Zone.utc) . format "yyyy-MM-dd'T'HH:mm:ss"
text = create_new_datetime 1970 (zone = Time_Zone.utc) . format "yyyy-MM-dd'T'HH:mm:ss"
text . should_equal "1970-01-01T00:00:00"
Test.specify "should format using default pattern" <|
text = create_new_datetime 1970 (zone = Zone.utc) . to_text
text = create_new_datetime 1970 (zone = Time_Zone.utc) . to_text
text . should_equal "1970-01-01T00:00:00Z[UTC]"
Test.specify "should convert to Json" <|
time = create_new_datetime 1970 12 21 (zone = Zone.utc)
time = create_new_datetime 1970 12 21 (zone = Time_Zone.utc)
time.to_json.should_equal <|
zone_pairs = [["zone", Zone.utc]]
zone_pairs = [["zone", Time_Zone.utc]]
time_pairs = [["year", time.year], ["month", time.month], ["day", time.day], ["hour", time.hour], ["minute", time.minute], ["second", time.second], ["nanosecond", time.nanosecond]]
Json.from_pairs ([["type", "Time"]] + time_pairs + zone_pairs)
Test.specify "should parse default time format" <|
text = create_new_datetime 1970 (zone = Zone.utc) . to_text
text = create_new_datetime 1970 (zone = Time_Zone.utc) . to_text
time = parse_datetime text
time . year . should_equal 1970
time . month . should_equal 1
@ -63,7 +61,7 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should parse local time adding system zone" <|
time = parse_datetime "1970-01-01T00:00:01"
@ -74,7 +72,7 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 1
time . nanosecond . should_equal 0
time . zone . should_equal Zone.system
time . zone . should_equal Time_Zone.system
Test.specify "should parse time Z" <|
time = parse_datetime "1970-01-01T00:00:01Z"
@ -107,7 +105,7 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 1
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal (Zone.new 1 . zone_id)
time . zone . zone_id . should_equal (Time_Zone.new 1 . zone_id)
Test.specify "should parse time with id-based zone" <|
time = parse_datetime "1970-01-01T00:00:01+01:00[Europe/Paris]"
@ -122,7 +120,7 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
Test.specify "should throw error when parsing invalid time" <|
case parse_datetime "2008-1-1" . catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Text '2008-1-1' could not be parsed at index 5"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -151,22 +149,22 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
Test.specify "should throw error when parsing custom format" <|
time = parse_datetime "2008-01-01" "yyyy-MM-dd'T'HH:mm:ss'['z']'"
case time.catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Text '2008-01-01' could not be parsed at index 10"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should get epoch seconds" <|
time = create_new_datetime 1970 1 1 0 0 8 (zone = Zone.utc)
time = create_new_datetime 1970 1 1 0 0 8 (zone = Time_Zone.utc)
time . to_epoch_seconds . should_equal 8
Test.specify "should get epoch millis" <|
time = create_new_datetime 1970 1 1 0 0 8 (zone = Zone.utc)
time = create_new_datetime 1970 1 1 0 0 8 (zone = Time_Zone.utc)
time . to_epoch_milliseconds . should_equal 8000
Test.specify "should set offset-based timezone" <|
tz = Zone.new 1 1 1
time = create_new_datetime 1970 (zone = Zone.utc) . at_zone tz
tz = Time_Zone.new 1 1 1
time = create_new_datetime 1970 (zone = Time_Zone.utc) . at_zone tz
time . year . should_equal 1970
time . month . should_equal 1
time . day . should_equal 1
@ -177,8 +175,8 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . zone . zone_id . should_equal tz.zone_id
Test.specify "should set id-based timezone" <|
tz = Zone.parse "Europe/Moscow"
time = create_new_datetime 1970 (zone = Zone.utc) . at_zone tz
tz = Time_Zone.parse "Europe/Moscow"
time = create_new_datetime 1970 (zone = Time_Zone.utc) . at_zone tz
time . year . should_equal 1970
time . month . should_equal 1
time . day . should_equal 1
@ -215,7 +213,7 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . day . should_equal 1
Test.specify "should add time interval" <|
time = create_new_datetime 1970 (zone = Zone.utc) + 1.nanosecond
time = create_new_datetime 1970 (zone = Time_Zone.utc) + 1.nanosecond
time . year . should_equal 1970
time . month . should_equal 1
time . day . should_equal 1
@ -223,10 +221,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 1
time . zone . should_equal Zone.utc
time . zone . should_equal Time_Zone.utc
Test.specify "should add date interval" <|
time = create_new_datetime 1970 (zone = Zone.utc) + 1.month
time = create_new_datetime 1970 (zone = Time_Zone.utc) + 1.month
time . year . should_equal 1970
time . month . should_equal 2
time . day . should_equal 1
@ -234,10 +232,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should add mixed date time interval" <|
time = create_new_datetime 1970 (zone = Zone.utc) + (1.month + 3.hours)
time = create_new_datetime 1970 (zone = Time_Zone.utc) + (1.month + 3.hours)
time . year . should_equal 1970
time . month . should_equal 2
time . day . should_equal 1
@ -245,10 +243,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should subtract time interval" <|
time = create_new_datetime 1970 (zone = Zone.utc) - 1.hour
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.hour
time . year . should_equal 1969
time . month . should_equal 12
time . day . should_equal 31
@ -256,10 +254,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should subtract date interval" <|
time = create_new_datetime 1970 (zone = Zone.utc) - 1.month
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.month
time . year . should_equal 1969
time . month . should_equal 12
time . day . should_equal 1
@ -267,10 +265,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should subtract mixed date time interval" <|
time = create_new_datetime 1970 (zone = Zone.utc) - (1.month - 3.hours)
time = create_new_datetime 1970 (zone = Time_Zone.utc) - (1.month - 3.hours)
time . year . should_equal 1969
time . month . should_equal 12
time . day . should_equal 1
@ -278,10 +276,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should support mixed interval operators" <|
time = create_new_datetime 1970 (zone = Zone.utc) - 1.month + 12.hours
time = create_new_datetime 1970 (zone = Time_Zone.utc) - 1.month + 12.hours
time . year . should_equal 1969
time . month . should_equal 12
time . day . should_equal 1
@ -289,7 +287,7 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time . minute . should_equal 0
time . second . should_equal 0
time . nanosecond . should_equal 0
time . zone . zone_id . should_equal Zone.utc.zone_id
time . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should be comparable" <|
time_1 = parse_datetime "2021-01-01T00:30:12.7102[UTC]"
@ -300,8 +298,10 @@ specWith name create_new_datetime parse_datetime nanoseconds_loss_in_precision=F
time_1>time_2 . should_be_true
time_1<time_2 . should_be_false
js_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 zone=Zone.system =
Panic.catch Any (js_datetime_with_zone year month day hour minute second nanosecond zone) (err -> Error.throw (Time.Time_Error err.payload.cause))
Date_Part_Spec.spec name create_new_datetime
js_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 zone=Time_Zone.system =
Panic.catch Any (js_datetime_with_zone year month day hour minute second nanosecond zone) (err -> Error.throw (Time_Error err.payload.cause))
# This ensures that date returned by javascript has the right timezone specified by the zone parameter.
# Javascript's toLocaleString will accept the timezone but it will just adapt the datetime while keeping the local timezone.
@ -309,7 +309,7 @@ js_datetime_with_zone year month day hour minute second nanosecond zone =
js_set_zone (js_local_datetime_impl year month day hour minute second nanosecond) zone
js_set_zone local_datetime zone =
datetime_with_tz = local_datetime.at_zone(zone)
datetime_with_tz = local_datetime.at_zone zone
diff = Duration.between datetime_with_tz local_datetime (timezone_aware=False)
datetime_with_tz + diff
@ -323,8 +323,8 @@ js_parse text format=Nothing =
d = Date_Time.parse text format
js_datetime d.year d.month d.day d.hour d.minute d.second d.nanosecond d.zone
js_array_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 zone=Zone.system =
arr = Panic.catch Any (js_array_datetimeCreate year month day hour minute second nanosecond) (err -> Error.throw (Time.Time_Error err.payload.cause))
js_array_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 zone=Time_Zone.system =
arr = Panic.catch Any (js_array_datetimeCreate year month day hour minute second nanosecond) (err -> Error.throw (Time_Error err.payload.cause))
js_set_zone arr.at(0) zone
foreign js js_array_datetimeCreate year month day hour minute second nanosecond = """
@ -333,17 +333,18 @@ foreign js js_array_datetimeCreate year month day hour minute second nanosecond
}
return [ new Date(year, month - 1, day, hour, minute, second, nanosecond / 1000000) ];
java_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 zone=Zone.system =
Panic.catch Any (ZonedDateTime.of year month day hour minute second nanosecond zone) (err -> Error.throw (Time.Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
java_datetime year month=1 day=1 hour=0 minute=0 second=0 nanosecond=0 zone=Time_Zone.system =
Panic.catch Any (ZonedDateTime.of year month day hour minute second nanosecond zone) (err -> Error.throw (Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
maybe_parse_java_zoned text pattern=Nothing =
if pattern == Nothing then ZonedDateTime.parse text else
ZonedDateTime.parse text pattern
parse_java_local original_error text pattern=Nothing =
if pattern == Nothing then Panic.catch Polyglot_Error (LocalDateTime.parse text) (_ -> Error.throw (Time.Time_Error original_error.payload.cause.getMessage)) else
formatter = DateTimeFormatter.ofPattern(pattern)
Panic.catch Polyglot_Error (LocalDateTime.parse text formatter) (_ -> Error.throw (Time.Time_Error original_error.payload.cause.getMessage))
Panic.catch Polyglot_Error handler=(_ -> Error.throw (Time_Error original_error.payload.cause.getMessage)) <|
if pattern.is_nothing then LocalDateTime.parse text else
formatter = DateTimeFormatter.ofPattern pattern
LocalDateTime.parse text (formatter.withLocale Locale.default.java_locale)
java_parse date_text_raw pattern=Nothing =
utc_replaced = date_text_raw.replace "[UTC]" "Z"

View File

@ -0,0 +1,55 @@
from Standard.Base import all
import Standard.Test
spec =
Test.group "Day_Of_Week conversions" <|
Test.specify "should be able to convert to an Integer" <|
Day_Of_Week.Sunday.to_integer . should_equal 1
Day_Of_Week.Wednesday.to_integer . should_equal 4
Day_Of_Week.Friday.to_integer . should_equal 6
Day_Of_Week.Saturday.to_integer . should_equal 7
Test.specify "should be able to convert from an Integer" <|
Day_Of_Week.from 1 . should_equal Day_Of_Week.Sunday
Day_Of_Week.from 4 . should_equal Day_Of_Week.Wednesday
Day_Of_Week.from 6 . should_equal Day_Of_Week.Friday
Day_Of_Week.from 7 . should_equal Day_Of_Week.Saturday
Test.specify "should be able to convert to an Integer starting at 0" <|
Day_Of_Week.Sunday.to_integer start_at_zero=True . should_equal 0
Day_Of_Week.Wednesday.to_integer start_at_zero=True . should_equal 3
Day_Of_Week.Friday.to_integer start_at_zero=True . should_equal 5
Day_Of_Week.Saturday.to_integer start_at_zero=True . should_equal 6
Test.specify "should be able to convert from an Integer starting at 0" <|
Day_Of_Week.from 0 start_at_zero=True . should_equal Day_Of_Week.Sunday
Day_Of_Week.from 3 start_at_zero=True . should_equal Day_Of_Week.Wednesday
Day_Of_Week.from 5 start_at_zero=True . should_equal Day_Of_Week.Friday
Day_Of_Week.from 6 start_at_zero=True . should_equal Day_Of_Week.Saturday
Test.specify "should be able to convert to an Integer starting on Monday" <|
Day_Of_Week.Sunday.to_integer Day_Of_Week.Monday . should_equal 7
Day_Of_Week.Wednesday.to_integer Day_Of_Week.Monday . should_equal 3
Day_Of_Week.Friday.to_integer Day_Of_Week.Monday . should_equal 5
Day_Of_Week.Saturday.to_integer Day_Of_Week.Monday . should_equal 6
Test.specify "should be able to convert from an Integer starting on Monday" <|
Day_Of_Week.from 7 Day_Of_Week.Monday . should_equal Day_Of_Week.Sunday
Day_Of_Week.from 3 Day_Of_Week.Monday . should_equal Day_Of_Week.Wednesday
Day_Of_Week.from 5 Day_Of_Week.Monday . should_equal Day_Of_Week.Friday
Day_Of_Week.from 6 Day_Of_Week.Monday . should_equal Day_Of_Week.Saturday
Test.specify "should be able to convert to an Integer starting on Monday at 0" <|
Day_Of_Week.Sunday.to_integer Day_Of_Week.Monday True . should_equal 6
Day_Of_Week.Wednesday.to_integer Day_Of_Week.Monday True . should_equal 2
Day_Of_Week.Friday.to_integer Day_Of_Week.Monday True . should_equal 4
Day_Of_Week.Saturday.to_integer Day_Of_Week.Monday True . should_equal 5
Test.specify "should be able to convert from an Integer starting on Monday at 0" <|
Day_Of_Week.from 6 Day_Of_Week.Monday True . should_equal Day_Of_Week.Sunday
Day_Of_Week.from 2 Day_Of_Week.Monday True . should_equal Day_Of_Week.Wednesday
Day_Of_Week.from 4 Day_Of_Week.Monday True . should_equal Day_Of_Week.Friday
Day_Of_Week.from 5 Day_Of_Week.Monday True . should_equal Day_Of_Week.Saturday
main = Test.Suite.run_main spec

View File

@ -1,8 +1,6 @@
from Standard.Base import all
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Date_Time
import Standard.Test
spec =

View File

@ -1,14 +1,20 @@
from Standard.Base import all
import Standard.Test
import project.Data.Time.Duration_Spec
import project.Data.Time.Time_Of_Day_Spec
import project.Data.Time.Date_Spec
import project.Data.Time.Time_Spec
import project.Data.Time.Zone_Spec
import project.Data.Time.Date_Time_Spec
import project.Data.Time.Time_Zone_Spec
import project.Data.Time.Day_Of_Week_Spec
spec =
Date_Spec.spec
Duration_Spec.spec
Time_Of_Day_Spec.spec
Time_Spec.spec
Zone_Spec.spec
Date_Time_Spec.spec
Time_Zone_Spec.spec
Day_Of_Week_Spec.spec
main = Test.Suite.run_main spec

View File

@ -1,9 +1,6 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
from Standard.Base.Error.Common import Time_Error
import Standard.Test
@ -26,7 +23,7 @@ specWith name create_new_time parse_time =
Test.specify "should handle errors when creating a time" <|
case create_new_time 24 0 0 . catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Invalid value for HourOfDay (valid values 0 - 23): 24"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -56,7 +53,7 @@ specWith name create_new_time parse_time =
Test.specify "should throw error when parsing invalid time" <|
case parse_time "1200" . catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Text '1200' could not be parsed at index 2"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -68,13 +65,13 @@ specWith name create_new_time parse_time =
Test.specify "should throw error when parsing custom format" <|
time = parse_time "12:30" "HH:mm:ss"
case time.catch of
Time.Time_Error msg ->
Time_Error msg ->
msg . should_equal "Text '12:30' could not be parsed at index 5"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should convert to time" <|
datetime = create_new_time 1 0 0 . to_time (Date.new 2000 12 21) Zone.utc
datetime = create_new_time 1 0 0 . to_time (Date.new 2000 12 21) Time_Zone.utc
datetime . year . should_equal 2000
datetime . month . should_equal 12
datetime . day . should_equal 21
@ -82,7 +79,7 @@ specWith name create_new_time parse_time =
datetime . minute . should_equal 0
datetime . second . should_equal 0
datetime . nanosecond . should_equal 0
datetime . zone . zone_id . should_equal Zone.utc.zone_id
datetime . zone . zone_id . should_equal Time_Zone.utc.zone_id
Test.specify "should add time-based interval" <|
time = create_new_time 0 + 1.minute
@ -98,14 +95,14 @@ specWith name create_new_time parse_time =
Test.specify "should throw error when adding date-based interval" <|
case (create_new_time 0 + 1.day) . catch of
Time.Time_Error message ->
Time_Error message ->
message . should_equal "Time_Of_Day does not support date intervals"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should throw error when subtracting date-based interval" <|
case (create_new_time 0 - (1.day - 1.minute)) . catch of
Time.Time_Error message ->
Time_Error message ->
message . should_equal "Time_Of_Day does not support date intervals"
result ->
Test.fail ("Unexpected result: " + result.to_text)
@ -123,11 +120,12 @@ enso_time hour minute=0 second=0 nanoOfSecond=0 =
Time_Of_Day.new hour minute second nanoOfSecond
java_time hour minute=0 second=0 nanoOfSecond=0 =
Panic.catch Any (LocalTime.of hour minute second nanoOfSecond) (err -> Error.throw (Time.Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
Panic.catch Any (LocalTime.of hour minute second nanoOfSecond) (err -> Error.throw (Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16)))
java_parse time_text pattern=Nothing =
if pattern == Nothing then Panic.catch Polyglot_Error (LocalTime.parse time_text) (err -> Error.throw (Time.Time_Error err.payload.cause.getMessage)) else
formatter = DateTimeFormatter.ofPattern(pattern)
Panic.catch Polyglot_Error (LocalTime.parse time_text formatter) (err -> Error.throw (Time.Time_Error err.payload.cause.getMessage))
Panic.catch Polyglot_Error handler=(err -> Error.throw (Time_Error err.payload.cause.getMessage)) <|
if pattern.is_nothing then LocalTime.parse time_text else
formatter = DateTimeFormatter.ofPattern pattern
LocalTime.parse time_text (formatter.withLocale Locale.default.java_locale)
main = Test.Suite.run_main spec

View File

@ -1,8 +1,5 @@
from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Zone
import Standard.Test
polyglot java import java.time.ZoneId
@ -11,42 +8,42 @@ polyglot java import java.time.ZoneOffset
spec =
Test.group "Zone" <|
Test.specify "should get system zone id" <|
Zone.system
Time_Zone.system
Test.specify "should parse UTC zone" <|
zone = "UTC"
id = Zone.parse zone
id = Time_Zone.parse zone
id . zone_id . should_equal zone
Test.specify "should parse id-based zone" <|
zone = "Europe/Warsaw"
id = Zone.parse zone
id = Time_Zone.parse zone
id . zone_id . should_equal zone
Test.specify "should parse offset-based zone" <|
zone = "+01:02:03"
id = Zone.parse zone
id = Time_Zone.parse zone
id . zone_id . should_equal zone
Test.specify "should get utc zone id" <|
id = Zone.utc
id = Time_Zone.utc
id . zone_id . should_equal "UTC"
Test.specify "should convert to Json" <|
zone = Zone.new 1 2 3
zone = Time_Zone.new 1 2 3
zone.to_json.should_equal <|
Json.from_pairs [["type", "Zone"], ["id", "+01:02:03"]]
Zone.utc.to_json.should_equal <|
Json.from_pairs [["type", "Zone"], ["id", "UTC"]]
Json.from_pairs [["type", "Time_Zone"], ["id", "+01:02:03"]]
Time_Zone.utc.to_json.should_equal <|
Json.from_pairs [["type", "Time_Zone"], ["id", "UTC"]]
Test.specify "should throw error when parsing invalid zone id" <|
case Zone.parse "foo" . catch of
Time.Time_Error msg ->
case Time_Zone.parse "foo" . catch of
Time_Error msg ->
msg . should_equal "Unknown time-zone ID: foo"
result ->
Test.fail ("Unexpected result: " + result.to_text)
Test.group "JavaZoneId" <|
Test.specify "should get system zone id" <|
defaultZone = ZoneId.systemDefault
Zone.system . should_equal defaultZone
Time_Zone.system . should_equal defaultZone
Test.specify "should parse UTC zone" <|
zone = "UTC"
id = ZoneId.of zone
id . should_equal Zone.utc
id . should_equal Time_Zone.utc
Test.specify "should parse id-based zone" <|
zone = "Europe/Warsaw"
id = ZoneId.of zone
@ -57,12 +54,12 @@ spec =
id . zone_id . should_equal zone
Test.specify "should get utc zone id" <|
zone = ZoneId.of "UTC"
zone . should_equal Zone.utc
zone . should_equal Time_Zone.utc
Test.specify "should convert to Json" <|
zone = ZoneOffset.ofHoursMinutesSeconds 1 2 3
zone.to_json.should_equal <|
Json.from_pairs [["type", "Zone"], ["id", "+01:02:03"]]
Json.from_pairs [["type", "Time_Zone"], ["id", "+01:02:03"]]
(ZoneId.of "UTC").to_json.should_equal <|
Json.from_pairs [["type", "Zone"], ["id", "UTC"]]
Json.from_pairs [["type", "Time_Zone"], ["id", "UTC"]]
main = Test.Suite.run_main spec