6

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?

Toby Speight
  • 8,678
Franco
  • 167

2 Answers2

8

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.

Toby Speight
  • 8,678
  • just add the timezone explicitly to the input date. eg in the sed append 'BST'. – meuh Sep 03 '15 at 16:59
  • @meuh - perhaps; it depends on what HashGuy is actually trying to do (I didn't find it clear in the question). – Toby Speight Sep 03 '15 at 17:01
  • I need the response back following same format of input 20150903171734 to 20150903161734 if that make sense... I need to use the string afterwards – Franco Sep 03 '15 at 17:04
  • I've edited with a local-to-UTC example. I haven't tested to see what it does during the 1-hour window of ambiguous local time... – Toby Speight Sep 03 '15 at 17:12
  • You see on the 27 March 2016 the time will go back to gmt again... I therefore think that Unix server should automatically updated to that time as well same the underlying database server... So logically between 27 March and June 2016 time will be gmt anyway – Franco Sep 03 '15 at 18:55
  • Is this a stupid assumption? – Franco Sep 03 '15 at 18:56
  • Toby look what i have done for testing this but still i am having problem storing the echo into a variable DateNew='20150903' TimeNew='200001' DateTimeNew_Suffix=${DateNew}${TimeNew} newPrefix=echo "${DateTimeNew_Suffix}"| 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 echo $newPrefix this is the error date: extra operand 20:00:01' Trydate --help' for more information. date: option requires an argument -- 'd' Try `date --help' for more information. – Franco Sep 03 '15 at 20:33
  • thanks toby .... i raised a different question this sed mask is working in output – Franco Sep 03 '15 at 20:52
4

I also used something more simple:

date -u -d @$(date -d '2019-09-17 19:29:45' +%s)
Tue Sep 17 23:29:45 UTC 2019

you still need conversion from your custom format to the one understandable by date, it was described in the previous answer

stimur
  • 141