diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/datetime.md | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/docs/datetime.md b/docs/datetime.md new file mode 100644 index 00000000..24215862 --- /dev/null +++ b/docs/datetime.md @@ -0,0 +1,435 @@ +# DateTime + +Tomo has a builtin datatype for representing a specific single point in time: +`DateTime`. A DateTime object is internally represented using a UNIX epoch in +seconds and a number of nanoseconds to represent sub-second times (in C, the +equivalent of `struct timeval`). DateTime values do not represent calendar +dates or clock times, they represent an exact moment in time, such as the +moment when a file was last modified on the filesystem or the current moment +(`DateTime.now()`). + +## Time Zones + +Because humans are not able to easily understand UNIX timestamps, the default +textual representation of `DateTime` objects uses the current locale's +preferred representation of the DateTime in the current time zone: + +```tomo +>> DateTime.now() += Sun Sep 29 18:20:12 2024 +``` + +For various methods, it is assumed by default that users wish to perform +calculations and specify datetimes using the local time zone and daylight +savings time rules. For example, if a program is running in New York and it is +currently 11pm on February 28th, 2023 (the last day of the month) in local +time, it is assumed that "one month from now" refers to 11pm on March 28th, +2024 in local time, rather than referring to one month from the current UTC +time. In that example, the initial time would be 3am March 1, 2023 in UTC, so +one month later would be 3am April 1, 2023 in UTC, which is which is 11am March +31st in local time. Most users would be unpleasantly surprised to find out that +when it's February 28th in local time, one month later is March 28th until 8pm, +at which point it becomes March 31st! For functions where this matters, there +is an extra `local_time` argument that is `yes` by default. + +## DateTime Methods + +### `after` + +**Description:** +Returns a DateTime that occurs after the specified time differences. Time +differences may be either positive or negative. + +**Note:** time offsets for days, months, weeks, and years do not refer to fixed +time intervals, but are relative to which date they are applied to. For +example, one year from January 1, 2024 is January 1, 2025, which is 366 days +later because 2024 is a leap year. Similarly, adding one month may add anywhere +from 28 to 31 days, depending on the starting month. Days and weeks are +affected by leap seconds. For this reason, `after()` takes an argument, +`local_time` which is used to determine whether time offsets should be +calculated using the current local time or UTC. + +**Usage:** +```markdown +datetime:after(seconds : Num = 0.0, minutes : Num = 0.0, hours : Num = 0.0, days : Int = 0, weeks : Int = 0, months : Int = 0, years : Int = 0, local_time : Bool = yes) -> DateTime +``` + +**Parameters:** + +- `seconds`: An amount of seconds to offset the datetime (default: 0). +- `minutes`: An amount of minutes to offset the datetime (default: 0). +- `hours`: An amount of hours to offset the datetime (default: 0). +- `days`: An amount of days to offset the datetime (default: 0). +- `weeks`: An amount of weeks to offset the datetime (default: 0). +- `months`: An amount of months to offset the datetime (default: 0). +- `years`: An amount of years to offset the datetime (default: 0). +- `local_time`: Whether to perform the calculations in local time (default: `yes`) or, if not, in UTC time. + +**Returns:** +A new `DateTime` offset by the given amount. + +**Example:** +```markdown +>> DateTime.new(2024, 9, 29, hour=19):after(days=1, minutes=30) += Mon Sep 30 19:30:00 2024 +``` + +--- + +### `date` + +**Description:** +Return a text representation of the datetime using the `"%F"` format +specifier, which gives the date in `YYYY-MM-DD` form. + +**Usage:** +```markdown +datetime:date(local_time : Bool = yes) -> Text +``` + +**Parameters:** + +- `local_time`: Whether to use local time (default: `yes`) or UTC. + +**Returns:** +The date in `YYYY-MM-DD` format. + +**Example:** +```markdown +>> DateTime.new(2024, 9, 29):format("%A") += "2024-09-29" +``` + +--- + +### `format` + +**Description:** +Using the C-style [`strftime`](https://linux.die.net/man/3/strftime) format +options, return a text representation of the given date in the given format. If +`local_time` is `no`, then use UTC instead of the current locale's timezone. + +**Usage:** +```markdown +datetime:format(format: Text = "%c", local_time : Bool = yes) -> Text +``` + +**Parameters:** + +- `path`: The path of the file to append to. +- `bytes`: The bytes to append to the file. +- `permissions` (optional): The permissions to set on the file if it is being created (default is `0o644`). + +**Returns:** +Nothing. + +**Example:** +```markdown +>> DateTime.new(2024, 9, 29):format("%A") += "Sunday" +``` + +--- + +### `from_unix_timestamp` + +**Description:** +Return a datetime object that represents the same moment in time as +the given UNIX epoch timestamp (seconds since January 1, 1970 UTC). + +**Usage:** +```markdown +DateTime.from_unix_timestamp(timestamp: Int64) -> DateTime +``` + +**Parameters:** + +- `timestamp`: The UNIX timestamp. + +**Returns:** +A `DateTime` object representing the same moment as the given UNIX timestamp. + +**Example:** +```markdown +# In the New York timezone: +>> DateTime.from_unix_timestamp(0) += Wed Dec 31 19:00:00 1969 +``` + +--- + +### `get` + +**Description:** +Get various components of the given datetime object and store them in the +provided optional fields. + +**Usage:** +```markdown +datetime:get(year : &Int? = !&Int, month : &Int? = !&Int, day : &Int? = !&Int, hour : &Int? = !&Int, minute : &Int? = !&Int, second : &Int? = !&Int, nanosecond : &Int? = !&Int, weekday : &Int? = !&Int, local_time=yes) -> Void +``` + +**Parameters:** + +- `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) +- `local_time`: Whether to use the local timezone (default: `yes`) or UTC. + +**Returns:** +Nothing. + +**Example:** +```markdown +dt := DateTime.new(2024, 9, 29) +month := 0 +dt:get(month=&month) +>> month += 9 +``` + +--- + +### `hours_till` + +**Description:** +Return the number of hours until a given datetime. + +**Usage:** +```markdown +datetime:hours_till(then:DateTime) -> Num +``` + +**Parameters:** + +- `then`: Another datetime that we want to calculate the time offset from (in hours). + +**Returns:** +The number of hours (possibly fractional, possibly negative) until the given time. + +**Example:** +```markdown +the_future := now():after(hours=1, minutes=30) +>> now():hours_till(the_future) += 1.5 +``` + +--- + +### `minutes_till` + +**Description:** +Return the number of minutes until a given datetime. + +**Usage:** +```markdown +datetime:minutes_till(then:DateTime) -> Num +``` + +**Parameters:** + +- `then`: Another datetime that we want to calculate the time offset from (in minutes). + +**Returns:** +The number of minutes (possibly fractional, possibly negative) until the given time. + +**Example:** +```markdown +the_future := now():after(minutes=1, seconds=30) +>> now():minutes_till(the_future) += 1.5 +``` + +--- + +### `new` + +**Description:** +Return a new `DateTime` object representing the given time parameters expressed +in local time. + +**Usage:** +```markdown +DateTime.new(year : Int, month : Int, day : Int, hour : Int = 0, minute : Int = 0, second : Num = 0.0) -> DateTime +``` + +**Parameters:** + +- `year`: The year. +- `month`: The month of the year (1-12). +- `day`: The day of the month (1-31). +- `hour`: The hour of the day (0-23) (default: 0). +- `minute`: The minute of the hour (0-59) (default: 0). +- `second`: The second of the minute (0-59) (default: 0.0). + +**Returns:** +A `DateTime` representing the given information in local time. If the given +parameters exceed reasonable bounds, the time values will wrap around. For +example, `DateTime.new(..., hour=3, minute=65)` is the same as +`DateTime.new(..., hour=4, minute=5)`. If any arguments cannot fit in a 32-bit +integer, an error will be raised. + +**Example:** +```markdown +>> DateTime.new(2024, 9, 29) += Mon Sep 30 00:00:00 2024 +``` + +--- + +### `parse` + +**Description:** +Return a new `DateTime` object parsed from the given string in the given format, +or a null value if the value could not be successfully parsed. + +**Usage:** +```markdown +DateTime.parse(text: Text, format: Text = "%c") -> DateTime? +``` + +**Parameters:** + +- `text`: The text to parse. +- `format`: The date format of the text being parsed (see: + [strptime](https://linux.die.net/man/3/strptime) for more info on this format) (default: `"%c"`). + +**Returns:** +If the text was successfully parsed according to the given format, return a +`DateTime` representing that information. Otherwise, return a null value. + +**Example:** +```markdown +>> DateTime.parse("2024-09-29", "%Y-%m-%d")! += Sun Sep 29 00:00:00 2024 + +>> DateTime.parse("???", "%Y-%m-%d") += !DateTime +``` + +--- + +### `relative` + +**Description:** +Return a plain English textual representation of the approximate time difference +between two `DateTime`s. For example: `5 minutes ago` or `1 day later` + +**Usage:** +```markdown +datetime:relative(relative_to : DateTime = DateTime.now(), local_time : Bool = yes) -> Text +``` + +**Parameters:** + +- `relative_to` (optional): The time against which the relative time is calculated (default: `DateTime.now()`). +- `local_time` (optional): Whether or not to perform calculations in local time (default: `yes`). + +**Returns:** +Return a plain English textual representation of the approximate time +difference between two `DateTime`s. For example: `5 minutes ago` or `1 day +later`. Return values are approximate and use only one significant unit of +measure with one significant digit, so a difference of 1.6 days will be +represented as `2 days later`. Datetimes in the past will have the suffix `" +ago"`, while datetimes in the future will have the suffix `" later"`. + +**Example:** +```markdown +>> now():after(days=2):relative() += "2 days later" + +>> now():after(minutes=-65):relative() += "1 hour ago" +``` + +--- + +### `seconds_till` + +**Description:** +Return the number of seconds until a given datetime. + +**Usage:** +```markdown +datetime:seconds_till(then:DateTime) -> Num +``` + +**Parameters:** + +- `then`: Another datetime that we want to calculate the time offset from (in seconds). + +**Returns:** +The number of seconds (possibly fractional, possibly negative) until the given time. + +**Example:** +```markdown +the_future := now():after(seconds=1) +>> now():seconds_till(the_future) += 1 +``` + +--- + +### `time` + +**Description:** +Return a text representation of the time component of the given datetime. + +**Usage:** +```markdown +datetime:time(seconds : Bool = no, am_pm : Bool = yes, local_time : Bool = yes) -> Text +``` + +**Parameters:** + +- `seconds`: Whether to include seconds in the time (default: `no`). +- `am_pm`: Whether to use am/pm in the representation or use a 24-hour clock (default: `yes`). +- `local_time`: Whether to use local time (default: `yes`) or UTC. + +**Returns:** +A text representation of the time component of the datetime. + +**Example:** +```markdown +dt := DateTime.new(2024, 9, 29, hours=13, minutes=59, seconds=30) + +>> dt:time() += "1:59pm" + +>> dt:time(am_pm=no) += "13:59" + +>> dt:time(seconds=yes) += "1:59:30pm" +``` + +--- + +### `unix_timestamp` + +**Description:** +Get the UNIX timestamp of the given datetime (seconds since the UNIX epoch: +January 1, 1970 UTC). + +**Usage:** +```markdown +datetime:unix_timestamp() -> Int64 +``` + +**Parameters:** + +None. + +**Returns:** +A 64-bit integer representation of the UNIX timestamp. + +**Example:** +```markdown +>> now():unix_timestamp() += 1727654730[64] +``` |
