Прежде всего вам необходимо нормализовать ваше время и дату, чтобы формат был распознан утилитой даты GNU. После этого вы можете нормализовать его до метки времени RFC 3339, которая включает информацию о часовом поясе. С этой информацией о часовом поясе дата GNU позволит вам преобразовать время в этом часовом поясе в UTC с помощью опции -u
. Вот скрипт, который делает все, что:
# 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 Brès):
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