feat(stdlib): Time/Date/Duration calendar-clock core (issue #9)
Some checks are pending
docs / build-and-deploy (push) Waiting to run
Some checks are pending
docs / build-and-deploy (push) Waiting to run
Implement the calendar/clock half of #9 as plain-i32 integer epochs — no new type, no floating point (the issue's "integer epochs to avoid drift") — so every operation is deterministic and bit-identical on every platform: Duration — a span in whole seconds; seconds/minutes/hours/days build one, as_seconds/as_minutes/as_hours/as_days read it back. Because a duration is just an int, `+` and `>` work with no extra machinery (Duration.minutes(5) + Duration.seconds(30), away > Duration.hours(3)). Date — a civil day as days-since-1970 (UTC): new/year/month/day/weekday/ is_leap/days_in_month/to_epoch/add_days/diff_days. DateTime — an instant as seconds-since-1970 (UTC, matching Time.now): from/date/add/year/month/day/weekday/hour/minute/second. Time.since(past) = now - past, for offline-progress / "time away" checks. New selfhost/emit_datetime.ludic (is_/emit_ for the three namespaces, wired into emit_ns_call + the frag list). The two civil<->epoch conversions are Howard Hinnant's public-domain proleptic-Gregorian algorithms, emitted once per program as the @fn_days_from_civil / @fn_civil_from_days prelude and gated by g_uses_datert; days_in_month is next-month-day-0 (no lookup table). Time gains `since`. Docs (Duration/Date/DateTime sections, 28 method pages + time-since), inventory, and LSP hover kept in sync; a registered test checks component math against hand-computed values. Reseeded; C-free fixpoint holds; all suites green (26 self-host / 45 regression / 29 tools); check.py, check-impl.py and validate.py OK. format/parse, a game-controlled simulated clock, and timezones are tracked follow-ups; v1 is UTC-only and, on the i32 epoch, valid through 2038. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
121053e179
commit
1a2c6ec2c7
43 changed files with 10670 additions and 7626 deletions
7
docs/language/date/_section.md
Normal file
7
docs/language/date/_section.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
id: date
|
||||
title: Date
|
||||
order: 6
|
||||
---
|
||||
|
||||
Calendar days on the proleptic Gregorian calendar (UTC). A <code>Date</code> is stored as a plain <code>int</code>: the count of days since 1970-01-01, so shifting a date by whole days is ordinary integer arithmetic and two dates subtract to a day count. Build one with <code>Date.new</code>, read its parts with <code>year</code>/<code>month</code>/<code>day</code>/<code>weekday</code>. Every operation is deterministic integer math — no leap seconds, no timezone, no floating point.
|
||||
22
docs/language/date/date-add_days.md
Normal file
22
docs/language/date/date-add_days.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-add_days
|
||||
name: Date.add_days
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.add_days
|
||||
sig: Date.add_days(date, n) -> int
|
||||
tip: The date n days later (n may be negative).
|
||||
order: 8
|
||||
ns: Date
|
||||
member: add_days
|
||||
---
|
||||
|
||||
The <code>Date</code> that is <code>n</code> days after <code>date</code>; pass a negative <code>n</code> to go backward. Rolls across month and year boundaries automatically.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let tomorrow = Date.add_days(Date.new(2026, 12, 31), 1) # 2027-01-01
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-day.md
Normal file
22
docs/language/date/date-day.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-day
|
||||
name: Date.day
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.day
|
||||
sig: Date.day(date) -> int
|
||||
tip: The day of the month (1-31) of a date.
|
||||
order: 3
|
||||
ns: Date
|
||||
member: day
|
||||
---
|
||||
|
||||
The day of the month of a <code>Date</code>, from <code>1</code> to <code>31</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let d = Date.day(Date.new(2026, 8, 30)) # 30
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-days_in_month.md
Normal file
22
docs/language/date/date-days_in_month.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-days_in_month
|
||||
name: Date.days_in_month
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.days_in_month
|
||||
sig: Date.days_in_month(year, month) -> int
|
||||
tip: Number of days in a given month.
|
||||
order: 6
|
||||
ns: Date
|
||||
member: days_in_month
|
||||
---
|
||||
|
||||
The number of days in <code>month</code> of <code>year</code> (28–31), accounting for leap Februaries.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let n = Date.days_in_month(2024, 2) # 29
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-diff_days.md
Normal file
22
docs/language/date/date-diff_days.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-diff_days
|
||||
name: Date.diff_days
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.diff_days
|
||||
sig: Date.diff_days(a, b) -> int
|
||||
tip: Whole days from b to a (a - b).
|
||||
order: 9
|
||||
ns: Date
|
||||
member: diff_days
|
||||
---
|
||||
|
||||
The number of whole days from <code>b</code> to <code>a</code> (that is, <code>a - b</code>). Negative when <code>a</code> precedes <code>b</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let gap = Date.diff_days(Date.new(2026, 1, 1), Date.new(2025, 1, 1)) # 365
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-is_leap.md
Normal file
22
docs/language/date/date-is_leap.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-is_leap
|
||||
name: Date.is_leap
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.is_leap
|
||||
sig: Date.is_leap(year) -> bool
|
||||
tip: True if the year is a leap year.
|
||||
order: 5
|
||||
ns: Date
|
||||
member: is_leap
|
||||
---
|
||||
|
||||
Whether <code>year</code> is a leap year on the proleptic Gregorian calendar: divisible by 4, except centuries, which must be divisible by 400.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let leap = Date.is_leap(2024) # true
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-month.md
Normal file
22
docs/language/date/date-month.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-month
|
||||
name: Date.month
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.month
|
||||
sig: Date.month(date) -> int
|
||||
tip: The month (1-12) of a date.
|
||||
order: 2
|
||||
ns: Date
|
||||
member: month
|
||||
---
|
||||
|
||||
The calendar month of a <code>Date</code>, from <code>1</code> (January) to <code>12</code> (December).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let m = Date.month(Date.new(2026, 8, 30)) # 8
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-new.md
Normal file
22
docs/language/date/date-new.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-new
|
||||
name: Date.new
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.new
|
||||
sig: Date.new(year, month, day) -> int
|
||||
tip: A calendar day as days-since-1970.
|
||||
order: 0
|
||||
ns: Date
|
||||
member: new
|
||||
---
|
||||
|
||||
Builds a <code>Date</code> from a calendar <code>year</code>, <code>month</code> (1–12) and <code>day</code> (1–31), returning the count of days since 1970-01-01 (UTC). Read the parts back with <code>Date.year</code>/<code>Date.month</code>/<code>Date.day</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let launch = Date.new(2026, 8, 30)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-to_epoch.md
Normal file
22
docs/language/date/date-to_epoch.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-to_epoch
|
||||
name: Date.to_epoch
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.to_epoch
|
||||
sig: Date.to_epoch(date) -> int
|
||||
tip: Midnight UTC of the day, as a DateTime.
|
||||
order: 7
|
||||
ns: Date
|
||||
member: to_epoch
|
||||
---
|
||||
|
||||
The instant at midnight (00:00:00 UTC) of the given <code>Date</code>, as a <code>DateTime</code> (seconds since 1970). Bridges a calendar day back to the wall-clock timeline.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let t = Date.to_epoch(Date.new(2026, 8, 30))
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-weekday.md
Normal file
22
docs/language/date/date-weekday.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-weekday
|
||||
name: Date.weekday
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.weekday
|
||||
sig: Date.weekday(date) -> int
|
||||
tip: Day of the week, 0=Sunday..6=Saturday.
|
||||
order: 4
|
||||
ns: Date
|
||||
member: weekday
|
||||
---
|
||||
|
||||
The day of the week of a <code>Date</code>, as <code>0</code> (Sunday) through <code>6</code> (Saturday). Useful for weekly events or daily-reward streaks.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let w = Date.weekday(Date.new(2000, 1, 1)) # 6 (Saturday)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/date/date-year.md
Normal file
22
docs/language/date/date-year.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: date-year
|
||||
name: Date.year
|
||||
category: date
|
||||
kind: namespace-method
|
||||
tokens: Date.year
|
||||
sig: Date.year(date) -> int
|
||||
tip: The calendar year of a date.
|
||||
order: 1
|
||||
ns: Date
|
||||
member: year
|
||||
---
|
||||
|
||||
The calendar year of a <code>Date</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let y = Date.year(Date.new(2026, 8, 30)) # 2026
|
||||
}
|
||||
}
|
||||
```
|
||||
7
docs/language/datetime/_section.md
Normal file
7
docs/language/datetime/_section.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
id: datetime
|
||||
title: DateTime
|
||||
order: 6
|
||||
---
|
||||
|
||||
Instants on the wall-clock timeline (UTC), stored as a plain <code>int</code>: the count of seconds since 1970-01-01, matching <code>Time.now</code>. Build one with <code>DateTime.from</code>, shift it by a <code>Duration</code> with <code>DateTime.add</code>, and pull it apart with the <code>year</code>/<code>month</code>/<code>day</code>/<code>hour</code>/<code>minute</code>/<code>second</code> readers. Deterministic integer math throughout; v1 is UTC-only with no leap seconds, and assumes instants at or after 1970.
|
||||
22
docs/language/datetime/datetime-add.md
Normal file
22
docs/language/datetime/datetime-add.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-add
|
||||
name: DateTime.add
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.add
|
||||
sig: DateTime.add(dt, span) -> int
|
||||
tip: The instant `span` seconds later.
|
||||
order: 2
|
||||
ns: DateTime
|
||||
member: add
|
||||
---
|
||||
|
||||
The instant <code>span</code> seconds after <code>dt</code>. Pair it with the <code>Duration</code> constructors to express the offset in real units.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let ready_at = DateTime.add(Time.now(), Duration.hours(3))
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-date.md
Normal file
22
docs/language/datetime/datetime-date.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-date
|
||||
name: DateTime.date
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.date
|
||||
sig: DateTime.date(dt) -> int
|
||||
tip: The calendar day the instant falls on.
|
||||
order: 1
|
||||
ns: DateTime
|
||||
member: date
|
||||
---
|
||||
|
||||
The <code>Date</code> (days since 1970) that the instant <code>dt</code> falls on, dropping the time of day.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let today = DateTime.date(Time.now())
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-day.md
Normal file
22
docs/language/datetime/datetime-day.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-day
|
||||
name: DateTime.day
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.day
|
||||
sig: DateTime.day(dt) -> int
|
||||
tip: The day of the month (1-31) of an instant.
|
||||
order: 5
|
||||
ns: DateTime
|
||||
member: day
|
||||
---
|
||||
|
||||
The day of the month of the instant <code>dt</code> (UTC), <code>1</code>–<code>31</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let d = DateTime.day(DateTime.from(2000, 3, 9, 0, 0, 0)) # 9
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-from.md
Normal file
22
docs/language/datetime/datetime-from.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-from
|
||||
name: DateTime.from
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.from
|
||||
sig: DateTime.from(year, month, day, hour, minute, second) -> int
|
||||
tip: Build an instant from its calendar parts.
|
||||
order: 0
|
||||
ns: DateTime
|
||||
member: from
|
||||
---
|
||||
|
||||
Builds a <code>DateTime</code> (seconds since 1970, UTC) from calendar and clock parts. The inverse of the component readers below.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let t = DateTime.from(2000, 1, 1, 12, 30, 15)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-hour.md
Normal file
22
docs/language/datetime/datetime-hour.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-hour
|
||||
name: DateTime.hour
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.hour
|
||||
sig: DateTime.hour(dt) -> int
|
||||
tip: The hour of day (0-23) of an instant.
|
||||
order: 7
|
||||
ns: DateTime
|
||||
member: hour
|
||||
---
|
||||
|
||||
The hour of the day of the instant <code>dt</code> (UTC), <code>0</code>–<code>23</code>. Drives day/night cycles from a real clock.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let h = DateTime.hour(DateTime.from(2000, 1, 1, 12, 30, 15)) # 12
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-minute.md
Normal file
22
docs/language/datetime/datetime-minute.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-minute
|
||||
name: DateTime.minute
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.minute
|
||||
sig: DateTime.minute(dt) -> int
|
||||
tip: The minute of the hour (0-59) of an instant.
|
||||
order: 8
|
||||
ns: DateTime
|
||||
member: minute
|
||||
---
|
||||
|
||||
The minute within the hour of the instant <code>dt</code> (UTC), <code>0</code>–<code>59</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let mi = DateTime.minute(DateTime.from(2000, 1, 1, 12, 30, 15)) # 30
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-month.md
Normal file
22
docs/language/datetime/datetime-month.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-month
|
||||
name: DateTime.month
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.month
|
||||
sig: DateTime.month(dt) -> int
|
||||
tip: The month (1-12) of an instant.
|
||||
order: 4
|
||||
ns: DateTime
|
||||
member: month
|
||||
---
|
||||
|
||||
The calendar month of the instant <code>dt</code> (UTC), <code>1</code>–<code>12</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let m = DateTime.month(DateTime.from(2000, 3, 9, 0, 0, 0)) # 3
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-second.md
Normal file
22
docs/language/datetime/datetime-second.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-second
|
||||
name: DateTime.second
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.second
|
||||
sig: DateTime.second(dt) -> int
|
||||
tip: The second of the minute (0-59) of an instant.
|
||||
order: 9
|
||||
ns: DateTime
|
||||
member: second
|
||||
---
|
||||
|
||||
The second within the minute of the instant <code>dt</code> (UTC), <code>0</code>–<code>59</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let s = DateTime.second(DateTime.from(2000, 1, 1, 12, 30, 15)) # 15
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-weekday.md
Normal file
22
docs/language/datetime/datetime-weekday.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-weekday
|
||||
name: DateTime.weekday
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.weekday
|
||||
sig: DateTime.weekday(dt) -> int
|
||||
tip: Day of the week, 0=Sunday..6=Saturday.
|
||||
order: 6
|
||||
ns: DateTime
|
||||
member: weekday
|
||||
---
|
||||
|
||||
The day of the week of the instant <code>dt</code> (UTC), <code>0</code> (Sunday) through <code>6</code> (Saturday).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let w = DateTime.weekday(DateTime.from(2000, 1, 1, 12, 0, 0)) # 6
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/datetime/datetime-year.md
Normal file
22
docs/language/datetime/datetime-year.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: datetime-year
|
||||
name: DateTime.year
|
||||
category: datetime
|
||||
kind: namespace-method
|
||||
tokens: DateTime.year
|
||||
sig: DateTime.year(dt) -> int
|
||||
tip: The calendar year of an instant.
|
||||
order: 3
|
||||
ns: DateTime
|
||||
member: year
|
||||
---
|
||||
|
||||
The calendar year of the instant <code>dt</code> (UTC).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let y = DateTime.year(DateTime.from(2000, 1, 1, 12, 30, 15)) # 2000
|
||||
}
|
||||
}
|
||||
```
|
||||
7
docs/language/duration/_section.md
Normal file
7
docs/language/duration/_section.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
id: duration
|
||||
title: Duration
|
||||
order: 6
|
||||
---
|
||||
|
||||
Spans of real time, measured in whole seconds and carried in a plain <code>int</code> — so a duration adds, subtracts and compares with the ordinary operators (<code>Duration.minutes(5) + Duration.seconds(30)</code>, <code>away > Duration.hours(3)</code>). The constructors build a span from a unit; the <code>as_*</code> readers convert a span back to whole units (truncating toward zero). Integer-only, so no floating-point drift.
|
||||
22
docs/language/duration/duration-as_days.md
Normal file
22
docs/language/duration/duration-as_days.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-as_days
|
||||
name: Duration.as_days
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.as_days
|
||||
sig: Duration.as_days(span) -> int
|
||||
tip: The span in whole days.
|
||||
order: 7
|
||||
ns: Duration
|
||||
member: as_days
|
||||
---
|
||||
|
||||
The span expressed in whole days, truncated toward zero (<code>span / 86400</code>).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let d = Duration.as_days(Duration.hours(50)) # 2
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-as_hours.md
Normal file
22
docs/language/duration/duration-as_hours.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-as_hours
|
||||
name: Duration.as_hours
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.as_hours
|
||||
sig: Duration.as_hours(span) -> int
|
||||
tip: The span in whole hours.
|
||||
order: 6
|
||||
ns: Duration
|
||||
member: as_hours
|
||||
---
|
||||
|
||||
The span expressed in whole hours, truncated toward zero (<code>span / 3600</code>). Useful for turning an elapsed-time gap into a reward count.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let h = Duration.as_hours(Duration.days(3)) # 72
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-as_minutes.md
Normal file
22
docs/language/duration/duration-as_minutes.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-as_minutes
|
||||
name: Duration.as_minutes
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.as_minutes
|
||||
sig: Duration.as_minutes(span) -> int
|
||||
tip: The span in whole minutes.
|
||||
order: 5
|
||||
ns: Duration
|
||||
member: as_minutes
|
||||
---
|
||||
|
||||
The span expressed in whole minutes, truncated toward zero (<code>span / 60</code>).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let m = Duration.as_minutes(Duration.hours(2)) # 120
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-as_seconds.md
Normal file
22
docs/language/duration/duration-as_seconds.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-as_seconds
|
||||
name: Duration.as_seconds
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.as_seconds
|
||||
sig: Duration.as_seconds(span) -> int
|
||||
tip: The span in whole seconds.
|
||||
order: 4
|
||||
ns: Duration
|
||||
member: as_seconds
|
||||
---
|
||||
|
||||
The span expressed in whole seconds. The inverse of <code>Duration.seconds</code>; also the identity, provided for symmetry with the other readers.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let s = Duration.as_seconds(Duration.minutes(3)) # 180
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-days.md
Normal file
22
docs/language/duration/duration-days.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-days
|
||||
name: Duration.days
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.days
|
||||
sig: Duration.days(n) -> int
|
||||
tip: A span of n days, in seconds.
|
||||
order: 3
|
||||
ns: Duration
|
||||
member: days
|
||||
---
|
||||
|
||||
A span of <code>n</code> days, returned in seconds (<code>n * 86400</code>).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let week = Duration.days(7)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-hours.md
Normal file
22
docs/language/duration/duration-hours.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-hours
|
||||
name: Duration.hours
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.hours
|
||||
sig: Duration.hours(n) -> int
|
||||
tip: A span of n hours, in seconds.
|
||||
order: 2
|
||||
ns: Duration
|
||||
member: hours
|
||||
---
|
||||
|
||||
A span of <code>n</code> hours, returned in seconds (<code>n * 3600</code>). Handy as a threshold for offline-progress checks.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let full_day = Duration.hours(24)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-minutes.md
Normal file
22
docs/language/duration/duration-minutes.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-minutes
|
||||
name: Duration.minutes
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.minutes
|
||||
sig: Duration.minutes(n) -> int
|
||||
tip: A span of n minutes, in seconds.
|
||||
order: 1
|
||||
ns: Duration
|
||||
member: minutes
|
||||
---
|
||||
|
||||
A span of <code>n</code> minutes, returned in seconds (<code>n * 60</code>).
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let respawn = Duration.minutes(2)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/duration/duration-seconds.md
Normal file
22
docs/language/duration/duration-seconds.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: duration-seconds
|
||||
name: Duration.seconds
|
||||
category: duration
|
||||
kind: namespace-method
|
||||
tokens: Duration.seconds
|
||||
sig: Duration.seconds(n) -> int
|
||||
tip: A span of n whole seconds.
|
||||
order: 0
|
||||
ns: Duration
|
||||
member: seconds
|
||||
---
|
||||
|
||||
A span of <code>n</code> whole seconds. Since a duration is just an <code>int</code> count of seconds, this is the identity — it exists so the unit is explicit at the call site.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let cooldown = Duration.seconds(45)
|
||||
}
|
||||
}
|
||||
```
|
||||
24
docs/language/time/time-since.md
Normal file
24
docs/language/time/time-since.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
id: time-since
|
||||
name: Time.since
|
||||
category: time
|
||||
kind: namespace-method
|
||||
tokens: Time.since
|
||||
sig: Time.since(past) -> int
|
||||
tip: Seconds elapsed from a past instant to now (non-deterministic).
|
||||
order: 4
|
||||
ns: Time
|
||||
member: since
|
||||
---
|
||||
|
||||
The number of seconds elapsed from the <code>DateTime</code> <code>past</code> to now (<code>Time.now() - past</code>). Because it reads the wall clock it is <b>non-deterministic</b> — use it for offline-progress and "time away" checks, never inside the lockstep simulation. The result is a <code>Duration</code> in seconds, ready for the <code>Duration.as_*</code> readers.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let last_seen = DateTime.from(2026, 8, 30, 9, 0, 0)
|
||||
let away = Time.since(last_seen)
|
||||
let hours_away = Duration.as_hours(away)
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue