How do I format a date for display in EK9?

← Date, Time, and Duration · Ref: Q537

EK9 provides two approaches: the $ operator for ISO 8601 and Locale methods for human-readable regional formatting.

ISO 8601 VIA $ OPERATOR

The $ operator on Date, Time, and DateTime always produces ISO 8601 strings:

  $birthday gives '1971-02-01'
  $meeting gives '09:30:00'
  $timestamp gives '2024-06-15T10:30:00Z'

This is the machine-readable format, suitable for APIs, logging, and data exchange.

LOCALE FORMATTING — FOUR NAMED LEVELS

For human-readable display, use Locale with four named methods:

  shortFormat: compact, numeric (03/10/2020 or 10/3/20)
  mediumFormat: abbreviated month (Oct 3, 2020)
  longFormat: full month name (3. oktobra 2020)
  fullFormat: includes day-of-week (Saturday, 3 October 2020)

Each level adapts automatically to the locale's conventions.

NO PATTERN STRINGS

EK9 deliberately avoids format pattern strings like 'yyyy-MM-dd' or 'dd/MM/yyyy'. Pattern strings are error-prone: 'mm' means minutes in Java but months in Excel, 'DD' means day-of-year in Java but day-of-month in Moment.js. Named levels eliminate this entire class of bugs.

See Q44 for complete Locale formatting guide. See Q549 for locale date formatting examples. See Q551 for RFC 7231 HTTP date headers.

Example

defines module qa.format.date.display

  defines program
    FormatDateDisplayDemo()
      stdout <- Stdout()

      birthday <- 1971-02-01
      meeting <- 09:30:00
      timestamp <- 2024-06-15T10:30:00Z

      // $ operator gives ISO 8601
      stdout.println(`Date ISO: ${birthday}`)
      stdout.println(`Time ISO: ${meeting}`)
      stdout.println(`DateTime ISO: ${timestamp}`)

      // Locale formatting with four levels
      enGB <- Locale("en_GB")
      enUS <- Locale("en_US")
      deutsch <- Locale("de_DE")

      // Date formatting
      stdout.println(`GB short: ${enGB.shortFormat(birthday)}`)
      stdout.println(`US short: ${enUS.shortFormat(birthday)}`)
      stdout.println(`GB medium: ${enGB.mediumFormat(birthday)}`)
      stdout.println(`DE long: ${deutsch.longFormat(birthday)}`)
      stdout.println(`GB full: ${enGB.fullFormat(birthday)}`)
      stdout.println(`DE full: ${deutsch.fullFormat(birthday)}`)

      // Time formatting
      stdout.println(`GB short time: ${enGB.shortFormat(meeting)}`)
      stdout.println(`DE medium time: ${deutsch.mediumFormat(meeting)}`)

      // DateTime formatting
      stdout.println(`US short DT: ${enUS.shortFormat(timestamp)}`)
      stdout.println(`GB medium DT: ${enGB.mediumFormat(timestamp)}`)
      stdout.println(`DE long DT: ${deutsch.longFormat(timestamp)}`)

Common mistakes

E50060 — Locale has no generic format() method with a style parameter. EK9 provides four named methods: shortFormat(), mediumFormat(), longFormat(), fullFormat(). See ek9 -h E50060 for details.

Incorrect:

stdout.println(`GB short: ${enGB.format(birthday, "short")}`)

Correct:

stdout.println(`GB short: ${enGB.shortFormat(birthday)}`)
Other ways to ask this
  • How do I convert a date to a string in EK9?
  • What date format does the $ operator produce?
  • How do I display dates in different formats?

Coming from another language?

Java: DateTimeFormatter.ofPattern('yyyy-MM-dd') pattern strings, multiple format letter conventions. Python: strftime('%Y-%m-%d') with % codes. JavaScript: toLocaleDateString() or Intl.DateTimeFormat. Go: bizarre reference date '2006-01-02'. Rust: chrono format!() with strftime codes. EK9: $ for ISO 8601, Locale.shortFormat/mediumFormat/longFormat/fullFormat for human-readable. No pattern strings.

Keywords: time, mediumFormat, locale, iso8601, format, display, duration, date, pattern, migrate, shortFormat, timezone, longFormat, string, fullFormat