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 "zombie" state, where processes were started but not visible to user. They
could cause issues with starting further IDE instances. could cause issues with starting further IDE instances.
- [New nodes are created in the project source when the searcher is opened - [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) #### EnsoGL (rendering engine)
@ -185,6 +185,7 @@
- [Expanded `Table.at` to support index access and added `Table.column_count` - [Expanded `Table.at` to support index access and added `Table.column_count`
method.][3644] method.][3644]
- [Removed `Array.set_at`.][3634] - [Removed `Array.set_at`.][3634]
- [Added various date part functions to `Date` and `Date_Time`.][3669]
[debug-shortcuts]: [debug-shortcuts]:
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug 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 [3617]: https://github.com/enso-org/enso/pull/3617
[3628]: https://github.com/enso-org/enso/pull/3628 [3628]: https://github.com/enso-org/enso/pull/3628
[3629]: https://github.com/enso-org/enso/pull/3629 [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 [3643]: https://github.com/enso-org/enso/pull/3643
[3644]: https://github.com/enso-org/enso/pull/3644 [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 [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 [3634]: https://github.com/enso-org/enso/pull/3634
[3669]: https://github.com/enso-org/enso/pull/3669
#### Enso Compiler #### 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 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.Duration
import Standard.Base.Data.Time.Time_Of_Day
import Standard.Base.Data.Time.Zone
import Standard.Base.Polyglot import Standard.Base.Polyglot
from Standard.Base.Error.Common import Time_Error
polyglot java import org.enso.base.Time_Utils 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. ## Obtains the current date from the system clock in the system timezone.
@ -41,7 +41,7 @@ today = now
> Example > Example
Create a new local date at Unix epoch. Create a new local date at Unix epoch.
import Standard.Base.Data.Time.Date from Standard.Base import Date
example_new = Date.new 1970 example_new = Date.new 1970
@ -50,7 +50,7 @@ today = now
example_new = Date.new 1986 8 5 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) = new year (month = 1) (day = 1) =
## TODO This is left using the old error handling approach, because ## TODO This is left using the old error handling approach, because
magically, changing this to the `catch_java` (which is now preferred way 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 https://github.com/enso-org/enso/pull/3559
Then this should be switched to use `Panic.catch_java`. 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 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 ex -> ex
## ALIAS Date from Text ## ALIAS Date from Text
@ -96,41 +96,43 @@ new year (month = 1) (day = 1) =
> Example > Example
Parse the date of 23rd December 2020. 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_parse = Date.parse "2020-12-23"
> Example > Example
Recover from an error due to a wrong format. 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 Date.new 2000 1 1
> Example > Example
Parse "1999-1-1" as Date using a custom format. 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_parse = Date.parse "1999-1-1" "yyyy-M-d"
> Example > Example
Recover from the parse error. 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 = example_parse_err =
date = Date.parse "1999-1-1" "yyyy-MM-dd" date = Date.parse "1999-1-1" "yyyy-MM-dd"
date.catch Time.Time_Error (_->Date.new 2000 1 1) date.catch Time_Error (_->Date.new 2000 1 1)
parse : Text -> (Text | Nothing) -> Date ! Time.Time_Error parse : Text -> (Text | Nothing) -> Date ! Time_Error
parse text pattern=Nothing = parse text pattern=Nothing =
result = Panic.recover Any <| case pattern of result = Panic.recover Any <| case pattern of
Nothing -> Date.internal_parse text 0 Nothing -> Date.internal_parse text 0
Text -> Date.internal_parse text pattern 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 result . map_error <| case _ of
Polyglot_Error err -> Time.Time_Error err.getMessage Polyglot_Error err -> Time_Error err.getMessage
ex -> ex ex -> ex
type Date type Date
@ -154,7 +156,7 @@ type Date
> Example > Example
Get the current year. Get the current year.
import Standard.Base.Data.Time.Date from Standard.Base import Date
example_year = Date.now.year example_year = Date.now.year
year : Integer year : Integer
@ -174,7 +176,7 @@ type Date
> Example > Example
Get the current day. Get the current day.
import Standard.Base.Data.Time.Date from Standard.Base import Date
example_day = Date.now.day example_day = Date.now.day
day : Integer day : Integer
@ -184,6 +186,7 @@ type Date
Arguments: Arguments:
- locale: the locale used to define the notion of weeks of year. - 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 ! Locale Dependency
Note that this operation is locale-specific. It varies both by the 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 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 containing the first Thursday of the year. Therefore it is important to
properly specify the `locale` argument. properly specify the `locale` argument.
week_of_year : Locale.Locale -> Integer week_of_year : (Locale.Locale | Nothing) -> Integer
week_of_year self locale=Locale.default = Time_Utils.week_of_year_localdate self locale.java_locale 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 ## ALIAS Date to Time
@ -207,12 +242,11 @@ type Date
> Example > Example
Convert this date to midnight UTC time. Convert this date to midnight UTC time.
import Standard.Base.Data.Time.Time_Of_Day from Standard.Base import Date, Time_Of_Day, Time_Zone
import Standard.Base.Data.Time.Zone
example_to_time = Date.new 2020 2 3 . to_time Time_Of_Day.new Zone.utc example_to_time = Date.new 2020 2 3 . to_time Time_Of_Day.new Time_Zone.utc
to_time : Time_Of_Day -> Zone -> Date_Time to_time : Time_Of_Day -> Time_Zone -> Date_Time
to_time self time_of_day (zone=Zone.system) = self.to_time_builtin time_of_day zone 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. ## 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 example_add = Date.new 2020 + 6.months
+ : Duration -> Date + : 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 (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 ## Subtract the specified amount of time from this instant to get another
@ -238,12 +272,12 @@ type Date
> Example > Example
Subtract 7 days from a local date. Subtract 7 days from a local date.
import Standard.Base.Data.Time.Date from Standard.Base import Date
import Standard.Base.Data.Time.Duration import Standard.Base.Data.Time.Duration
example_subtract = Date.new 2020 - 7.days example_subtract = Date.new 2020 - 7.days
- : Duration -> Date - : 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 (Time_Utils.date_adjust self Time_Utils.AdjustOp.MINUS amount.internal_period) . internal_local_date
@ -268,7 +302,7 @@ type Date
> Example > Example
Format "2020-06-02" as "2 June 2020" 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" 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 import all
from Standard.Base.Data.Time import Time_Error
import Standard.Base.Data.Time.Duration import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day from Standard.Base.Error.Common import Time_Error
import Standard.Base.Data.Time.Zone
polyglot java import java.time.format.DateTimeFormatter 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 polyglot java import org.enso.base.Time_Utils
## ALIAS Current Time ## ALIAS Current Time
@ -16,7 +16,7 @@ polyglot java import org.enso.base.Time_Utils
> Example > Example
Get the current time Get the current time
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_now = Date_Time.now example_now = Date_Time.now
now : Date_Time now : Date_Time
@ -40,20 +40,18 @@ now = @Builtin_Method "Date_Time.now"
> Example > Example
Create a new zoned date time at Unix epoch. Create a new zoned date time at Unix epoch.
import Standard.Base.Data.Time.Date_Time from Standard.Base import Date_Time, Time_Zone
import Standard.Base.Data.Time.Zone
example_new = Date_Time.new 1970 (zone = Zone.utc) example_new = Date_Time.new 1970 (zone = Time_Zone.utc)
> Example > Example
Get the 5 August 1986 at midnight. Get the 5 August 1986 at midnight.
import Standard.Base.Data.Time.Date_Time from Standard.Base import Date_Time, Time_Zone
import Standard.Base.Data.Time.Zone
example_new = Date_Time.new 1986 8 5 example_new = Date_Time.new 1986 8 5
new : Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Zone -> Date_Time ! Time_Error 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 = Zone.system) = 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-> 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) 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 > Example
Parse UTC time. 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 = Date_Time.parse "2020-10-01T04:11:12Z"
> Example > Example
Parse UTC-04:00 time. 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 = Date_Time.parse "2020-10-01T04:11:12-04:00"
> Example > Example
Parse UTC-04:00 time specifying New York timezone. 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 = Date_Time.parse "2020-10-01T04:11:12-04:00[America/New_York]"
> Example > Example
Parse UTC-04:00 time with nanoseconds. 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_parse = Date_Time.parse "2020-10-01T04:11:12.177528-04:00"
> Example > Example
Recover from the parse error. 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 = Date_Time.parse "2020-10-01" . catch Time_Error (_->Date_Time.now)
> Example > Example
Parse "2020-05-06 04:30:20" as Date_Time 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 > Example
Parse "06 of May 2020 at 04:30AM" as Date_Tme Parse "06 of May 2020 at 04:30AM" as Date_Tme
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_parse = example_parse =
Date_Time.parse "06 of May 2020 at 04:30AM" "dd 'of' MMMM yyyy 'at' hh:mma" 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 > Example
Get the current year. Get the current year.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_year = Date_Time.now.year example_year = Date_Time.now.year
year : Integer year : Integer
@ -175,7 +173,7 @@ type Date_Time
> Example > Example
Get the current month. Get the current month.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_month = Date_Time.now.month example_month = Date_Time.now.month
month : Integer month : Integer
@ -186,7 +184,7 @@ type Date_Time
> Example > Example
Get the current day. Get the current day.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_day = Date_Time.now.day example_day = Date_Time.now.day
day : Integer day : Integer
@ -197,7 +195,7 @@ type Date_Time
> Example > Example
Get the current hour. Get the current hour.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_hour = Date_Time.now.hour example_hour = Date_Time.now.hour
hour : Integer hour : Integer
@ -208,7 +206,7 @@ type Date_Time
> Example > Example
Get the current minute. Get the current minute.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_minute = Date_Time.now.minute example_minute = Date_Time.now.minute
minute : Integer minute : Integer
@ -219,7 +217,7 @@ type Date_Time
> Example > Example
Get the current second. Get the current second.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_second = Date_Time.now.second example_second = Date_Time.now.second
second : Integer second : Integer
@ -230,7 +228,7 @@ type Date_Time
> Example > Example
Get the current nanosecond. Get the current nanosecond.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_nanosecond = Date_Time.now.nanosecond example_nanosecond = Date_Time.now.nanosecond
nanosecond : Integer nanosecond : Integer
@ -241,10 +239,10 @@ type Date_Time
> Example > Example
Get the current timezone. Get the current timezone.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_zone = Date_Time.now.zone example_zone = Date_Time.now.zone
zone : Zone zone : Time_Zone
zone self = @Builtin_Method "Date_Time.zone" zone self = @Builtin_Method "Date_Time.zone"
## Return the number of seconds from the Unix epoch. ## Return the number of seconds from the Unix epoch.
@ -252,7 +250,7 @@ type Date_Time
> Example > Example
Get the current number of seconds from the Unix epoch. 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 example_epoch = Date_Time.now.to_epoch_seconds
to_epoch_seconds : Integer to_epoch_seconds : Integer
@ -263,7 +261,7 @@ type Date_Time
> Example > Example
Get the current number of milliseconds from the unix epoch. 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 example_epoch = Date_Time.now.to_epoch_milliseconds
to_epoch_milliseconds : Integer to_epoch_milliseconds : Integer
@ -275,7 +273,7 @@ type Date_Time
> Example > Example
Convert the current time to a time of day. 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 example_time_of_day = Date_Time.now.time_of_day
time_of_day : Time_Of_Day time_of_day : Time_Of_Day
@ -285,6 +283,7 @@ type Date_Time
Arguments: Arguments:
- locale: the locale used to define the notion of weeks of year. - 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 ! Locale Dependency
Note that this operation is locale-specific. It varies both by the 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 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 containing the first Thursday of the year. Therefore it is important to
properly specify the `locale` argument. properly specify the `locale` argument.
week_of_year : Locale.Locale -> Integer week_of_year : (Locale.Locale | Nothing) -> Integer
week_of_year self locale=Locale.default = Time_Utils.week_of_year_zoneddatetime self locale.java_locale 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 ## ALIAS Time to Date
@ -305,7 +335,7 @@ type Date_Time
> Example > Example
Convert the current time to a date. Convert the current time to a date.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_date = Date_Time.now.date example_date = Date_Time.now.date
date : Date date : Date
@ -321,11 +351,10 @@ type Date_Time
> Example > Example
Convert time instance to -04:00 timezone. Convert time instance to -04:00 timezone.
import Standard.Base.Data.Time.Date_Time from Standard.Base import Date_Time, Time_Zone
import Standard.Base.Data.Time.Zone
example_at_zone = Date_Time.new 2020 . at_zone (Zone.new -4) example_at_zone = Date_Time.new 2020 . at_zone (Time_Zone.new -4)
at_zone : Zone -> Date_Time at_zone : Time_Zone -> Date_Time
at_zone self zone = @Builtin_Method "Date_Time.at_zone" at_zone self zone = @Builtin_Method "Date_Time.at_zone"
## Add the specified amount of time to this instant to produce a new instant. ## Add the specified amount of time to this instant to produce a new instant.
@ -336,7 +365,7 @@ type Date_Time
> Example > Example
Add 15 years and 3 hours to a zoned date time. 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 import Standard.Base.Data.Time.Duration
example_plus = Date_Time.new 2020 + 15.years + 3.hours example_plus = Date_Time.new 2020 + 15.years + 3.hours
@ -353,7 +382,7 @@ type Date_Time
> Example > Example
Subtract 1 year and 9 months from a zoned date time. 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 import Standard.Base.Data.Time.Duration
example_minus = Date_Time.new 2020 - 1.year - 9.months example_minus = Date_Time.new 2020 - 1.year - 9.months
@ -366,7 +395,7 @@ type Date_Time
> Example > Example
Convert the current time to text. 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 example_to_text = Date_Time.now.to_text
to_text : Text to_text : Text
@ -377,7 +406,7 @@ type Date_Time
> Example > Example
Convert the current time to JSON. 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 example_to_json = Date_Time.now.to_json
to_json : Json.Object to_json : Json.Object
@ -438,7 +467,7 @@ type Date_Time
Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as
"2020-10-08T16:41:13+03:00[Europe/Moscow]". "2020-10-08T16:41:13+03:00[Europe/Moscow]".
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_format = example_format =
Date_Time.parse "2020-10-08T16:41:13+03:00[Europe/Moscow]" . format "yyyy-MM-dd'T'HH:mm:ssZZZZ'['VV']'" 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 > Example
Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as
"Thursday October 8 4:41 PM". "Thursday October 8 4:41 PM".
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_format = example_format =
Date_Time.parse "2020-10-08T16:41:13+03:00[Europe/Moscow]" . format "EEEE MMMM d h:mm a" 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 Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as
"Thu Oct 8 (16:41)". "Thu Oct 8 (16:41)".
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_format = example_format =
Date_Time.parse "2020-10-08T16:41:13+03:00[Europe/Moscow]" . format "EEE MMM d (HH:mm)" 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 from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.System import Standard.Base.System
polyglot java import java.time.Duration as Java_Duration polyglot java import java.time.Duration as Java_Duration
@ -17,8 +15,8 @@ polyglot java import org.enso.base.Time_Utils
> Example > Example
An hour interval between two points in time. 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.Duration
import Standard.Base.Data.Time.Date_Time
example_between = Duration.between Date_Time.now (Date_Time.new 2010 10 20) example_between = Duration.between Date_Time.now (Date_Time.new 2010 10 20)
between : Date_Time -> Date_Time -> Duration between : Date_Time -> Date_Time -> Duration

View File

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

View File

@ -1,6 +1,5 @@
from Standard.Base import all from Standard.Base import all
from Standard.Base.Error.Common import Time_Error
import Standard.Base.Data.Time
polyglot java import java.time.ZoneId polyglot java import java.time.ZoneId
polyglot java import java.time.ZoneOffset polyglot java import java.time.ZoneOffset
@ -11,11 +10,11 @@ polyglot java import org.enso.base.Time_Utils
> Example > Example
Get the system default timezone. Get the system default timezone.
import Standard.Base.Data.Time.Zone from Standard.Base import Time_Zone
example_system = Zone.system example_system = Time_Zone.system
system : Zone system : Time_Zone
system = @Builtin_Method "Zone.system" system = @Builtin_Method "Time_Zone.system"
## ALIAS Current Time Zone ## ALIAS Current Time Zone
@ -24,10 +23,10 @@ system = @Builtin_Method "Zone.system"
> Example > Example
Get the system's local timezone. Get the system's local timezone.
import Standard.Base.Data.Time.Zone from Standard.Base import Time_Zone
example_local = Zone.local example_local = Time_Zone.local
local : Zone local : Time_Zone
local = system local = system
## ALIAS UTC Time Zone ## ALIAS UTC Time Zone
@ -37,13 +36,13 @@ local = system
> Example > Example
Get the UTC timezone. Get the UTC timezone.
import Standard.Base.Data.Time.Zone from Standard.Base import Time_Zone
example_utc = Zone.utc example_utc = Time_Zone.utc
utc : Zone utc : Time_Zone
utc = parse "UTC" 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. from the UTC zone.
Arguments: Arguments:
@ -56,16 +55,16 @@ utc = parse "UTC"
> Example > Example
Get time zone 1 hour 1 minute and 50 seconds from UTC. 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 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) = 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 ## ALIAS Time Zone from Text
This method parses the ID producing a `Zone`. This method parses the ID producing a `Time_Zone`.
Arguments: Arguments:
- text: The text representing a zone identifier. - text: The text representing a zone identifier.
@ -73,36 +72,36 @@ new (hours = 0) (minutes = 0) (seconds = 0) =
> Example > Example
Get Central European Time. 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 > Example
Get Moscow time. 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 > Example
Get time zone -06:00. 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 > Example
Get custom offset +03:02:01 of 3 hours 2 minutes an 1 second. 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" example_parse = Time_Zone.parse "+03:02:01"
parse : Text -> Zone parse : Text -> Time_Zone
parse text = parse text =
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)) <|
Zone.parse_builtin text Time_Zone.parse_builtin text
type Zone type Time_Zone
## PRIVATE ## PRIVATE
@ -115,30 +114,30 @@ type Zone
A time zone can be eiter offset-based like "-06:00" or id-based like A time zone can be eiter offset-based like "-06:00" or id-based like
"Europe/Paris". "Europe/Paris".
@Builtin_Type @Builtin_Type
type Zone type Time_Zone
## Get the unique timezone ID. ## Get the unique timezone ID.
> Example > Example
Get the unique identifier for your system's current timezone. 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 : Text
zone_id self = @Builtin_Method "Zone.zone_id" zone_id self = @Builtin_Method "Time_Zone.zone_id"
## Convert the time zone to JSON. ## Convert the time zone to JSON.
> Example > Example
Convert your system's current timezone to JSON. 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 : 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. ## Compares two Zones for equality.
== : Zone -> Boolean == : Time_Zone -> Boolean
== self that = Time_Utils.equals_zone self that == 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 example_unimplemented = Errors.unimplemented
unimplemented : Text -> Void unimplemented : Text -> Void
unimplemented message="" = Panic.throw (Unimplemented_Error message) 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.Text_Ordering
import project.Data.Text.Span import project.Data.Text.Span
import project.Data.Time.Date 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.Data.Vector
import project.Error.Common import project.Error.Common
import project.Error.Problem_Behavior 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
export project.Data.Text.Regex.Mode as Regex_Mode export project.Data.Text.Regex.Mode as Regex_Mode
export project.Data.Time.Date 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.Data.Vector
export project.Error.Problem_Behavior export project.Error.Problem_Behavior
export project.IO export project.IO

View File

@ -1,7 +1,8 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.Data.Time.Duration 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.Form
import Standard.Base.Network.Http.Header import Standard.Base.Network.Http.Header
import Standard.Base.Network.Http.Method import Standard.Base.Network.Http.Method
@ -658,7 +659,7 @@ type Http
internal_http_client self = internal_http_client self =
builder = HttpClient.newBuilder builder = HttpClient.newBuilder
# timeout # 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 builder.connectTimeout self.timeout.internal_duration
# redirect # redirect
redirect = HttpClient.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 from Standard.Base.Error.Problem_Behavior import Report_Warning
import Standard.Base.Runtime.Resource import Standard.Base.Runtime.Resource
from Standard.Base.Runtime.Resource import Managed_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.Array_Utils
polyglot java import org.enso.base.Encoding_Utils polyglot java import org.enso.base.Encoding_Utils

View File

@ -1,9 +1,8 @@
from Standard.Base import all 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.Network.Http
import Standard.Base.System.Platform import Standard.Base.System.Platform
import Standard.Base.Data.Time.Duration
import Standard.Base.Network.URI import Standard.Base.Network.URI
import Standard.Base.Data.Text.Regex.Engine.Default as Default_Engine import Standard.Base.Data.Text.Regex.Engine.Default as Default_Engine

View File

@ -7,28 +7,27 @@
> Example > Example
Get the current time Get the current time
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_now = Date_Time.now example_now = Date_Time.now
> Example > Example
Parse UTC time. 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 > Example
Convert time instance to -04:00 timezone. Convert time instance to -04:00 timezone.
import Standard.Base.Data.Time.Date_Time from Standard.Base import Date_Time, Time_Zone
import Standard.Base.Data.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 > Example
Convert the current time to a date. Convert the current time to a date.
import Standard.Base.Data.Time from Standard.Base import Date_Time
example_date = Date_Time.now.date example_date = Date_Time.now.date

View File

@ -1,5 +1,4 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.Data.Time
## The type representing inferring the column type automatically based on values ## The type representing inferring the column type automatically based on values
present in the column. 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 decimals or integers, `Decimal` is chosen,
- if all values are booleans, `Boolean` 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), - 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, respectively,
- otherwise, `Text` is chosen as a fallback and the column is kept as-is - otherwise, `Text` is chosen as a fallback and the column is kept as-is
without parsing. without parsing.
@ -22,4 +21,4 @@ type Auto
index. index.
- datatype: The desired datatype for the column or `Auto` to infer the type - datatype: The desired datatype for the column or `Auto` to infer the type
from the data. 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 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 import Standard.Base.Error.Common as Errors
from Standard.Table.Data.Column_Type_Selection import Auto from Standard.Table.Data.Column_Type_Selection import Auto

View File

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

View File

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

View File

@ -50,12 +50,12 @@ public abstract class HostMethodCallNode extends Node {
CONVERT_TO_DATE, CONVERT_TO_DATE,
/** /**
* The method call should be handled by converting {@code self} to a {@code * 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, CONVERT_TO_ZONED_DATE_TIME,
/** /**
* The method call should be handled by converting {@code self} to a {@code * 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, CONVERT_TO_DATE_TIME,
/** /**
@ -65,9 +65,9 @@ public abstract class HostMethodCallNode extends Node {
CONVERT_TO_TIME_OF_DAY, CONVERT_TO_TIME_OF_DAY,
/** /**
* The method call should be handled by converting {@code self} to a {@code * 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. */ /** The method call should be handled by dispatching through the {@code Any} type. */
NOT_SUPPORTED; NOT_SUPPORTED;
@ -85,7 +85,7 @@ public abstract class HostMethodCallNode extends Node {
&& this != CONVERT_TO_DATE_TIME && this != CONVERT_TO_DATE_TIME
&& this != CONVERT_TO_ZONED_DATE_TIME && this != CONVERT_TO_ZONED_DATE_TIME
&& this != CONVERT_TO_TIME_OF_DAY && 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)) { } else if (library.isTime(self)) {
return PolyglotCallType.CONVERT_TO_TIME_OF_DAY; return PolyglotCallType.CONVERT_TO_TIME_OF_DAY;
} else if (library.isTimeZone(self)) { } else if (library.isTimeZone(self)) {
return PolyglotCallType.CONVERT_TO_ZONE; return PolyglotCallType.CONVERT_TO_TIME_ZONE;
} else if (library.isString(self)) { } else if (library.isString(self)) {
return PolyglotCallType.CONVERT_TO_TEXT; return PolyglotCallType.CONVERT_TO_TEXT;
} else if (library.isMemberInvocable(self, methodName)) { } else if (library.isMemberInvocable(self, methodName)) {

View File

@ -78,7 +78,7 @@ public class Builtins {
private final BuiltinAtomConstructor date; private final BuiltinAtomConstructor date;
private final BuiltinAtomConstructor dateTime; private final BuiltinAtomConstructor dateTime;
private final BuiltinAtomConstructor timeOfDay; private final BuiltinAtomConstructor timeOfDay;
private final BuiltinAtomConstructor zone; private final BuiltinAtomConstructor timeZone;
private final BuiltinAtomConstructor warning; private final BuiltinAtomConstructor warning;
/** /**
@ -126,9 +126,9 @@ public class Builtins {
timeOfDay = timeOfDay =
new BuiltinAtomConstructor( new BuiltinAtomConstructor(
this, org.enso.interpreter.node.expression.builtin.date.TimeOfDay.class); this, org.enso.interpreter.node.expression.builtin.date.TimeOfDay.class);
zone = timeZone =
new BuiltinAtomConstructor( 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); special = new Special(language);
warning = new BuiltinAtomConstructor(this, Warning.class); 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() { public AtomConstructor timeOfDay() {
return timeOfDay.constructor(); 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() { public AtomConstructor timeZone() {
return zone.constructor(); 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.") @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())); return new EnsoDateTime(date.atTime(timeOfDay.asTime()).atZone(zone.asTimeZone()));
} }

View File

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

View File

@ -89,7 +89,7 @@ public class EnsoTimeOfDay implements TruffleObject {
@Builtin.Method( @Builtin.Method(
name = "to_time_builtin", name = "to_time_builtin",
description = "Combine this time of day with a date to create a point in time.") 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())); 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.DateTimeException;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.format.DateTimeParseException;
import java.time.zone.ZoneRulesException; import java.time.zone.ZoneRulesException;
@ExportLibrary(InteropLibrary.class) @ExportLibrary(InteropLibrary.class)
@ExportLibrary(MethodDispatchLibrary.class) @ExportLibrary(MethodDispatchLibrary.class)
@Builtin(pkg = "date", name = "Zone", stdlibName = "Standard.Base.Data.Time.Zone") @Builtin(pkg = "date", name = "TimeZone", stdlibName = "Standard.Base.Data.Time.Time_Zone")
public final class EnsoZone implements TruffleObject { public final class EnsoTimeZone implements TruffleObject {
private final ZoneId zone; private final ZoneId zone;
public EnsoZone(ZoneId zone) { public EnsoTimeZone(ZoneId zone) {
this.zone = zone; this.zone = zone;
} }
@ -37,30 +36,30 @@ public final class EnsoZone implements TruffleObject {
return Text.create(this.zone.getId()); 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.Specialize
@Builtin.WrapException( @Builtin.WrapException(
from = ZoneRulesException.class, from = ZoneRulesException.class,
to = PolyglotError.class, to = PolyglotError.class,
propagate = true) propagate = true)
public static EnsoZone parse(String text) { public static EnsoTimeZone parse(String text) {
return new EnsoZone(ZoneId.of(text)); return new EnsoTimeZone(ZoneId.of(text));
} }
@Builtin.Method( @Builtin.Method(
name = "new_builtin", name = "new_builtin",
description = 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) @Builtin.WrapException(from = DateTimeException.class, to = PolyglotError.class, propagate = true)
public static EnsoZone create(long hours, long minutes, long seconds) { public static EnsoTimeZone create(long hours, long minutes, long seconds) {
return new EnsoZone( return new EnsoTimeZone(
ZoneOffset.ofHoursMinutesSeconds( ZoneOffset.ofHoursMinutesSeconds(
Math.toIntExact(hours), Math.toIntExact(minutes), Math.toIntExact(seconds))); Math.toIntExact(hours), Math.toIntExact(minutes), Math.toIntExact(seconds)));
} }
@Builtin.Method(name = "system", description = "The system default timezone.") @Builtin.Method(name = "system", description = "The system default timezone.")
public static EnsoZone system() { public static EnsoTimeZone system() {
return new EnsoZone(ZoneId.systemDefault()); return new EnsoTimeZone(ZoneId.systemDefault());
} }
@ExportMessage @ExportMessage
@ -83,14 +82,14 @@ public final class EnsoZone implements TruffleObject {
@CompilerDirectives.TruffleBoundary @CompilerDirectives.TruffleBoundary
static Function doResolve(InteropLibrary my, UnresolvedSymbol symbol) { static Function doResolve(InteropLibrary my, UnresolvedSymbol symbol) {
Context context = Context.get(my); Context context = Context.get(my);
return symbol.resolveFor(context.getBuiltins().zone(), context.getBuiltins().any()); return symbol.resolveFor(context.getBuiltins().timeZone(), context.getBuiltins().any());
} }
@Specialization( @Specialization(
guards = {"cachedSymbol == symbol", "function != null"}, guards = {"cachedSymbol == symbol", "function != null"},
limit = "3") limit = "3")
static Function resolveCached( static Function resolveCached(
EnsoZone self, EnsoTimeZone self,
UnresolvedSymbol symbol, UnresolvedSymbol symbol,
@Cached("symbol") UnresolvedSymbol cachedSymbol, @Cached("symbol") UnresolvedSymbol cachedSymbol,
@CachedLibrary("self") InteropLibrary mySelf, @CachedLibrary("self") InteropLibrary mySelf,
@ -100,7 +99,7 @@ public final class EnsoZone implements TruffleObject {
@Specialization(replaces = "resolveCached") @Specialization(replaces = "resolveCached")
static Function resolve( static Function resolve(
EnsoZone self, UnresolvedSymbol symbol, @CachedLibrary("self") InteropLibrary mySelf) EnsoTimeZone self, UnresolvedSymbol symbol, @CachedLibrary("self") InteropLibrary mySelf)
throws MethodDispatchLibrary.NoSuchMethodException { throws MethodDispatchLibrary.NoSuchMethodException {
Function function = doResolve(mySelf, symbol); Function function = doResolve(mySelf, symbol);
if (function == null) { if (function == null) {

View File

@ -53,7 +53,7 @@ import org.enso.polyglot.data.TypeGraph;
EnsoDate.class, EnsoDate.class,
EnsoDateTime.class, EnsoDateTime.class,
EnsoTimeOfDay.class, EnsoTimeOfDay.class,
EnsoZone.class, EnsoTimeZone.class,
}) })
public class Types { public class Types {
@ -227,7 +227,7 @@ public class Types {
graph.insert(ConstantsGen.DATE, ConstantsGen.ANY); graph.insert(ConstantsGen.DATE, ConstantsGen.ANY);
graph.insert(ConstantsGen.DATE_TIME, ConstantsGen.ANY); graph.insert(ConstantsGen.DATE_TIME, ConstantsGen.ANY);
graph.insert(ConstantsGen.TIME_OF_DAY, 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(ConstantsGen.PANIC);
graph.insertWithoutParent(Constants.THUNK); graph.insertWithoutParent(Constants.THUNK);
graph.insertWithoutParent(Constants.UNRESOLVED_SYMBOL); 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.EnsoDate",
"org.enso.interpreter.runtime.data.EnsoDateTime", "org.enso.interpreter.runtime.data.EnsoDateTime",
"org.enso.interpreter.runtime.data.EnsoTimeOfDay", "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.ManagedResource",
"org.enso.interpreter.runtime.data.Ref", "org.enso.interpreter.runtime.data.Ref",
"org.enso.interpreter.runtime.data.text.Text", "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.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields; import java.time.temporal.WeekFields;
import java.util.Locale; 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) { public static long week_of_year_localdate(LocalDate date, Locale locale) {
return WeekFields.of(locale).weekOfYear().getFrom(date); return WeekFields.of(locale).weekOfYear().getFrom(date);
} }

View File

@ -1,8 +1,4 @@
from Standard.Base import all 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 import Standard.Table
from Standard.Table import Column, Data_Formatter, Quote_Style from Standard.Table import Column, Data_Formatter, Quote_Style
@ -140,15 +136,15 @@ spec =
formatter = Data_Formatter formatter = Data_Formatter
formatter.format (Date.new 2022) . should_equal "2022-01-01" 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) . 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=Time_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.parse "America/Los_Angeles")) . should_equal "1999-01-01 00:00:00"
formatter.format (Time_Of_Day.new) . should_equal "00:00:00" formatter.format (Time_Of_Day.new) . should_equal "00:00:00"
Test.specify "should allow custom date formats" <| 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 = 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.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=Time_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.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" formatter.format (Time_Of_Day.new 13 55) . should_equal "1:55pm"
Test.specify "should act as identity on Text" <| Test.specify "should act as identity on Text" <|

View File

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

View File

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

View File

@ -1,6 +1,4 @@
from Standard.Base import all 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
import Standard.Table.Data.Column import Standard.Table.Data.Column

View File

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

View File

@ -1,27 +1,25 @@
from Standard.Base import all 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.Duration
import Standard.Base.Data.Time.Zone
import Standard.Test import Standard.Test
import project.Data.Time.Date_Part_Spec
polyglot java import java.time.ZonedDateTime polyglot java import java.time.ZonedDateTime
polyglot java import java.time.LocalDateTime polyglot java import java.time.LocalDateTime
polyglot java import java.time.format.DateTimeFormatter polyglot java import java.time.format.DateTimeFormatter
spec = spec =
specWith "Date_Time" Date_Time.new Date_Time.parse spec_with "Date_Time" Date_Time.new Date_Time.parse
specWith "JavascriptDate" js_datetime js_parse nanoseconds_loss_in_precision=True spec_with "JavascriptDate" js_datetime js_parse nanoseconds_loss_in_precision=True
specWith "JavaZonedDateTime" java_datetime java_parse spec_with "JavaZonedDateTime" java_datetime java_parse
specWith "JavascriptDataInArray" js_array_datetime js_parse nanoseconds_loss_in_precision=True 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.group name <|
Test.specify "should create time" <| 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 . year . should_equal 1970
time . month . should_equal 1 time . month . should_equal 1
time . day . 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| Test.specify "should handle errors when creating time" <|
case create_new_datetime 1970 0 0 . catch of 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" msg . should_equal "Invalid value for MonthOfYear (valid values 1 - 12): 0"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should format using provided pattern" <| 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" text . should_equal "1970-01-01T00:00:00"
Test.specify "should format using default pattern" <| 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]" text . should_equal "1970-01-01T00:00:00Z[UTC]"
Test.specify "should convert to Json" <| 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 <| 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]] 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) Json.from_pairs ([["type", "Time"]] + time_pairs + zone_pairs)
Test.specify "should parse default time format" <| 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 = parse_datetime text
time . year . should_equal 1970 time . year . should_equal 1970
time . month . should_equal 1 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| Test.specify "should parse local time adding system zone" <|
time = parse_datetime "1970-01-01T00:00:01" 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 . minute . should_equal 0
time . second . should_equal 1 time . second . should_equal 1
time . nanosecond . should_equal 0 time . nanosecond . should_equal 0
time . zone . should_equal Zone.system time . zone . should_equal Time_Zone.system
Test.specify "should parse time Z" <| Test.specify "should parse time Z" <|
time = parse_datetime "1970-01-01T00:00:01Z" 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 . minute . should_equal 0
time . second . should_equal 1 time . second . should_equal 1
time . nanosecond . should_equal 0 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" <| Test.specify "should parse time with id-based zone" <|
time = parse_datetime "1970-01-01T00:00:01+01:00[Europe/Paris]" 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" <| Test.specify "should throw error when parsing invalid time" <|
case parse_datetime "2008-1-1" . catch of 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" msg . should_equal "Text '2008-1-1' could not be parsed at index 5"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) 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" <| Test.specify "should throw error when parsing custom format" <|
time = parse_datetime "2008-01-01" "yyyy-MM-dd'T'HH:mm:ss'['z']'" time = parse_datetime "2008-01-01" "yyyy-MM-dd'T'HH:mm:ss'['z']'"
case time.catch of 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" msg . should_equal "Text '2008-01-01' could not be parsed at index 10"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should get epoch seconds" <| 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 time . to_epoch_seconds . should_equal 8
Test.specify "should get epoch millis" <| 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 time . to_epoch_milliseconds . should_equal 8000
Test.specify "should set offset-based timezone" <| Test.specify "should set offset-based timezone" <|
tz = Zone.new 1 1 1 tz = Time_Zone.new 1 1 1
time = create_new_datetime 1970 (zone = Zone.utc) . at_zone tz time = create_new_datetime 1970 (zone = Time_Zone.utc) . at_zone tz
time . year . should_equal 1970 time . year . should_equal 1970
time . month . should_equal 1 time . month . should_equal 1
time . day . 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 time . zone . zone_id . should_equal tz.zone_id
Test.specify "should set id-based timezone" <| Test.specify "should set id-based timezone" <|
tz = Zone.parse "Europe/Moscow" tz = Time_Zone.parse "Europe/Moscow"
time = create_new_datetime 1970 (zone = Zone.utc) . at_zone tz time = create_new_datetime 1970 (zone = Time_Zone.utc) . at_zone tz
time . year . should_equal 1970 time . year . should_equal 1970
time . month . should_equal 1 time . month . should_equal 1
time . day . 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 time . day . should_equal 1
Test.specify "should add time interval" <| 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 . year . should_equal 1970
time . month . should_equal 1 time . month . should_equal 1
time . day . 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . should_equal 1 time . nanosecond . should_equal 1
time . zone . should_equal Zone.utc time . zone . should_equal Time_Zone.utc
Test.specify "should add date interval" <| 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 . year . should_equal 1970
time . month . should_equal 2 time . month . should_equal 2
time . day . should_equal 1 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| 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 . year . should_equal 1970
time . month . should_equal 2 time . month . should_equal 2
time . day . should_equal 1 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| 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 . year . should_equal 1969
time . month . should_equal 12 time . month . should_equal 12
time . day . should_equal 31 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| 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 . year . should_equal 1969
time . month . should_equal 12 time . month . should_equal 12
time . day . should_equal 1 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| 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 . year . should_equal 1969
time . month . should_equal 12 time . month . should_equal 12
time . day . should_equal 1 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| 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 . year . should_equal 1969
time . month . should_equal 12 time . month . should_equal 12
time . day . should_equal 1 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 . minute . should_equal 0
time . second . should_equal 0 time . second . should_equal 0
time . nanosecond . 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" <| Test.specify "should be comparable" <|
time_1 = parse_datetime "2021-01-01T00:30:12.7102[UTC]" 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_true
time_1<time_2 . should_be_false 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 = Date_Part_Spec.spec name create_new_datetime
Panic.catch Any (js_datetime_with_zone year month day hour minute second nanosecond zone) (err -> Error.throw (Time.Time_Error err.payload.cause))
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. # 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. # 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 (js_local_datetime_impl year month day hour minute second nanosecond) zone
js_set_zone local_datetime 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) diff = Duration.between datetime_with_tz local_datetime (timezone_aware=False)
datetime_with_tz + diff datetime_with_tz + diff
@ -323,8 +323,8 @@ js_parse text format=Nothing =
d = Date_Time.parse text format 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_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 = 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.Time_Error err.payload.cause)) 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 js_set_zone arr.at(0) zone
foreign js js_array_datetimeCreate year month day hour minute second nanosecond = """ 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) ]; 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 = 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.Time_Error <| err.payload.to_display_text.drop (Text_Sub_Range.First 16))) 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 = maybe_parse_java_zoned text pattern=Nothing =
if pattern == Nothing then ZonedDateTime.parse text else if pattern == Nothing then ZonedDateTime.parse text else
ZonedDateTime.parse text pattern ZonedDateTime.parse text pattern
parse_java_local original_error text pattern=Nothing = 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 Panic.catch Polyglot_Error handler=(_ -> Error.throw (Time_Error original_error.payload.cause.getMessage)) <|
formatter = DateTimeFormatter.ofPattern(pattern) if pattern.is_nothing then LocalDateTime.parse text else
Panic.catch Polyglot_Error (LocalDateTime.parse text formatter) (_ -> Error.throw (Time.Time_Error original_error.payload.cause.getMessage)) formatter = DateTimeFormatter.ofPattern pattern
LocalDateTime.parse text (formatter.withLocale Locale.default.java_locale)
java_parse date_text_raw pattern=Nothing = java_parse date_text_raw pattern=Nothing =
utc_replaced = date_text_raw.replace "[UTC]" "Z" 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 from Standard.Base import all
import Standard.Base.Data.Time.Duration import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Date_Time
import Standard.Test import Standard.Test
spec = spec =

View File

@ -1,14 +1,20 @@
from Standard.Base import all from Standard.Base import all
import Standard.Test
import project.Data.Time.Duration_Spec import project.Data.Time.Duration_Spec
import project.Data.Time.Time_Of_Day_Spec import project.Data.Time.Time_Of_Day_Spec
import project.Data.Time.Date_Spec import project.Data.Time.Date_Spec
import project.Data.Time.Time_Spec import project.Data.Time.Date_Time_Spec
import project.Data.Time.Zone_Spec import project.Data.Time.Time_Zone_Spec
import project.Data.Time.Day_Of_Week_Spec
spec = spec =
Date_Spec.spec Date_Spec.spec
Duration_Spec.spec Duration_Spec.spec
Time_Of_Day_Spec.spec Time_Of_Day_Spec.spec
Time_Spec.spec Date_Time_Spec.spec
Zone_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 from Standard.Base import all
import Standard.Base.Data.Time
import Standard.Base.Data.Time.Duration import Standard.Base.Data.Time.Duration
import Standard.Base.Data.Time.Time_Of_Day from Standard.Base.Error.Common import Time_Error
import Standard.Base.Data.Time.Zone
import Standard.Test import Standard.Test
@ -26,7 +23,7 @@ specWith name create_new_time parse_time =
Test.specify "should handle errors when creating a time" <| Test.specify "should handle errors when creating a time" <|
case create_new_time 24 0 0 . catch of 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" msg . should_equal "Invalid value for HourOfDay (valid values 0 - 23): 24"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) 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" <| Test.specify "should throw error when parsing invalid time" <|
case parse_time "1200" . catch of 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" msg . should_equal "Text '1200' could not be parsed at index 2"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) 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" <| Test.specify "should throw error when parsing custom format" <|
time = parse_time "12:30" "HH:mm:ss" time = parse_time "12:30" "HH:mm:ss"
case time.catch of case time.catch of
Time.Time_Error msg -> Time_Error msg ->
msg . should_equal "Text '12:30' could not be parsed at index 5" msg . should_equal "Text '12:30' could not be parsed at index 5"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should convert to time" <| 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 . year . should_equal 2000
datetime . month . should_equal 12 datetime . month . should_equal 12
datetime . day . should_equal 21 datetime . day . should_equal 21
@ -82,7 +79,7 @@ specWith name create_new_time parse_time =
datetime . minute . should_equal 0 datetime . minute . should_equal 0
datetime . second . should_equal 0 datetime . second . should_equal 0
datetime . nanosecond . 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" <| Test.specify "should add time-based interval" <|
time = create_new_time 0 + 1.minute 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" <| Test.specify "should throw error when adding date-based interval" <|
case (create_new_time 0 + 1.day) . catch of 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" message . should_equal "Time_Of_Day does not support date intervals"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) Test.fail ("Unexpected result: " + result.to_text)
Test.specify "should throw error when subtracting date-based interval" <| Test.specify "should throw error when subtracting date-based interval" <|
case (create_new_time 0 - (1.day - 1.minute)) . catch of 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" message . should_equal "Time_Of_Day does not support date intervals"
result -> result ->
Test.fail ("Unexpected result: " + result.to_text) 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 Time_Of_Day.new hour minute second nanoOfSecond
java_time hour minute=0 second=0 nanoOfSecond=0 = 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 = 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 Panic.catch Polyglot_Error handler=(err -> Error.throw (Time_Error err.payload.cause.getMessage)) <|
formatter = DateTimeFormatter.ofPattern(pattern) if pattern.is_nothing then LocalTime.parse time_text else
Panic.catch Polyglot_Error (LocalTime.parse time_text formatter) (err -> Error.throw (Time.Time_Error err.payload.cause.getMessage)) formatter = DateTimeFormatter.ofPattern pattern
LocalTime.parse time_text (formatter.withLocale Locale.default.java_locale)
main = Test.Suite.run_main spec main = Test.Suite.run_main spec

View File

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