1

How can Miller 5.6.2 convert a local date and time to UTC using an expression simpler than the following?

$ printf "time1\n2019-06-13 05:54 PM\n" | mlr --csv put '
  $time1=sec2gmt(
    localtime2sec(
      strftime(
        strptime($time1, "%Y-%m-%d %H:%M %p"),
        "%Y-%m-%d %H:%M:%S")));'
time1
2019-06-13T10:54:00Z

Note that my local time zone in June is EDT or -04:00:

$ date --date='2019-06-13 05:54 PM' '+%Y-%m-%dT%H:%M:%S %Z'
2019-06-13T17:54:00 EDT
$ date --date='2019-06-13 05:54 PM' '+%Y-%m-%dT%H:%M:%S%z'
2019-06-13T17:54:00-0400
Derek Mahar
  • 27,608
  • 43
  • 124
  • 174

1 Answers1

1

I found two similar expressions, both of which use strptime_local() instead of strptime() to parse the local date and time string and convert it to seconds since the Epoch in UTC (GMT):

$ printf "time1\n2019-06-13 05:54 PM\n" | mlr --csv put '
  $time1=strftime(
    strptime_local($time1, "%Y-%m-%d %H:%M %p"),
    "%Y-%m-%dT%H:%M:%SZ");'
time1
2019-06-13T10:54:00Z
$ printf "time1\n2019-06-13 05:54 PM\n" | mlr --csv put '
  $time1=sec2gmt(strptime_local($time1, "%Y-%m-%d %H:%M %p"));'
time1
2019-06-13T10:54:00Z

Both strftime() and sec2gmt() assume an argument of seconds since the Epoch in UTC.

Function strptime() assumes an input date and time string in UTC and ignores a time zone in the input string:

$ printf "time1\n2019-06-13 05:54 PM\n" | mlr --csv put '
  $time1=strptime($time1, "%Y-%m-%d %H:%M %p");'
time1
1560405240.000000
$ printf "time1\n2019-06-13 05:54 PM EDT\n" | mlr --csv put '
  $time1=strptime($time1, "%Y-%m-%d %H:%M %p %Z");'
time1
1560405240.000000

Function strptime_local() also ignores a time zone in the input date and time string, but assumes the string is in the local time zone and converts it to UTC:

$ printf "time1\n2019-06-13 05:54 PM\n" | mlr --csv put '
  $time1=strptime_local($time1, "%Y-%m-%d %H:%M %p");'
time1
1560423240.000000
$ printf "time1\n2019-06-13 05:54 PM EDT\n" | mlr --csv put '
  $time1=strptime_local($time1, "%Y-%m-%d %H:%M %p %Z");'
time1
1560423240.000000
$ printf "time1\n2019-06-13 05:54 PM EST\n" | mlr --csv put '
  $time1=strptime_local($time1, "%Y-%m-%d %H:%M %p %Z");'
time1
1560423240.000000
$ printf "time1\n2019-06-13 05:54 PM AUT\n" | mlr --csv put '
  $time1=strptime_local($time1, "%Y-%m-%d %H:%M %p %Z");'
time1
1560423240.000000
Derek Mahar
  • 27,608
  • 43
  • 124
  • 174
  • Turns out that neither of the two expressions in https://stackoverflow.com/revisions/61876042/2 give the correct result. Date and time `2019-06-13 05:54 PM -0400` actually translates to `2019-06-13 21:54:00 +0000` in UTC (see `date --utc --date="2019-06-13 17:54 -0400" "+%F %T %z"`). – Derek Mahar May 19 '20 at 18:59