How to convert a local date-time into UTC date-time

date

I am trying to get a bash script working and in order to do so I need to transform a local time in +%Y%m%d%H%M%S format (example: "20150903170731") into UTC time in the same format.

I know date -u can give me the current UTC time:

$ date +%Y%m%d%H%M%S  -u
20150903161322

Or, without the -u the local time (here, BST):

$ date +%Y%m%d%H%M%S
20150903171322

Now if I add an argument to date, I get an error:

echo "20150903154607" | xargs date +"%Y%m%d%H%M%S" -u
date: extra operand `20150903154607'

Is there any way I can do perform this conversion without such errors?

Best Answer

To pass a date to use into date, use the -d option. So your command would look something like echo "20150903154607" | xargs date +"%Y%m%d%H%M%S" -u -d.

It doesn't take exactly the date format you're supplying, though:

$ date -d 20150903154607
date: invalid date ‘20150903154607’
$ date -d 20150903\ 15:46:07
Thu Sep  3 15:46:07 BST 2015

So massage it a little first (GNU sed):

$ echo "20150903154607" \
   | sed -re 's/^([0-9]{8})([0-9]{2})([0-9]{2})([0-9]{2})$/\1\\ \2:\3:\4/' \
   | xargs date -u -d
Thu Sep  3 15:46:07 UTC 2015

To convert from local to UTC, you need to do a bit more, because -u affects the interpretation of both input and output dates:

$ echo "20150903171734" \
   | sed -re 's/^([0-9]{8})([0-9]{2})([0-9]{2})([0-9]{2})$/\1\\ \2:\3:\4/' \
   | xargs date +@%s -d \
   | xargs date -u +%Y%m%d%H%M%S -d
20150903161734

The first invocation of date above converts local time (according to $TZ) into seconds since the epoch; the second then converts epoch-seconds into UTC date and time.

Related Question