aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-10-27 18:41:00 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-10-27 18:41:00 -0400
commit0d615443dc452f85f3d6b1b2c82d92a9c8db1fff (patch)
tree4fcc37c20916a3abe2bd6413bb129e1a663ed2e8
parentf4d22958f70924f630265467c847d2352f4a34c1 (diff)
Update DateTime API to have separate methods for getting each component
instead of get(...)
-rw-r--r--docs/datetime.md237
-rw-r--r--environment.c10
-rw-r--r--stdlib/datetime.c62
-rw-r--r--stdlib/datetime.h10
-rw-r--r--test/datetime.tm4
5 files changed, 284 insertions, 39 deletions
diff --git a/docs/datetime.md b/docs/datetime.md
index 96eda14a..334c615b 100644
--- a/docs/datetime.md
+++ b/docs/datetime.md
@@ -133,6 +133,85 @@ The date in `YYYY-MM-DD` format.
---
+### `day_of_month`
+
+**Description:**
+Return the integer day of the month (1-31).
+
+**Signature:**
+```tomo
+func day_of_month(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the day of the month from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The day of the month as an integer (1-31).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29):day_of_month()
+= 29
+```
+
+---
+
+### `day_of_week`
+
+**Description:**
+Return the integer day of the week (1-7), where 1 = Sunday, 2 = Monday,
+3 = Tuesday, 4 = Wednesday, 5 = Thursday, 6 = Friday, 7 = Saturday.
+
+**Signature:**
+```tomo
+func day_of_week(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the day of the week from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The day of the week as an integer (1-7).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29):day_of_week()
+= 1
+```
+
+---
+
+### `day_of_year`
+
+**Description:**
+Return the integer day of the year (1-366, including leap years).
+
+**Signature:**
+```tomo
+func day_of_year(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the day of the year from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The day of the year as an integer (1-366).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29):day_of_year()
+= 272
+```
+
+---
+
### `format`
**Description:**
@@ -188,69 +267,55 @@ A `DateTime` object representing the same moment as the given UNIX timestamp.
= Wed Dec 31 19:00:00 1969
```
----
-
-### `get`
+### `get_local_timezone`
-**Description:**
-Get various components of the given datetime object and store them in the
-provided optional fields.
+**Description:**
+Get the local timezone's name (e.g. `America/New_York` or `UTC`. By default,
+this value is read from `/etc/localtime`, however, this can be overridden by
+calling `DateTime.set_local_timezone(...)`.
**Signature:**
```tomo
-func get(datetime: DateTime, year : &Int? = !&Int, month : &Int? = !&Int, day : &Int? = !&Int, hour : &Int? = !&Int, minute : &Int? = !&Int, second : &Int? = !&Int, nanosecond : &Int? = !&Int, weekday : &Int? = !&Int, timezone : Text? = !Text -> Void)
+func get_local_timezone(->Text)
```
**Parameters:**
-- `datetime`: The datetime from which to extract information.
-- `year`: If non-null, store the year here.
-- `month`: If non-null, store the month here (1-12).
-- `day`: If non-null, store the day of the month here (1-31).
-- `hour`: If non-null, store the hour of the day here (0-23).
-- `minute`: If non-null, store the minute of the hour here (0-59).
-- `second`: If non-null, store the second of the minute here (0-59).
-- `nanosecond`: If non-null, store the nanosecond of the second here (0-1,000,000,000).
-- `weekday`: If non-null, store the day of the week here (sunday=1, saturday=7)
-- `timezone` (optional): If specified, give values in the given timezone (otherwise, use the current local timezone).
+None.
**Returns:**
-Nothing.
+The name of the current local timezone.
**Example:**
```tomo
-dt := DateTime(2024, 9, 29)
-month := 0
-dt:get(month=&month)
->> month
-= 9
+>> DateTime.get_local_timezone()
+= "America/New_York"
```
---
-### `get_local_timezone`
+### `hour`
-**Description:**
-Get the local timezone's name (e.g. `America/New_York` or `UTC`. By default,
-this value is read from `/etc/localtime`, however, this can be overridden by
-calling `DateTime.set_local_timezone(...)`.
+**Description:**
+Return the hour of the day as an integer (1-24).
**Signature:**
```tomo
-func get_local_timezone(->Text)
+func hour(datetime: DateTime, timezone : Text? = !Text -> Int)
```
**Parameters:**
-None.
+- `datetime`: The datetime to get the hour from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
-**Returns:**
-The name of the current local timezone.
+**Returns:**
+The hour of the day as an integer (1-24).
**Example:**
```tomo
->> DateTime.get_local_timezone()
-= "America/New_York"
+>> DateTime(2024, 9, 29, 11, 59):hour()
+= 11
```
---
@@ -282,6 +347,32 @@ the_future := now():after(hours=1, minutes=30)
---
+### `minute`
+
+**Description:**
+Return the minute of the day as an integer (0-59).
+
+**Signature:**
+```tomo
+func minute(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the minute from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The minute of the hour as an integer (0-59).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29, 11, 59):minute()
+= 59
+```
+
+---
+
### `minutes_till`
**Description:**
@@ -309,6 +400,58 @@ the_future := now():after(minutes=1, seconds=30)
---
+### `month`
+
+**Description:**
+Return the month of the year as an integer (1-12).
+
+**Signature:**
+```tomo
+func month(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the month from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The month of the year as an integer (1-12).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29, 11, 59):month()
+= 9
+```
+
+---
+
+### `nanosecond`
+
+**Description:**
+Return the nanosecond of the second as an integer (0-999,999,999).
+
+**Signature:**
+```tomo
+func nanosecond(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the nanosecond from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The nanosecond of the second as an integer (0-999,999,999).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29, 11, 59):month()
+= 9
+```
+
+---
+
### `new`
**Description:**
@@ -445,6 +588,32 @@ ago"`, while datetimes in the future will have the suffix `" later"`.
---
+### `second`
+
+**Description:**
+Return the second of the minute as an integer (0-59).
+
+**Signature:**
+```tomo
+func second(datetime: DateTime, timezone : Text? = !Text -> Int)
+```
+
+**Parameters:**
+
+- `datetime`: The datetime to get the second from.
+- `timezone` (optional): If specified, use the given timezone (otherwise, use the current local timezone).
+
+**Returns:**
+The second of the hour as an integer (0-59).
+
+**Example:**
+```tomo
+>> DateTime(2024, 9, 29, 11, 30, 59):second()
+= 59
+```
+
+---
+
### `seconds_till`
**Description:**
diff --git a/environment.c b/environment.c
index a6b68b91..cab39a0c 100644
--- a/environment.c
+++ b/environment.c
@@ -267,19 +267,27 @@ env_t *new_compilation_unit(CORD libname)
{"after", "DateTime$after", "func(dt:DateTime,seconds,minutes,hours=0.0,days,weeks,months,years=0,timezone=!Text -> DateTime)"},
{"date", "DateTime$date", "func(dt:DateTime,timezone=!Text -> Text)"},
+ {"day_of_month", "DateTime$day_of_month", "func(dt:DateTime,timezone=!Text -> Int)"},
+ {"day_of_week", "DateTime$day_of_week", "func(dt:DateTime,timezone=!Text -> Int)"},
+ {"day_of_year", "DateTime$day_of_year", "func(dt:DateTime,timezone=!Text -> Int)"},
{"format", "DateTime$format", "func(dt:DateTime,format=\"%Y-%m-%dT%H:%M:%S%z\",timezone=!Text -> Text)"},
{"from_unix_timestamp", "DateTime$from_unix_timestamp", "func(timestamp:Int64 -> DateTime)"},
- {"get", "DateTime$get", "func(dt:DateTime,year,month,day,hour,minute,second,nanosecond,weekday=!&Int,timezone=!Text)"},
{"get_local_timezone", "DateTime$get_local_timezone", "func(->Text)"},
+ {"hour", "DateTime$hour", "func(dt:DateTime,timezone=!Text -> Int)"},
{"hours_till", "DateTime$hours_till", "func(now,then:DateTime -> Num)"},
+ {"minute", "DateTime$minute", "func(dt:DateTime,timezone=!Text -> Int)"},
{"minutes_till", "DateTime$minutes_till", "func(now,then:DateTime -> Num)"},
+ {"month", "DateTime$month", "func(dt:DateTime,timezone=!Text -> Int)"},
+ {"nanosecond", "DateTime$nanosecond", "func(dt:DateTime,timezone=!Text -> Int)"},
{"new", "DateTime$new", "func(year,month,day:Int,hour,minute=0,second=0.0,timezone=!Text -> DateTime)"},
{"parse", "DateTime$parse", "func(text:Text, format=\"%Y-%m-%dT%H:%M:%S%z\" -> DateTime?)"},
{"relative", "DateTime$relative", "func(dt:DateTime,relative_to=DateTime.now(),timezone=!Text -> Text)"},
+ {"second", "DateTime$second", "func(dt:DateTime,timezone=!Text -> Int)"},
{"seconds_till", "DateTime$seconds_till", "func(now:DateTime,then:DateTime -> Num)"},
{"set_local_timezone", "DateTime$set_local_timezone", "func(timezone=!Text)"},
{"time", "DateTime$time", "func(dt:DateTime,seconds=no,am_pm=yes,timezone=!Text -> Text)"},
{"unix_timestamp", "DateTime$unix_timestamp", "func(dt:DateTime -> Int64)"},
+ {"year", "DateTime$year", "func(dt:DateTime,timezone=!Text -> Int)"},
)},
{"Path", Type(TextType, .lang="Path", .env=namespace_env(env, "Path")), "Text_t", "Text$info", TypedArray(ns_entry_t,
{"append", "Path$append", "func(path:Path, text:Text, permissions=0o644[32])"},
diff --git a/stdlib/datetime.c b/stdlib/datetime.c
index 9fa4f8cd..98c23a8e 100644
--- a/stdlib/datetime.c
+++ b/stdlib/datetime.c
@@ -124,6 +124,68 @@ public void DateTime$get(
if (weekday) *weekday = I(info.tm_wday + 1);
}
+public Int_t DateTime$year(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_year + 1900);
+}
+
+public Int_t DateTime$month(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_mon + 1);
+}
+
+public Int_t DateTime$day_of_week(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_wday + 1);
+}
+
+public Int_t DateTime$day_of_month(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_mday);
+}
+
+public Int_t DateTime$day_of_year(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_yday);
+}
+
+public Int_t DateTime$hour(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_hour);
+}
+
+public Int_t DateTime$minute(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_min);
+}
+
+public Int_t DateTime$second(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_sec);
+}
+
+public Int_t DateTime$nanosecond(DateTime_t dt, OptionalText_t timezone)
+{
+ (void)timezone;
+ return I(dt.tv_usec);
+}
+
public Text_t DateTime$format(DateTime_t dt, Text_t fmt, OptionalText_t timezone)
{
struct tm info;
diff --git a/stdlib/datetime.h b/stdlib/datetime.h
index 96669aa3..ccbc5190 100644
--- a/stdlib/datetime.h
+++ b/stdlib/datetime.h
@@ -18,7 +18,15 @@ DateTime_t DateTime$after(DateTime_t dt, double seconds, double minutes, double
CONSTFUNC double DateTime$seconds_till(DateTime_t now, DateTime_t then);
CONSTFUNC double DateTime$minutes_till(DateTime_t now, DateTime_t then);
CONSTFUNC double DateTime$hours_till(DateTime_t now, DateTime_t then);
-void DateTime$get(DateTime_t dt, Int_t *year, Int_t *month, Int_t *day, Int_t *hour, Int_t *minute, Int_t *second, Int_t *nanosecond, Int_t *weekday, OptionalText_t timezone);
+Int_t DateTime$year(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$month(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$day_of_week(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$day_of_month(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$day_of_year(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$hour(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$minute(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$second(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$nanosecond(DateTime_t dt, OptionalText_t timezone);
Text_t DateTime$format(DateTime_t dt, Text_t fmt, OptionalText_t timezone);
Text_t DateTime$date(DateTime_t dt, OptionalText_t timezone);
Text_t DateTime$time(DateTime_t dt, bool seconds, bool am_pm, OptionalText_t timezone);
diff --git a/test/datetime.tm b/test/datetime.tm
index 37559996..19ca74b0 100644
--- a/test/datetime.tm
+++ b/test/datetime.tm
@@ -29,9 +29,7 @@ func main():
>> t:hours_till(t:after(minutes=60))
= 1
- weekday := 0
- >> t:get(weekday=&weekday)
- >> weekday # 1 = Sun, 2 = Mon, 3 = Tue
+ >> t:day_of_week() # 1 = Sun, 2 = Mon, 3 = Tue
= 3
>> t:format("%A")