How do I generate RFC 7231 HTTP date headers in EK9?

← Date, Time, and Duration · Ref: Q551

EK9 provides a built-in rfc7231() method on DateTime that produces the exact format required by HTTP headers.

ONE-LINER

  httpDate <- DateTime().now().rfc7231()

Produces: 'Sat, 15 Jun 2024 14:30:00 GMT'

THE RFC 7231 FORMAT

HTTP/1.1 requires dates in the format: 'Day, DD Mon YYYY HH:MM:SS GMT'
Examples:

  'Sat, 15 Jun 2024 14:30:00 GMT'
  'Wed, 25 Dec 2024 00:00:00 GMT'

The value is always in GMT (UTC). The rfc7231() method automatically converts to UTC regardless of the DateTime's timezone.

WHERE HTTP DATES ARE USED

  Date: response header (when the response was generated)
  Last-Modified: when the resource was last changed
  Expires: when the cached response becomes stale
  If-Modified-Since: conditional request header
  Retry-After: when to retry a failed request

WHY BUILT-IN

Every HTTP-serving application needs this format. In Java, you need DateTimeFormatter.RFC_1123_DATE_TIME. In Go, you use time.RFC1123. Making it a one-liner on DateTime eliminates a common boilerplate pattern.

See Q537 for general date formatting. See Q549 for locale formatting. See Q541 for timezone handling.

Example

defines module qa.rfc7231.http.headers

  defines program
    Rfc7231HttpHeadersDemo()
      stdout <- Stdout()

      // Generate RFC 7231 HTTP date from current time
      now <- DateTime().now()
      httpDate <- now.rfc7231()
      stdout.println(`Date: ${httpDate}`)

      // From a specific DateTime
      event <- 2024-06-15T14:30:00Z
      stdout.println(`Event: ${event.rfc7231()}`)

      // Works from any timezone - always converts to GMT
      nyEvent <- 2024-12-25T00:00:00-05:00
      stdout.println(`NY event: ${nyEvent.rfc7231()}`)

      // Typical HTTP response headers
      stdout.println(`Date: ${DateTime().now().rfc7231()}`)
      stdout.println(`Last-Modified: ${event.rfc7231()}`)

      // The result is a String
      headerValue <- event.rfc7231()
      require headerValue?
      stdout.println(`Type check: ${headerValue}`)

Common mistakes

E50060 — DateTime has no toRFC1123() method. EK9 uses rfc7231() which produces the HTTP-standard date format. See ek9 -h E50060 for details.

Incorrect:

httpDate <- now.toRFC1123()

Correct:

httpDate <- now.rfc7231()
Other ways to ask this
  • How do I format dates for HTTP headers?
  • How does rfc7231() work in EK9?
  • How do I create an HTTP Date header value?

Coming from another language?

Java: DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC)). Python: email.utils.formatdate(usegmt=True). JavaScript: new Date().toUTCString(). Go: t.UTC().Format(time.RFC1123). Rust: chrono format with custom pattern. EK9: dateTime.rfc7231() one-liner, always GMT.

Keywords: header, duration, migrate, http, api, gmt, time, last-modified, web, expires, format, date, timezone, rfc7231