您首先需要将日期时间标准化为GNU日期实用程序可识别的格式。之后,您可以进一步将其归一化为RFC 3339时间戳,其中包含时区信息。通过该时区信息,GNU日期将允许您使用-u
选项将该时区中的时间转换为UTC。这里有一个脚本,做一切:
# Convert the "yyyymmddhh" string in argument $1 to "yyyy-mm-dd hh:00" and
# pass the result to 'date --rfc-3339=seconds' to normalize the date.
# The date is interpreted in the timezone specified by the value that
# the "TZ" environment variable was at first invocation of the script.
#
# Example 1: 2015-12-10 10:00 PST (UTC-0800)
# $ env TZ='America/Los_Angeles' ./utcdate 2015121010
# 2015121018
#
# Example 2: 2015-10-10 10:00 PDT (UTC-0700; PST with DST in effect)
# $ env TZ='America/Los_Angeles' ./utcdate 2015101010
# 2015101017
# Raw YYYYMMDDHH converted to YYYY-MM-DD HH:00.
convldt="$(echo "$1" | awk '
$1 ~ /^[0-9]{10}/
{
year = substr($0, 1, 4)
mon = substr($0, 5, 2)
day = substr($0, 7, 2)
hour = substr($0, 9, 2)
printf("%s-%s-%s %s:00\n", year, mon, day, hour)
exit
}
{ print "errorfmt" ; exit 1 }
')"
if test x"$convldt" = xerrorfmt ; then
echo "note: Format must be YYYYMMDDHH." >&2
exit 1
fi
# The converted time is then normalized to include a timezone.
normldt="$(env TZ="$TZ" date -d "$convldt" --rfc-3339=seconds || echo error)"
test x"$normldt" = xerror && exit 2
# Convert to UTC.
date -u -d "$normldt" +'%Y%m%d%H'
然后你有一个通用脚本,它将对任何时区工作,你只需要设置TZ
在命令行上作为脚本的第一个注释块指出。该脚本将处理其余的事情,当遇到错误时退出。 sed -r
可能已经到位使用更简洁的语法被使用的awk
(-r
使POSIX ERES,这是什么awk
用于其正则表达式的语法; sed
默认为POSIX BREs里面):
convldt="$(echo "$1" | sed -r 's/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})/\1-\2-\3 \4:00/')"
我用awk
主要是因为阅读起来更容易。 sed
本来可以工作,但我真的不知道如何处理日期时间格式错误,因为我使用的是awk
。当需要错误处理时,sed
似乎不是正确的工具。
如果您打算在OS X上使用此功能,而不仅限于Linux,请使用the date
bits would need to be altered。另外,sed -r
would instead be sed -E
。
夏令时(DST)的状态应该从日期本身推断出来吗?如果是这样,请更新问题以包含此信息 - 可能有两个示例:一个是DST处于活动状态,另一个是DST处于非活动状态。正如现在所写,很难理解您是否只使用PDT,或者您是否也会处理PST。 –
@Chrono,是的,我需要处理PST和PDT。你能不能推荐一些时间来处理这两个时区。 – Jay