How to parse 'Thu, 22 Dec 2016 09:50:06 PST' into an sql TimeStamp in Java 8

108 Views Asked by At

The RSS specification states that date-time strings should be RFC 822 compliant. Example:

Sat, 07 Sep 2002 00:00:01 GMT. 

I can use:

 TimeStamp timestamp = TimeStamp.parse("Sat, 07 Sep 2002 00:00:01 GMT")

to store the RFC 822 formatted string into Derby. However, I have one feed that formats its dates like so:

Thu, 22 Dec 2016 09:50:06 PST

Not RFC 822/ISO8061 compliant, right? What format is this? How can I make it RFC 822 compliant and, how could I predict these without having a DateTimeFormatter for every non-compliant date-time string that a feed may throw at me?

1

There are 1 best solutions below

1
On BEST ANSWER

The format "Thu, 22 Dec 2016 09:50:06 PST" is NOT RFC-822-compliant for another reason than you think. The zone name PST is explicitly supported in RFC-822 (paragraph 5) and stands for GMT-07:00. However, the format given above is not compliant because it uses four-digit-year and not two-digit-year. This strong limitation was then corrected in RFC-1123 which says:

All mail software SHOULD use 4-digit years in dates, to ease the transition to the next century.

Another question is how to support it in Java. The best way is to write your own formatter with a custom pattern in all cases where Java-8-support is not sufficient. Java-8 only supports the first format using GMT-prefix but not PST in DateTimeFormatter.RFC_1123_DATE_TIME:

RFC-1123 updates RFC-822 changing the year from two digits to four. This implementation requires a four digit year. This implementation also does not handle North American or military zone names, only 'GMT' and offset amounts.

Update:

Meanwhile I have released a new version of my library Time4J-v.22 which supports northamerican timezone abbreviations, too. It is realized as constant ChronoFormatter.RFC_1123. Example of usage:

Instant instant = 
  ChronoFormatter.RFC_1123.parse("Thu, 22 Dec 2016 09:50:06 PST").toTemporalAccessor();

Only military zones are not yet supported, and I don't intend to go that way because the RFC-822-spec had got a sign error with all military zones (with the only exception of "Z"). So you can either use this simple and performant way (adding an extra dependency) or write a parser composed of many different formats based on instances of java.time.format.DateTimeFormatter.