Shell – How to parse ISO8601 dates with linux date command

dateshell-script

I'm trying to use the date command to generate a file timestamp that the date command itself can interpret. However, the date command does not seem to like its own output, and I am not sure how to work around this. Case in point:

sh-4.2$ date
Fri Jan  3 14:22:19 PST 2014
sh-4.2$ date +%Y%m%dT%H%M
20140103T1422
sh-4.2$ date -d "20140103T1422"
Thu Jan  2 23:22:00 PST 2014

date appears to be interpreting the string with an offset of 15 hours. Are there any known workarounds for this?

Edit: this is not an issue of display:

sh-4.2$ date +%s
1388791096
sh-4.2$ date +%Y%m%dT%H%M
20140103T1518
sh-4.2$ date -d 20140103T1518 +%s
1388737080
sh-4.2$ python
Python 3.3.3 (default, Nov 26 2013, 13:33:18) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1388737080 - 1388791096
-54016
>>> 54016/3600
15.004444444444445
>>> 

It's still off by 15 hours when displayed as a unix timestamp.

EDIT #1

Maybe I should pose this question a little differently. Say I have a list of ISO8601 basic timestamps of the form:

  • YYYYMMDDThhmm
  • YYYYMMDDThhmmss

What is the simplest way to convert them to the corresponding Unix timestamps?

For example:

- 20140103T1422   = 1388787720
- 20140103T142233 = 1388787753

Best Answer

You ask for "known workarounds." Here is a simple one:

$ date -d "$(echo 20140103T1422 | sed 's/T/ /')"
Fri Jan  3 14:22:00 PST 2014

This uses sed to replace "T" with a space. The result is a format that date understands.

If we add seconds onto the ISO8601 date, then date requires more changes:

$ date -d "$(echo 20140103T142211 | sed -r 's/(.*)T(..)(..)(..)/\1 \2:\3:\4/')"
Fri Jan  3 14:22:11 PST 2014

In the above, sed replaces the "T" with a space and also separates HHMMSS into HH:MM:SS.

Related Question