Date and Time

Dates and times are hard. Everyone says this, and it's true. I've tried to make them less painful in Adama by providing four specialized types:

  • date - Calendar dates (year, month, day)
  • time - Time of day (hour, minute)
  • datetime - Full timestamps with timezone
  • timespan - Durations

Constants and Literals

Adama has literal syntax for temporal values so you don't have to construct everything from integers:

Type Syntax Example Notes
time @time $hr:$min @time 4:20 Use military time (0-23) for hours
date @date $year/$mo/$day @date 2023/10/31 Must be a valid date
timespan @timespan $count $unit @timespan 30 min Units: sec, min, hr, day, week
datetime @datetime "$iso8601" @datetime "2023-04-24T17:57:19.802528800-05:00[America/Chicago]" ISO 8601 format with timezone
time morning = @time 9:30;
date halloween = @date 2023/10/31;
timespan halfHour = @timespan 30 min;
datetime meeting = @datetime "2023-04-24T17:57:19-05:00[America/Chicago]";

Getting Current Date/Time

The Time class gives you access to current temporal values:

Function Description Returns
Time.today() Get the current date date
Time.datetime() Get the current date and time datetime
Time.time() Get the current time of day time
Time.zone() Get the document's time zone string
Time.setZone(zone) Set the document's time zone bool
Time.now() Get current time as UNIX timestamp long
date today = Time.today();
datetime now = Time.datetime();
time currentTime = Time.time();
string tz = Time.zone();
long unixTime = Time.now();

Document Timezone

Every document starts in "UTC". The timezone affects how Time.today(), Time.datetime(), and Time.time() compute their values. You can change it whenever you want:

@construct {
  // Default timezone is UTC
  string tz = Time.zone();              // "UTC"

  // Change to Eastern time
  bool ok = Time.setZone("America/New_York");  // true

  // Invalid timezones are rejected
  bool bad = Time.setZone("Not/A/Zone");       // false
}

Time.setZone() accepts any valid IANA timezone identifier (e.g., "America/Chicago", "Europe/London", "Asia/Tokyo") and returns true on success. The timezone is persisted as part of the document state and survives restarts.

For the full story on timezone management and other global objects, see Global Objects.

Time Functions

Construction

Function Description Returns
Time.make(hr, min) Create a time value maybe<time>
maybe<time> t = Time.make(14, 30);  // 2:30 PM

Operations

Function Description Returns
Time.extendWithinDay(t, s) Add timespan, clamping at midnight time
Time.cyclicAdd(t, s) Add timespan, wrapping around clock time
Time.toInt(t) Convert time to integer int
Time.overlaps(a, b, c, d) Check if ranges [a,b] and [c,d] overlap bool

The distinction between extendWithinDay and cyclicAdd matters: one clamps at midnight (you can't go past 23:59), the other wraps around (23:00 + 2 hours = 01:00). Pick the one that matches your semantics.

time t = @time 23:00;
timespan oneHour = @timespan 1 hr;

// Clamps at midnight (23:59)
time extended = Time.extendWithinDay(t, oneHour);

// Wraps around (00:00)
time wrapped = Time.cyclicAdd(t, oneHour);

Instance Methods on time

Method Description Returns
.toInt() Convert time to integer for comparisons int
time t = @time 14:30;
int timeInt = t.toInt();  // Integer representation for comparisons

Date Functions

Instance Methods

Date values have methods for pulling out components:

Method Description Returns
.day() Get the day of month int
.month() Get the month (1-12) int
.year() Get the year int
date d = @date 2025/6/15;
int day = d.day();     // 15
int month = d.month(); // 6
int year = d.year();   // 2025

Construction

Function Description Returns
Date.make(yr, mo, day) Create a date maybe<date>
Date.construct(dy, t, sec, zone) Create a datetime from components maybe<datetime>
maybe<date> d = Date.make(2025, 6, 15);
maybe<datetime> dt = Date.construct(@date 2025/6/15, @time 14:30, 0.0, "America/Chicago");

Calendar Views

These are useful for building calendar UIs. The calendarViewOf() method on a date gives you the full surrounding month; the static functions give you different views.

Instance method on date values:

Method Description Returns
.calendarViewOf() Get surrounding month list<date>

Static functions:

Function Description Returns
Date.weekViewOf(d) Get surrounding week list<date>
Date.neighborViewOf(d, days) Get neighborhood of dates list<date>
Date.inclusiveRange(from, to) Get all dates in range list<date>
procedure foo() {
  date today = @date 2025/1/15;
  list<date> month = today.calendarViewOf();
  list<date> week = Date.weekViewOf(today);
  list<date> neighbors = Date.neighborViewOf(today, 3);  // 3 days before and after
  list<date> range = Date.inclusiveRange(@date 2025/1/1, @date 2025/1/31);
}

Weekly Patterns

I needed a way to express "every Monday, Wednesday, and Friday" for scheduling, so I built weekly patterns. You create a bitmask from a boolean for each day, then test dates against it.

Function Description Returns
Date.patternOf(m, tu, w, th, fr, sa, su) Convert week pattern to bitmask int
Date.satisfiesWeeklyPattern(d, pattern) Check if date matches pattern bool
Date.inclusiveRangeSatisfiesWeeklyPattern(from, to, pattern) Get matching dates in range list<date>
// Create pattern for weekdays only
int weekdays = Date.patternOf(true, true, true, true, true, false, false);

date d = @date 2025/1/15;  // A Wednesday
bool isWeekday = Date.satisfiesWeeklyPattern(d, weekdays);  // true

// Get all weekdays in January
formula workdays = Date.inclusiveRangeSatisfiesWeeklyPattern(
  @date 2025/1/1, @date 2025/1/31, weekdays
);

Date Information

Instance methods:

Method Description Returns
.dayOfWeek() Get day of week number int
.dayOfWeekEnglish() Get day name in English string
.monthNameEnglish() Get month name in English string

Static functions:

Function Description Returns
Date.dayOfWeek(d) Get day of week (1=Monday, 7=Sunday) int
Date.dayOfWeekEnglish(d) Get day name in English string
Date.monthNameEnglish(d) Get month name in English string
date d = @date 2025/1/15;

// Instance methods
int dow = d.dayOfWeek();                 // 3 (Wednesday)
string dayName = d.dayOfWeekEnglish();   // "Wednesday"
string monthName = d.monthNameEnglish(); // "January"

// Static functions (equivalent)
int dow2 = Date.dayOfWeek(d);
string dayName2 = Date.dayOfWeekEnglish(d);

Date Arithmetic

Instance methods on date values:

Method Description Returns
.offsetMonth(m) Add/subtract months date
.offsetDay(n) Add/subtract days date
.periodYearsFractional(other) Get fractional years between dates maybe<double>

Static functions:

Function Description Returns
Date.offsetDay(d, days) Add/subtract days date
Date.periodYearsFractional(from, to) Get years between dates double
Date.periodMonths(from, to) Get months between dates int
date d = @date 2025/1/15;
date nextMonth = d.offsetMonth(1);         // 2025/2/15
date lastWeek = d.offsetDay(-7);           // 2025/1/8

date start = @date 2020/1/1;
date end = @date 2025/1/1;
double years = Date.periodYearsFractional(start, end);  // 5.0
int months = Date.periodMonths(start, end);             // 60

// Instance method for age calculation
date birthday = @date 1990/5/20;
maybe<double> age = birthday.periodYearsFractional(Time.today());

Date Comparison

Function Description Returns
Date.min(d1, d2) Get the earlier date date
Date.max(d1, d2) Get the later date date
Date.overlaps(a, b, c, d) Check if ranges overlap bool
date a = @date 2025/1/1;
date b = @date 2025/12/31;
date earlier = Date.min(a, b);  // 2025/1/1
date later = Date.max(a, b);    // 2025/12/31

bool overlap = Date.overlaps(@date 2025/1/1, @date 2025/6/30,
                             @date 2025/4/1, @date 2025/12/31);  // true

Date Formatting

Function Description Returns
Date.format(d, format) Format date using pattern (English) maybe<string>
Date.format(d, format, lang) Format date using pattern and language maybe<string>
date d = @date 2025/1/15;
maybe<string> formatted = Date.format(d, "MMMM dd, yyyy");  // "January 15, 2025"

TimeSpan Functions

Construction

Function Description Returns
TimeSpan.makeFromSeconds(s) Create timespan from seconds timespan
TimeSpan.makeFromMinutes(m) Create timespan from minutes timespan
timespan t1 = TimeSpan.makeFromSeconds(90);    // 1.5 minutes
timespan t2 = TimeSpan.makeFromMinutes(3.14);  // 3.14 minutes

Arithmetic

Function Description Returns
TimeSpan.add(a, b) Add two timespans timespan
TimeSpan.multiply(a, v) Multiply timespan by factor timespan

Timespans also support the obvious operators:

timespan a = @timespan 30 min;
timespan b = @timespan 15 min;

timespan sum = a + b;      // 45 minutes
timespan doubled = a * 2;  // 60 minutes

Conversion

Function/Method Description Returns
TimeSpan.seconds(a) or a.seconds() Get duration in seconds double
TimeSpan.minutes(a) or a.minutes() Get duration in minutes double
TimeSpan.hours(a) or a.hours() Get duration in hours double
timespan duration = @timespan 90 min;
double secs = duration.seconds();  // 5400.0
double mins = duration.minutes();  // 90.0
double hrs = duration.hours();     // 1.5

DateTime Functions

These are called directly on datetime values:

Method Description Returns
.future(t) Get datetime in the future datetime
.past(t) Get datetime in the past datetime
.between(other) Get timespan between datetimes timespan
.format(pattern) Format as string maybe<string>
datetime now = Time.datetime();
timespan oneDay = @timespan 1 day;

datetime tomorrow = now.future(oneDay);
datetime yesterday = now.past(oneDay);
timespan diff = yesterday.between(tomorrow);  // 2 days

Extraction

Function Description Returns
Date.date(d) Extract date component date
Date.time(d) Extract time component time
datetime dt = Time.datetime();
date d = Date.date(dt);
time t = Date.time(dt);

Timezone

Function Description Returns
Date.adjustTimeZone(d, tz) Adjust to different timezone maybe<datetime>
datetime dt = Time.datetime();
maybe<datetime> pacific = Date.adjustTimeZone(dt, "America/Los_Angeles");

Modification

Sometimes you need to swap out just one component of a datetime -- change the year, set the hour to noon, that sort of thing:

Function Description Returns
Date.withYear(d, year) Replace year maybe<datetime>
Date.withMonth(d, month) Replace month maybe<datetime>
Date.withDayOfMonth(d, day) Replace day maybe<datetime>
Date.withHour(d, hour) Replace hour maybe<datetime>
Date.withMinute(d, minute) Replace minute maybe<datetime>
Date.withTime(d, t) Replace time component maybe<datetime>
datetime dt = Time.datetime();
maybe<datetime> newYear = Date.withYear(dt, 2030);
maybe<datetime> noon = Date.withTime(dt, @time 12:00);

Truncation

Function Description Returns
Date.truncateDay(d) Zero out below month datetime
Date.truncateHour(d) Zero out below day datetime
Date.truncateMinute(d) Zero out below hour datetime
Date.truncateSeconds(d) Zero out below minute datetime
Date.truncateMilliseconds(d) Zero out milliseconds datetime
datetime dt = Time.datetime();
datetime startOfDay = Date.truncateHour(dt);
datetime startOfHour = Date.truncateMinute(dt);

DateTime Comparison

Function Description Returns
Date.min(d1, d2) Get the earlier datetime datetime
Date.max(d1, d2) Get the later datetime datetime
Date.overlaps(a, b, c, d) Check if datetime ranges overlap bool

DateTime Formatting

Function Description Returns
Date.format(dt, format) Format datetime (English) maybe<string>
Date.format(dt, format, lang) Format datetime with language maybe<string>
datetime dt = Time.datetime();
maybe<string> formatted = Date.format(dt, "yyyy-MM-dd HH:mm:ss");

Common Patterns

Scheduling Check

time meetingStart = @time 14:00;
time meetingEnd = @time 15:30;
time newStart = @time 14:30;
time newEnd = @time 16:00;

bool conflict = Time.overlaps(meetingStart, meetingEnd, newStart, newEnd);  // true

Date Range Iteration

date start = @date 2025/1/1;
date end = @date 2025/1/7;

formula week = Date.inclusiveRange(start, end);
// Contains 7 dates from Jan 1-7

Duration Calculation

datetime checkIn = @datetime "2025-01-15T10:00:00-05:00";
datetime checkOut = @datetime "2025-01-15T18:30:00-05:00";

timespan worked = checkIn.between(checkOut);
double hours = worked.hours();  // 8.5
Previous Math