How do I get the current date and time in EK9?

← Date, Time, and Duration · Ref: Q536

EK9 has three factory methods for 'now': Date().today(), Time().now(), and DateTime().now(). The critical distinction is that the no-arg constructor creates an UNSET value, not the current moment.

GETTING THE CURRENT MOMENT

Date().today() returns today's calendar date.
Time().now() returns the current wall-clock time.
DateTime().now() returns the current date, time, and timezone.
DateTime().today() is an alias for DateTime().now().

THE UNSET CONSTRUCTOR TRAP

Date() creates an unset date (not today). Time() creates an unset time (not now). DateTime() creates an unset DateTime (not now). This follows EK9's tri-state design (see Q29): every type can be present-but-unset, which is different from absent and from set-with-value.

Why? Because 'no date specified yet' is a legitimate state. Think of a form where the user has not entered their birth date. You need to distinguish 'not entered' from 'today' from 'some specific date'.

PATTERN: GUARD AGAINST UNSET

Since the factory methods return new set values, you can use guard patterns:

  if today <- Date().today()
    stdout.println(`Today is ${today}`)

This always executes because today() always returns a set value.

See Q31 for Date and Time basics. See Q92 for DateTime with timezones. See Q29 for tri-state semantics. See Q543 for Unix timestamps. See Q544 for elapsed time benchmarking.

Example

defines module qa.current.date.time

  defines program
    CurrentDateTimeDemo()
      stdout <- Stdout()

      // Date() is UNSET - not today
      unsetDate <- Date()
      stdout.println(`Date() isSet: ${unsetDate?}`)

      // Date().today() gets the current date
      currentDate <- Date().today()
      stdout.println(`Today: ${currentDate}`)

      // Time() is UNSET - not now
      unsetTime <- Time()
      stdout.println(`Time() isSet: ${unsetTime?}`)

      // Time().now() gets the current time
      currentTime <- Time().now()
      stdout.println(`Now: ${currentTime}`)

      // DateTime() is UNSET - not now
      unsetDT <- DateTime()
      stdout.println(`DateTime() isSet: ${unsetDT?}`)

      // DateTime().now() gets the current date+time+timezone
      currentDT <- DateTime().now()
      stdout.println(`Now: ${currentDT}`)

      // DateTime().today() is an alias for now()
      todayDT <- DateTime().today()
      stdout.println(`Today: ${todayDT}`)

      // Guard pattern - always executes because today() returns set value
      if today <- Date().today()
        stdout.println(`Guard confirmed today: ${today}`)

      // All three are set
      require currentDate?
      require currentTime?
      require currentDT?

      // The unset ones are not
      require ~unsetDate?
      require ~unsetTime?
      require ~unsetDT?

Common mistakes

E50001 — EK9 uses factory methods on instances, not static methods. Date().today() creates an unset Date then calls today() on it. Date.now() does not exist. Triggers E50001 — method not resolved. See ek9 -h Date for the full API.

Incorrect:

today <- Date.now()

Correct:

today <- Date().today()

E50001 — Renaming the variable means later references to 'currentDate' become unresolved, triggering E50001. See ek9 -h E50001 for details.

Incorrect:

currentDateXYZ <- Date().today()

Correct:

currentDate <- Date().today()
Other ways to ask this
  • How do I get today's date in EK9?
  • How do I get the current time in EK9?
  • What is the difference between Date() and Date().today()?

Coming from another language?

Java: LocalDate.now(), LocalTime.now(), ZonedDateTime.now() static factory methods. Python: datetime.date.today(), datetime.datetime.now(). JavaScript: new Date() gives current moment (confusing: constructor IS the factory). Go: time.Now(). Rust: chrono::Local::now(). EK9: Date().today(), Time().now(), DateTime().now() factory methods; no-arg constructor creates unset, not current.

Keywords: factory, clock, datetime, current, timezone, time, unset, date, today, now, duration