mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 15:21:43 +03:00
Add day_of_week
and day_of_year
to Column and DB_Column (#10081)
- Adds support for getting the weekday as an integer (1 Monday - 7 Sunday - ISO standard). - Add support for getting the day of year.
This commit is contained in:
parent
200da1ad50
commit
ab4b1f0f35
@ -667,6 +667,7 @@
|
||||
- [Added ability to save an existing Postgres connection as a Data Link in Enso
|
||||
Cloud.][9957]
|
||||
- [Improved `Table.union`.][9968]
|
||||
- [Add `day_of_week` and `day_of_year` to `Column`.][10081]
|
||||
|
||||
[debug-shortcuts]:
|
||||
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
|
||||
@ -980,6 +981,7 @@
|
||||
[9879]: https://github.com/enso-org/enso/pull/9879
|
||||
[9957]: https://github.com/enso-org/enso/pull/9957
|
||||
[9968]: https://github.com/enso-org/enso/pull/9968
|
||||
[10081]: https://github.com/enso-org/enso/pull/10081
|
||||
|
||||
#### Enso Compiler
|
||||
|
||||
|
@ -1520,6 +1520,29 @@ type DB_Column
|
||||
day self = Value_Type.expect_has_date self <|
|
||||
self.make_unary_op "day"
|
||||
|
||||
## GROUP Standard.Base.DateTime
|
||||
ICON date_and_time
|
||||
Gets the day of the year as a number (1 - 366) from the date stored in
|
||||
the column.
|
||||
|
||||
Applies only to columns that hold the `Date` or `Date_Time` types.
|
||||
Returns a column of `Integer` type.
|
||||
day_of_year : DB_Column ! Invalid_Value_Type
|
||||
day_of_year self = Value_Type.expect_has_date self <|
|
||||
self.make_unary_op "day_of_year"
|
||||
|
||||
## ALIAS weekday
|
||||
GROUP Standard.Base.DateTime
|
||||
ICON date_and_time
|
||||
Gets the weekday as a number (1 - 7) from the date stored in the column.
|
||||
Monday is 1, Tuesday is 2, ..., Sunday is 7.
|
||||
|
||||
Applies only to columns that hold the `Date` or `Date_Time` types.
|
||||
Returns a column of `Integer` type.
|
||||
day_of_week : DB_Column ! Invalid_Value_Type
|
||||
day_of_week self = Value_Type.expect_has_date self <|
|
||||
self.make_unary_op "day_of_week"
|
||||
|
||||
## GROUP Standard.Base.DateTime
|
||||
ICON time
|
||||
Gets the hour as a number (0-23) from the time stored in the column.
|
||||
|
@ -280,7 +280,7 @@ make_internal_generator_dialect =
|
||||
stddev_pop = ["STDDEV_POP", Base_Generator.make_function "stddev_pop"]
|
||||
stddev_samp = ["STDDEV_SAMP", Base_Generator.make_function "stddev_samp"]
|
||||
stats = [agg_median, agg_mode, agg_percentile, stddev_pop, stddev_samp]
|
||||
date_ops = [make_extract_as_int "year", make_extract_as_int "quarter", make_extract_as_int "month", make_extract_as_int "week", make_extract_as_int "day", make_extract_as_int "hour", make_extract_as_int "minute", make_extract_fractional_as_int "second", make_extract_fractional_as_int "millisecond" modulus=1000, make_extract_fractional_as_int "microsecond" modulus=1000, ["date_add", make_date_add], ["date_diff", make_date_diff], ["date_trunc_to_day", make_date_trunc_to_day]]
|
||||
date_ops = [make_extract_as_int "year", make_extract_as_int "quarter", make_extract_as_int "month", make_extract_as_int "week", make_extract_as_int "day", make_extract_as_int "day_of_week" "isodow", make_extract_as_int "day_of_year" "doy", make_extract_as_int "hour", make_extract_as_int "minute", make_extract_fractional_as_int "second", make_extract_fractional_as_int "millisecond" modulus=1000, make_extract_fractional_as_int "microsecond" modulus=1000, ["date_add", make_date_add], ["date_diff", make_date_diff], ["date_trunc_to_day", make_date_trunc_to_day]]
|
||||
special_overrides = [is_null, is_empty]
|
||||
other = [["RUNTIME_ERROR", make_runtime_error_op]]
|
||||
my_mappings = text + counts + stats + first_last_aggregators + arith_extensions + bool + date_ops + special_overrides + other
|
||||
|
@ -1523,6 +1523,29 @@ type Column
|
||||
day self = Value_Type.expect_has_date self <|
|
||||
apply_unary_operation self DatePartOperation.DAY_INSTANCE
|
||||
|
||||
## GROUP Standard.Base.DateTime
|
||||
ICON date_and_time
|
||||
Gets the day of the year as a number (1 - 366) from the date stored in
|
||||
the column.
|
||||
|
||||
Applies only to columns that hold the `Date` or `Date_Time` types.
|
||||
Returns a column of `Integer` type.
|
||||
day_of_year : Column ! Invalid_Value_Type
|
||||
day_of_year self = Value_Type.expect_has_date self <|
|
||||
apply_unary_operation self DatePartOperation.DAY_OF_YEAR_INSTANCE
|
||||
|
||||
## ALIAS weekday
|
||||
GROUP Standard.Base.DateTime
|
||||
ICON date_and_time
|
||||
Gets the weekday as a number (1 - 7) from the date stored in the column.
|
||||
Monday is 1, Tuesday is 2, ..., Sunday is 7.
|
||||
|
||||
Applies only to columns that hold the `Date` or `Date_Time` types.
|
||||
Returns a column of `Integer` type.
|
||||
day_of_week : Column ! Invalid_Value_Type
|
||||
day_of_week self = Value_Type.expect_has_date self <|
|
||||
apply_unary_operation self DatePartOperation.DAY_OF_WEEK_INSTANCE
|
||||
|
||||
## GROUP Standard.Base.DateTime
|
||||
ICON time
|
||||
Gets the hour as a number (0-23) from the time stored in the column.
|
||||
|
@ -31,6 +31,14 @@ public class DatePartOperation extends AbstractUnaryLongOperation {
|
||||
public static final UnaryOperation DAY_INSTANCE =
|
||||
new DatePartOperation(DAY, ChronoField.DAY_OF_MONTH, false);
|
||||
|
||||
public static final String DAY_OF_YEAR = "day_of_year";
|
||||
public static final UnaryOperation DAY_OF_YEAR_INSTANCE =
|
||||
new DatePartOperation(DAY_OF_YEAR, ChronoField.DAY_OF_YEAR, false);
|
||||
|
||||
public static final String DAY_OF_WEEK = "day_of_week";
|
||||
public static final UnaryOperation DAY_OF_WEEK_INSTANCE =
|
||||
new DatePartOperation(DAY_OF_WEEK, ChronoField.DAY_OF_WEEK, false);
|
||||
|
||||
public static final String HOUR = "hour";
|
||||
public static final UnaryOperation HOUR_INSTANCE =
|
||||
new DatePartOperation(HOUR, ChronoField.HOUR_OF_DAY, true);
|
||||
|
@ -22,9 +22,9 @@ type Data
|
||||
|
||||
setup create_connection_fn table_builder = Data.Value <|
|
||||
connection = create_connection_fn Nothing
|
||||
dates = table_builder [["A", [Date.new 2020 12 31, Date.new 2024 2 29, Date.new 1990 1 1, Nothing]], ["X", [2020, 29, 1, 100]]] connection=connection
|
||||
dates = table_builder [["A", [Date.new 2020 12 31, Date.new 2024 2 29, Date.new 1990 1 1, Nothing, Date.new 2024 5 26]], ["X", [2020, 29, 1, 100, 99]]] connection=connection
|
||||
times = table_builder [["A", [Time_Of_Day.new 23 59 59 millisecond=567 nanosecond=123, Time_Of_Day.new 2 30 44 nanosecond=1002000, Time_Of_Day.new 0 0 0, Nothing]], ["X", [2020, 29, 1, 100]]] connection=connection
|
||||
datetimes = table_builder [["A", [Date_Time.new 2020 12 31 23 59 59 millisecond=567 nanosecond=123, Date_Time.new 2024 2 29 2 30 44 nanosecond=1002000, Date_Time.new 1990 1 1 0 0 0, Nothing]], ["X", [2020, 29, 1, 100]]] connection=connection
|
||||
datetimes = table_builder [["A", [Date_Time.new 2020 12 31 23 59 59 millisecond=567 nanosecond=123, Date_Time.new 2024 2 29 2 30 44 nanosecond=1002000, Date_Time.new 1990 1 1 0 0 0, Nothing, Date_Time.new 2024 5 26 11 43 22]], ["X", [2020, 29, 1, 100, 99]]] connection=connection
|
||||
[connection, dates, times, datetimes]
|
||||
|
||||
teardown self =
|
||||
@ -84,34 +84,38 @@ add_specs suite_builder setup =
|
||||
table_builder cols =
|
||||
setup.table_builder cols connection=data.connection
|
||||
|
||||
group_builder.specify "should allow to get the year/month/day of a Date" <|
|
||||
group_builder.specify "should allow to get the year/month/day/day_of_year/day_of_week of a Date" <|
|
||||
t = data.dates
|
||||
a = t.at "A"
|
||||
a.year . to_vector . should_equal [2020, 2024, 1990, Nothing]
|
||||
a.month . to_vector . should_equal [12, 2, 1, Nothing]
|
||||
a.day . to_vector . should_equal [31, 29, 1, Nothing]
|
||||
[a.year, a.month, a.day].each c->
|
||||
a.year . to_vector . should_equal [2020, 2024, 1990, Nothing, 2024]
|
||||
a.month . to_vector . should_equal [12, 2, 1, Nothing, 5]
|
||||
a.day . to_vector . should_equal [31, 29, 1, Nothing, 26]
|
||||
a.day_of_year . to_vector . should_equal [366, 60, 1, Nothing, 147]
|
||||
a.day_of_week . to_vector . should_equal [4, 4, 1, Nothing, 7]
|
||||
[a.year, a.month, a.day, a.day_of_year, a.day_of_week].each c->
|
||||
Test.with_clue "The column "+c.name+" value type ("+c.value_type.to_display_text+") should be an integer: " <|
|
||||
c.value_type.is_integer.should_be_true
|
||||
c.value_type.is_integer.should_be_true
|
||||
|
||||
((a.year) == (t.at "X")).to_vector . should_equal [True, False, False, Nothing]
|
||||
((a.month) == (t.at "X")).to_vector . should_equal [False, False, True, Nothing]
|
||||
((a.day) == (t.at "X")).to_vector . should_equal [False, True, True, Nothing]
|
||||
((a.year) == (t.at "X")).to_vector . should_equal [True, False, False, Nothing, False]
|
||||
((a.month) == (t.at "X")).to_vector . should_equal [False, False, True, Nothing, False]
|
||||
((a.day) == (t.at "X")).to_vector . should_equal [False, True, True, Nothing, False]
|
||||
|
||||
group_builder.specify "should allow to get the year/month/day of a Date_Time" <|
|
||||
group_builder.specify "should allow to get the year/month/day/day_of_year/day_of_week of a Date_Time" <|
|
||||
t = data.datetimes
|
||||
a = t.at "A"
|
||||
a.year . to_vector . should_equal [2020, 2024, 1990, Nothing]
|
||||
a.month . to_vector . should_equal [12, 2, 1, Nothing]
|
||||
a.day . to_vector . should_equal [31, 29, 1, Nothing]
|
||||
[a.year, a.month, a.day].each c->
|
||||
a.year . to_vector . should_equal [2020, 2024, 1990, Nothing, 2024]
|
||||
a.month . to_vector . should_equal [12, 2, 1, Nothing, 5]
|
||||
a.day . to_vector . should_equal [31, 29, 1, Nothing, 26]
|
||||
a.day_of_year . to_vector . should_equal [366, 60, 1, Nothing, 147]
|
||||
a.day_of_week . to_vector . should_equal [4, 4, 1, Nothing, 7]
|
||||
[a.year, a.month, a.day, a.day_of_year, a.day_of_week].each c->
|
||||
Test.with_clue "The column "+c.name+" value type ("+c.value_type.to_display_text+") should be an integer: " <|
|
||||
c.value_type.is_integer.should_be_true
|
||||
|
||||
((a.year) == (t.at "X")).to_vector . should_equal [True, False, False, Nothing]
|
||||
((a.month) == (t.at "X")).to_vector . should_equal [False, False, True, Nothing]
|
||||
((a.day) == (t.at "X")).to_vector . should_equal [False, True, True, Nothing]
|
||||
((a.year) == (t.at "X")).to_vector . should_equal [True, False, False, Nothing, False]
|
||||
((a.month) == (t.at "X")).to_vector . should_equal [False, False, True, Nothing, False]
|
||||
((a.day) == (t.at "X")).to_vector . should_equal [False, True, True, Nothing, False]
|
||||
|
||||
group_builder.specify "should allow to evaluate expressions with year/month/day" <|
|
||||
t = table_builder [["A", [Date.new 2020 12 31, Date.new 2024 2 29, Date.new 1990 1 1, Nothing]], ["X", [0, 2, 1, 100]], ["B", [Date_Time.new 2020 10 31 23 59 59, Date_Time.new 2024 4 29 2 30 44, Date_Time.new 1990 10 1 0 0 0, Nothing]]]
|
||||
@ -136,13 +140,13 @@ add_specs suite_builder setup =
|
||||
|
||||
group_builder.specify "should allow to get hour/minute/second of a Date_Time" <|
|
||||
a = data.datetimes.at "A"
|
||||
a.hour . to_vector . should_equal [23, 2, 0, Nothing]
|
||||
a.minute . to_vector . should_equal [59, 30, 0, Nothing]
|
||||
a.second . to_vector . should_equal [59, 44, 0, Nothing]
|
||||
a.hour . to_vector . should_equal [23, 2, 0, Nothing, 11]
|
||||
a.minute . to_vector . should_equal [59, 30, 0, Nothing, 43]
|
||||
a.second . to_vector . should_equal [59, 44, 0, Nothing, 22]
|
||||
|
||||
a.date_part Time_Period.Hour . to_vector . should_equal [23, 2, 0, Nothing]
|
||||
a.date_part Time_Period.Minute . to_vector . should_equal [59, 30, 0, Nothing]
|
||||
a.date_part Time_Period.Second . to_vector . should_equal [59, 44, 0, Nothing]
|
||||
a.date_part Time_Period.Hour . to_vector . should_equal [23, 2, 0, Nothing, 11]
|
||||
a.date_part Time_Period.Minute . to_vector . should_equal [59, 30, 0, Nothing, 43]
|
||||
a.date_part Time_Period.Second . to_vector . should_equal [59, 44, 0, Nothing, 22]
|
||||
|
||||
[a.hour, a.minute, a.second, a.date_part Time_Period.Hour, a.date_part Time_Period.Minute, a.date_part Time_Period.Second].each c->
|
||||
Test.with_clue "The column "+c.name+" value type ("+c.value_type.to_display_text+") should be an integer: " <|
|
||||
@ -168,8 +172,8 @@ add_specs suite_builder setup =
|
||||
|
||||
group_builder.specify "should allow to get week/quarter of Date through date_part" <|
|
||||
a = data.dates.at "A"
|
||||
a.date_part Date_Period.Quarter . to_vector . should_equal [4, 1, 1, Nothing]
|
||||
a.date_part Date_Period.Week . to_vector . should_equal [53, 9, 1, Nothing]
|
||||
a.date_part Date_Period.Quarter . to_vector . should_equal [4, 1, 1, Nothing, 2]
|
||||
a.date_part Date_Period.Week . to_vector . should_equal [53, 9, 1, Nothing, 21]
|
||||
|
||||
[a.date_part Date_Period.Quarter, a.date_part Date_Period.Week].each c->
|
||||
Test.with_clue "The column "+c.name+" value type ("+c.value_type.to_display_text+") should be an integer: " <|
|
||||
@ -177,13 +181,13 @@ add_specs suite_builder setup =
|
||||
|
||||
group_builder.specify "should allow to get various date_part of Date_Time" <|
|
||||
a = data.datetimes.at "A"
|
||||
a.date_part Date_Period.Quarter . to_vector . should_equal [4, 1, 1, Nothing]
|
||||
a.date_part Date_Period.Week . to_vector . should_equal [53, 9, 1, Nothing]
|
||||
a.date_part Time_Period.Millisecond . to_vector . should_equal [567, 1, 0, Nothing]
|
||||
a.date_part Time_Period.Microsecond . to_vector . should_equal [0, 2, 0, Nothing]
|
||||
a.date_part Date_Period.Quarter . to_vector . should_equal [4, 1, 1, Nothing, 2]
|
||||
a.date_part Date_Period.Week . to_vector . should_equal [53, 9, 1, Nothing, 21]
|
||||
a.date_part Time_Period.Millisecond . to_vector . should_equal [567, 1, 0, Nothing, 0]
|
||||
a.date_part Time_Period.Microsecond . to_vector . should_equal [0, 2, 0, Nothing, 0]
|
||||
case setup.test_selection.supports_nanoseconds_in_time of
|
||||
True ->
|
||||
a.date_part Time_Period.Nanosecond . to_vector . should_equal [123, 0, 0, Nothing]
|
||||
a.date_part Time_Period.Nanosecond . to_vector . should_equal [123, 0, 0, Nothing, 0]
|
||||
False ->
|
||||
a.date_part Time_Period.Nanosecond . should_fail_with Unsupported_Database_Operation
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user