The time_utils package provides immutable types for working with time in GALA. It offers Duration for representing lengths of time and Instant for representing specific moments in time.
import . "martianoff/gala/time_utils"
Duration represents a length of time stored as nanoseconds. All operations return new Duration values (immutable).
// From various time units
val ns = Nanoseconds(1000)
val us = Microseconds(500)
val ms = Milliseconds(100)
val sec = Seconds(30)
val min = Minutes(5)
val hr = Hours(2)
val day = Days(1)
// Zero duration
val zero = ZeroDuration()
// From Go time.Duration
val goDur = FromGoDuration(time.Second * 5)
// Between two instants
val elapsed = Between(start, end)
val d1 = Seconds(30)
val d2 = Seconds(15)
// Arithmetic
val sum = d1.Plus(d2) // 45 seconds
val diff = d1.Minus(d2) // 15 seconds
val doubled = d1.Multiply(2) // 60 seconds
val halved = d1.Divide(2) // 15 seconds
// Sign operations
val neg = d1.Negate() // -30 seconds
val abs = neg.Abs() // 30 seconds
// Predicates
d1.IsZero() // false
d1.IsPositive() // true
d1.IsNegative() // false
// Comparison
d1.Compare(d2) // 1 (d1 > d2)
d1.Equals(d2) // false
val d = Hours(2).Plus(Minutes(30))
d.ToNanos() // nanoseconds
d.ToMicros() // microseconds
d.ToMillis() // milliseconds
d.ToSeconds() // 9000
d.ToMinutes() // 150
d.ToHours() // 2
d.ToDays() // 0
d.ToGoDuration() // Go time.Duration
d.String() // "2h30m0s"
Instant represents a specific moment in time stored as nanoseconds since Unix epoch. All operations return new Instant values (immutable).
// Current time
val now = Now()
// From Unix timestamps
val fromSecs = FromUnixSeconds(1704067200)
val fromMillis = FromUnixMillis(1704067200000)
val fromNanos = FromUnixNanos(1704067200000000000)
// Unix epoch (January 1, 1970 UTC)
val epoch = UnixEpoch()
// From Go time.Time
val fromGo = FromGoTime(time.Now())
// Parsing strings
val parsed = ParseISO("2024-01-15T10:30:00Z") // Option[Instant]
val rfc3339 = ParseRFC3339("2024-01-15T10:30:00Z") // Option[Instant]
val nano = ParseRFC3339Nano("2024-01-15T10:30:00.123456789Z")
val custom = Parse(time.Kitchen, "3:04PM") // Option[Instant]
val i1 = FromUnixSeconds(1000)
val i2 = FromUnixSeconds(2000)
// Add/subtract durations
val later = i1.Plus(Hours(1))
val earlier = i1.Minus(Minutes(30))
// Calculate durations between instants
val until = i1.Until(i2) // Duration from i1 to i2
val since = i2.Since(i1) // Duration from i1 to i2
// Comparison
i1.IsBefore(i2) // true
i1.IsAfter(i2) // false
i1.Equals(i2) // false
i1.Compare(i2) // -1
// Min/Max
i1.Min(i2) // i1 (earlier)
i1.Max(i2) // i2 (later)
// Relative to now
val elapsed = pastInstant.SinceNow() // Duration since instant
val remaining = futureInstant.UntilNow() // Duration until instant (negative if past)
val i = ParseISO("2024-06-15T10:30:45Z").Get()
// Unix timestamps
i.UnixSeconds() // seconds since epoch
i.UnixMillis() // milliseconds since epoch
i.UnixNanos() // nanoseconds since epoch
// Date components (UTC)
i.Year() // 2024
i.Month() // 6
i.Day() // 15
i.Hour() // 10
i.Minute() // 30
i.Second() // 45
i.Nanosecond() // 0
i.Weekday() // 6 (Saturday, 0=Sunday)
i.YearDay() // 167
// Go interop
i.ToGoTime() // time.Time in UTC
val i = Now()
i.FormatISO() // "2024-06-15T10:30:45Z"
i.FormatRFC3339() // "2024-06-15T10:30:45Z"
i.FormatRFC3339Nano() // "2024-06-15T10:30:45.123456789Z"
i.Format(time.Kitchen) // "10:30AM"
i.String() // ISO 8601 format
val i = ParseRFC3339Nano("2024-06-15T10:30:45.123456789Z").Get()
i.TruncateToSecond() // 2024-06-15T10:30:45Z
i.TruncateToMinute() // 2024-06-15T10:30:00Z
i.TruncateToHour() // 2024-06-15T10:00:00Z
i.TruncateToDay() // 2024-06-15T00:00:00Z
val i = Now()
// Get time in specific timezone
val inNY = i.InTimezone("America/New_York") // Option[time.Time]
val inTokyo = i.InTimezone("Asia/Tokyo") // Option[time.Time]
inNY match {
case Some(t) => Println(t.Format(time.RFC3339))
case _ => Println("Invalid timezone")
}
// Sleep for a duration
Sleep(Seconds(1))
// Get instant after duration from now
val deadline = After(Minutes(5))
The package provides extractors for pattern matching on Instant values.
Extract year, month, day, hour, minute, second:
val i = Now()
i match {
case InstantComponents(year, month, day, hour, minute, second) =>
Println(f"$year%d-$month%02d-$day%02d $hour%02d:$minute%02d:$second%02d")
case _ => Println("Unknown")
}
Extract just the date components:
val i = Now()
i match {
case DateOnly(year, month, day) =>
Println(f"$year%d-$month%02d-$day%02d")
case _ => Println("Unknown")
}
Extract just the time components:
val i = Now()
i match {
case TimeOnly(hour, minute, second) =>
Println(f"$hour%02d:$minute%02d:$second%02d")
case _ => Println("Unknown")
}
package main
import . "martianoff/gala/time_utils"
func main() {
// Measure execution time
val start = Now()
// Do some work
Sleep(Milliseconds(100))
val elapsed = start.SinceNow().Abs()
Println(s"Execution took ${elapsed.String()}")
// Parse and format dates
val parsed = ParseISO("2024-12-25T00:00:00Z")
parsed match {
case Some(christmas) =>
val daysUntil = Now().Until(christmas).ToDays()
Println(s"Days until Christmas: $daysUntil")
case _ =>
Println("Failed to parse date")
}
// Work with durations
val workday = Hours(8)
val lunch = Minutes(30)
val actualWork = workday.Minus(lunch)
Println(s"Actual work time: ${actualWork.String()}")
// Extract components
val now = Now()
now match {
case DateOnly(y, m, d) =>
Println(f"Today is $y%d-$m%02d-$d%02d")
case _ =>
Println("Unknown")
}
}
| Method | Return Type | Description |
|---|---|---|
Plus(other) |
Duration |
Add two durations |
Minus(other) |
Duration |
Subtract duration |
Multiply(factor) |
Duration |
Multiply by factor |
Divide(divisor) |
Duration |
Divide by divisor |
Abs() |
Duration |
Absolute value |
Negate() |
Duration |
Negate duration |
IsZero() |
bool |
Check if zero |
IsPositive() |
bool |
Check if positive |
IsNegative() |
bool |
Check if negative |
Compare(other) |
int |
Compare (-1, 0, 1) |
Equals(other) |
bool |
Check equality |
ToNanos() |
int64 |
Get nanoseconds |
ToMicros() |
int64 |
Get microseconds |
ToMillis() |
int64 |
Get milliseconds |
ToSeconds() |
int64 |
Get seconds |
ToMinutes() |
int64 |
Get minutes |
ToHours() |
int64 |
Get hours |
ToDays() |
int64 |
Get days |
ToGoDuration() |
time.Duration |
Convert to Go duration |
String() |
string |
Human-readable string |
| Method | Return Type | Description |
|---|---|---|
Plus(d) |
Instant |
Add duration |
Minus(d) |
Instant |
Subtract duration |
Until(other) |
Duration |
Duration to other instant |
Since(other) |
Duration |
Duration from other instant |
IsBefore(other) |
bool |
Check if before |
IsAfter(other) |
bool |
Check if after |
Equals(other) |
bool |
Check equality |
Compare(other) |
int |
Compare (-1, 0, 1) |
Min(other) |
Instant |
Earlier instant |
Max(other) |
Instant |
Later instant |
UnixSeconds() |
int64 |
Unix seconds |
UnixMillis() |
int64 |
Unix milliseconds |
UnixNanos() |
int64 |
Unix nanoseconds |
ToGoTime() |
time.Time |
Convert to Go time |
Format(layout) |
string |
Format with layout |
FormatISO() |
string |
ISO 8601 format |
FormatRFC3339() |
string |
RFC 3339 format |
FormatRFC3339Nano() |
string |
RFC 3339 with nanos |
String() |
string |
ISO 8601 format |
Year() |
int |
Get year |
Month() |
int |
Get month (1-12) |
Day() |
int |
Get day (1-31) |
Hour() |
int |
Get hour (0-23) |
Minute() |
int |
Get minute (0-59) |
Second() |
int |
Get second (0-59) |
Nanosecond() |
int |
Get nanosecond |
Weekday() |
int |
Get weekday (0=Sun) |
YearDay() |
int |
Get day of year |
InTimezone(tz) |
Option[time.Time] |
Convert to timezone |
TruncateToSecond() |
Instant |
Truncate to second |
TruncateToMinute() |
Instant |
Truncate to minute |
TruncateToHour() |
Instant |
Truncate to hour |
TruncateToDay() |
Instant |
Truncate to day |
SinceNow() |
Duration |
Duration since now |
UntilNow() |
Duration |
Duration until now |
| Function | Return Type | Description |
|---|---|---|
Nanoseconds(n) |
Duration |
Create from nanoseconds |
Microseconds(n) |
Duration |
Create from microseconds |
Milliseconds(n) |
Duration |
Create from milliseconds |
Seconds(n) |
Duration |
Create from seconds |
Minutes(n) |
Duration |
Create from minutes |
Hours(n) |
Duration |
Create from hours |
Days(n) |
Duration |
Create from days |
ZeroDuration() |
Duration |
Zero duration |
Between(start, end) |
Duration |
Duration between instants |
FromGoDuration(d) |
Duration |
From Go duration |
Now() |
Instant |
Current instant |
FromUnixSeconds(s) |
Instant |
From Unix seconds |
FromUnixMillis(ms) |
Instant |
From Unix milliseconds |
FromUnixNanos(ns) |
Instant |
From Unix nanoseconds |
FromGoTime(t) |
Instant |
From Go time.Time |
UnixEpoch() |
Instant |
Unix epoch |
Parse(layout, value) |
Option[Instant] |
Parse with layout |
ParseISO(value) |
Option[Instant] |
Parse ISO 8601 |
ParseRFC3339(value) |
Option[Instant] |
Parse RFC 3339 |
ParseRFC3339Nano(value) |
Option[Instant] |
Parse RFC 3339 with nanos |
Sleep(d) |
- | Sleep for duration |
After(d) |
Instant |
Instant after duration |
| See also: Language Reference | Immutable Collections | Code Examples |