How do I work with Unix timestamps in EK9?

← Date, Time, and Duration · Ref: Q543

EK9 uses the Millisecond type for epoch-based timestamps. SystemClock().millisecond() returns the current Unix epoch time in milliseconds.

GETTING EPOCH TIME

  epochNow <- SystemClock().millisecond()

This returns a Millisecond value representing milliseconds since 1970-01-01T00:00:00Z (the Unix epoch).

DATE FROM EPOCH DAYS

The Date constructor accepts days from epoch:

  Date(daysFromEpoch) creates a date from the number of days since 1970-01-01.

The #< operator extracts epoch days from a Date:

  epochDays <- #< myDate

DATETIME AND EPOCH

DateTime does not have a direct epoch constructor, but you can work with epoch values through Duration and Millisecond arithmetic:

  epochMs <- SystemClock().millisecond()
  asDuration <- epochMs.duration()

MILLISECOND AS TIMESTAMP

Millisecond is the natural type for Unix timestamps, API timestamps, and database epoch values. It carries type information (this is milliseconds, not nanoseconds or seconds) and supports arithmetic.

See Q41 for Millisecond basics. See Q544 for benchmarking with Millisecond. See Q536 for getting current date and time.

Example

defines module qa.unix.timestamps

  defines program
    UnixTimestampsDemo()
      stdout <- Stdout()

      // Current epoch time in milliseconds
      epochNow <- SystemClock().millisecond()
      stdout.println(`Epoch now: ${epochNow}`)

      // Date from epoch days
      // 1970-01-01 is day 0
      unixEpoch <- Date(0)
      stdout.println(`Epoch date: ${unixEpoch}`)

      // Extract epoch days from a date
      today <- Date().today()
      epochDays <- #< today
      stdout.println(`Today's epoch days: ${epochDays}`)

      // Round-trip: epoch days back to date
      restored <- Date(epochDays)
      require restored == today
      stdout.println(`Restored: ${restored}`)

      // Millisecond to Duration conversion
      fiveSeconds <- 5000ms
      asDuration <- fiveSeconds.duration()
      stdout.println(`5000ms as Duration: ${asDuration}`)

      // Millisecond arithmetic for timestamp differences
      earlier <- SystemClock().millisecond()
      stdout.println("Some work here")
      later <- SystemClock().millisecond()
      elapsed <- later - earlier
      stdout.println(`Elapsed: ${elapsed}`)

      // Known epoch dates
      y2k <- Date(10957)
      stdout.println(`Y2K (day 10957): ${y2k}`)

Common mistakes

E50060 — SystemClock has no currentTimeMillis() method. Use millisecond() to get the current epoch time as a typed Millisecond value. See ek9 -h E50060 for details.

Incorrect:

epochNow <- SystemClock().currentTimeMillis()

Correct:

epochNow <- SystemClock().millisecond()
Other ways to ask this
  • How do I convert epoch milliseconds to a date?
  • How do I get the Unix epoch time in EK9?
  • How does Millisecond relate to epoch time?
  • How do I work with epoch time in EK9?

Coming from another language?

Java: System.currentTimeMillis() returns raw long, Instant.toEpochMilli(), LocalDate.toEpochDay(). Python: time.time() returns float seconds, datetime.timestamp(). JavaScript: Date.now() returns milliseconds, new Date(epochMs). Go: time.Now().UnixMilli(). Rust: SystemTime::now().duration_since(UNIX_EPOCH). EK9: SystemClock().millisecond() returns typed Millisecond, Date(epochDays) for date construction, #< for epoch extraction.

Keywords: unix, systemclock, epoch, seconds, duration, timestamp, convert, millisecond, time, timezone, days