Skip to content

Dates and Times

Emerald has a separate type for each thing a program can mean by “a time”. They aren’t interchangeable, and that is deliberate: a birthday, a deadline, and a timeout are different kinds of thing, and Emerald checks that one isn’t used where another was meant.

Type Means Prints as
Date A day on the calendar: a birthday, a due date 2026-09-25
Time A time on the clock: an alarm, opening hours 14:30:00
DateTime A date and a time together, with no zone: what a calendar and wall clock show 2026-09-25T14:30:00
Instant An exact moment, the same everywhere: a timestamp, a deadline 2026-09-25T18:30:00Z
Duration An exact length of time: a timeout, a lap time 1h 30m
TimeZone Where the clocks are, which decides what time a moment shows Europe/Paris
Stopwatch A way to measure how long something takes

Weekday names the days of the week, and DateTimeError is what is raised when a value can’t be made. To pause a program for a length of time, see Program.sleep.

const today = Date(2026, 9, 25)
var birthday = Date(2026, 3, 14)
if birthday < today {
birthday = birthday.add(years: 1)
}
print("#{today.days_until(birthday)} days to go")
Output
170 days to go

Two kinds of arithmetic look alike but behave differently, so they are written differently.

Duration and Instant are exact, so they have operators: an Instant plus a Duration is always the same moment.

A step on the calendar depends on where it starts, since months differ in length. So Date and DateTime have methods with named units, such as date.add(months: 1), which from 31 January lands on the last day of February. The unit is always named, because add(5) wouldn’t say whether it meant days or years; Emerald refuses it and lists the units.

A calendar day and 24 hours usually agree, but not on a day the clocks change. In New York, on the day the clocks go forward, adding a calendar day keeps the time on the clock, while adding 24 exact hours moves the clock on by one more hour:

const new_york = TimeZone("America/New_York")
const noon = DateTime(2026, 3, 7, 12)
print(noon.add(days: 1))
print(noon.to_instant(new_york).after(Duration(days: 1)).to_date_time(new_york))
Output
2026-03-08T12:00:00
2026-03-08T13:00:00

Every value prints in the international standard form shown in the table, which reads the same in every country and sorts correctly as text. Each type’s parse reads that form back, and parse_maybe gives nothing instead of raising an error. For another layout, put the parts into text yourself:

const day = Date(2026, 9, 25)
print("#{day.weekday}, #{day.month_name} #{day.day}, #{day.year}")
Output
Friday, September 25, 2026

A function that needs a zone takes an optional zone, and uses the computer’s own, TimeZone.local, when you give none. Named zones come from a copy of the international time zone database built into Emerald, so a program gives the same answer on every computer.