+++
title = "RFC822 formatted datetimes and CET timezone"
+++

While working on [Gozer](https://github.com/dannyvankooten/gozer), the static site generator responsible for building this website from a bunch of Markdown files, I got bit by a peculiarity around RFC822 formatted datetimes and Golang's constants for common datetime formats.

I was working on adding support for RSS feeds, which is an XML feed that conforms to the [RSS 2.0 specification](https://www.rssboard.org/rss-specification).
That specification states that all datetimes in RSS must conform to the [Date and Time Specification of RFC 822](https://www.rfc-editor.org/rfc/rfc822.html#section-5.1).

This format is important enough to have its own [constant in Golang's time package](https://pkg.go.dev/time#pkg-constants) so formatting a local time in that format should be as easy as:

```go
publishedAt.Format(time.RFC822)
```

Except... W3C's feed validation service kept rejecting the RSS feed because of a "[problematic RFC 822 date-time value](https://validator.w3.org/feed/docs/warning/ProblematicalRFC822Date.html)".

Huh. Is Golang outputting the wrong format or is W3C being weird? Who's wrong here?

The datetime being rejected looked like this:

```
Wed, 22 Nov 2023 16:33:55 CET
```

While W3C's feed validation service shows the following as an example datetime which is valid:

```
Wed, 02 Oct 2002 08:00:00 EST
```

Can you spot the difference? Just looking at the format, I couldn't.

### Accepted timezone abbreviations for RFC 822

After taking a closer look at the RFC 822 specification their list of valid time zone abbreviations looked... lacking.

```txt
zone        =  "UT"  / "GMT"                ; Universal Time
                                         ; North American : UT
         /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
         /  "CST" / "CDT"                ;  Central:  - 6/ - 5
         /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
         /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
         /  1ALPHA                       ; Military: Z = UT;
                                         ;  A:-1; (J not used)
                                         ;  M:-12; N:+1; Y:+12
         / ( ("+" / "-") 4DIGIT )        ; Local differential
                                         ;  hours+min. (HHMM)
```

It turns out that `CET` is not a valid time zone according to RFC 822. Only UTC, GMT and US time zone abbreviations are accepted...

That lead me to checking ISO 8601, which doesn't accept _any_ abbreviations because they can be ambiguous.
For example, "CST" can mean China Standard Time (UTC+8), Cuba Standard Time (UTC−5), and (North American) Central Standard Time (UTC−6).

It is therefore recommended to always specify the timezone in terms of its UTC offset.

In this particular case the fix was to use `time.RFC822Z` as my format string, which specifies the timezone offset numerically.

Today I learned!



