Цитирование через unix-даты

У меня довольно простая задача, но она не смогла найти правильное решение. Я хочу итератировать интервал дат с 2008 года для текущих и требуемых значений эпох для каждой итерации цикла. Я заинтересован в итерации как лет, так и половин и месяцев.
Я написал такой скрипт

#!/bin/bash initial_date=`date -d "2008-02-04 00:00:00 UTC" +%s` end_date=`date +%s` n=0 until [ $initial_date -gt $end_date ]; do echo $initial_date let n+=1 readable_date=`date +"%Y-%m-%d %T" -d "1970-01-01 $initial_date sec"` echo $readable_date readable_date=`date -d "$readable_date + $n year"` initial_date=`date -d "$readable_date" +%s` done 

но его выход довольно странный для меня:

1202083200
2008-02-04 00 : 00: 00
1233702000
2009-02-03 23 : 00: 00
1265230800
2010-02-03 21 : 00: 00
1296756000
2011-02-03 18 : 00: 00
1328277600
2012-02-03 15 : 00: 00
1359885600
2013-02-03 11 : 00: 00
1391403600
2014-02-03 06 : 00: 00
1422918000
2015-02-02 23 : 00: 00
1454425200
2016-02-02 15 : 00: 00

Почему год не увеличивается правильно? Сдвиг часов кажется мне побочным эффектом unix >> UTC >> unix conversion. Есть ли какой-либо прямой (без реверсии) метод для этого?

PS
И да, я проверил это , этот и этот вопрос и не нашел ясного способа сделать это. Все они основаны на увеличении числа и преобразовании даты с помощью этого, что не кажется мне точным.

И да, я думал о добавлении 60*60*24*30*365 к начальной дате, но будет ли это правильно? Этот подход не учитывает високосные годы, месяцы, составляющие 31 день, и так далее.

2 Solutions collect form web for “Цитирование через unix-даты”

Используемая дата:

 $ dateA="2008-02-04 00:00:00 UTC" 

Первой причиной получения дат со сменными временами является запрос «местных» дат:

 $ date -d "$dateA" Sun Feb 3 19:00:00 EST 2008 

Который будет исправлен, если вы укажете время UTC:

 $ TZ=UTC0 date -d "$dateA" Mon Feb 4 00:00:00 UTC 2008 

Или лучше (используйте привычку использовать его) используйте опцию -u даты:

 $ date -ud "$dateA" Mon Feb 4 00:00:00 UTC 2008 

Вторая причина – запросить «относительные элементы» со знаком:

 $ date -ud "$(date +"%Y-%m-%d %T" -ud "$dateA") +1 year" ### wrong Tue Feb 3 23:00:00 UTC 2009 $ date -ud "$(date +"%Y-%m-%d %T" -ud "$dateA") 1 year" ### better Mon Feb 4 00:00:00 UTC 2008 

Но все время проблемы (обычно) исчезают, когда используется «часовой пояс» (-z):

 $ date -ud "$(date +"%Y-%m-%d %T %z" -ud "$dateA") +1 year" ### Best Wed Feb 4 00:00:00 UTC 2009 $ date -ud "$(date +"%Y-%m-%d %T %z" -ud "$dateA") 1 year" ### Preferred Wed Feb 4 00:00:00 UTC 2009 

Проблема связана с тем, как синтаксическая строка даты обрабатывается, если значение TZ отсутствует, +1 может быть интерпретировано как значение временной зоны:

 $ date -ud "2008-02-04 00:00:00 +3 year" Tue Feb 3 21:00:00 UTC 2009 

Даже если значение среды для TZ установлено:

 $ TZ=UTC0 date -ud "2008-02-04 00:00:00 +3 year" Tue Feb 3 21:00:00 UTC 2009 

Да, год был взят один раз (2009 вместо 2008), но +3 был использован для изменения представленного времени (а не того, что было предназначено).

Повторяю: проблема в том, что +3 может анализироваться как значение временной зоны.


Кроме того, для преобразования (эпохи) секунд в даты, дата GNU может использовать «@»,

 $ dateAsec="$( date -ud "$dateA" +"%s" ) $ date -ud @"$dateAsec" Mon Feb 4 00:00:00 UTC 2008 

Сценарий (с использованием функции (newdate)) можно записать следующим образом:

 #!/bin/bash dateI="$(date -ud "2008-02-04 00:00:00 UTC" +%s)" dateF="$(date -u +%s)" newdate(){ date -ud "$(date +"%Y-%m-%d %T %z" -ud @"$dateI") $1 year" +"%s"; } n=0 while dateN="$( newdate "$n" )" (( dateN < dateF )); do dateNhuman="$(date +"%Y-%m-%d %T %z" -ud @"$dateN")" echo "dateN=$dateN --- $dateNhuman ---> $dateF $(( $dateF - $dateN )) $n" (( n++ )) done 

Результаты:

 dateN=1202083200 --- 2008-02-04 00:00:00 +0000 ---> 1470543626 268460426 0 dateN=1233705600 --- 2009-02-04 00:00:00 +0000 ---> 1470543626 236838026 1 dateN=1265241600 --- 2010-02-04 00:00:00 +0000 ---> 1470543626 205302026 2 dateN=1296777600 --- 2011-02-04 00:00:00 +0000 ---> 1470543626 173766026 3 dateN=1328313600 --- 2012-02-04 00:00:00 +0000 ---> 1470543626 142230026 4 dateN=1359936000 --- 2013-02-04 00:00:00 +0000 ---> 1470543626 110607626 5 dateN=1391472000 --- 2014-02-04 00:00:00 +0000 ---> 1470543626 79071626 6 dateN=1423008000 --- 2015-02-04 00:00:00 +0000 ---> 1470543626 47535626 7 dateN=1454544000 --- 2016-02-04 00:00:00 +0000 ---> 1470543626 15999626 8 

Все годы появляются, и все кажется правильным.

Итератор в относительной дате от начальной точки может иметь больше смысла:

 #!/usr/bin/env bash START='2008-02-04 00:00:00 UTC' END=$( date +%s ) for yearnum in $( seq 1 999 ); do NUDATE=$( date -d "$START + $yearnum year" +%s ) PUNY_HUMAN_DATE=$( date -d "@$NUDATE" "+%Y-%m-%d %T %Z" ) if [[ $NUDATE -gt $END ]]; then break fi echo $NUDATE $PUNY_HUMAN_DATE done 

Это приводит к чему-то вроде:

 -bash-4.1$ bash iter 1233705600 2009-02-04 00:00:00 UTC 1265241600 2010-02-04 00:00:00 UTC 1296777600 2011-02-04 00:00:00 UTC 1328313600 2012-02-04 00:00:00 UTC 1359936000 2013-02-04 00:00:00 UTC 1391472000 2014-02-04 00:00:00 UTC 1423008000 2015-02-04 00:00:00 UTC 1454544000 2016-02-04 00:00:00 UTC -bash-4.1$ 
  • Скопируйте файлы, исключая x, y, z, вызывая ошибку в сценарии оболочки
  • Массовое создание файлов с bash
  • эхо-имена и количество строк для каждого файла в каталоге
  • Сценарий оболочки для списка заблокированных пакетов во FreeBSD
  • Команда Grep в сценарии оболочки
  • скрипт для замены команды mkdir -p
  • Сценарий для обмена мониторами?
  • / bin / cat: слишком длинный список аргументов
  • Удаление файлов старше 500 дней
  • Как ускорить работу скрипта на основе поиска grep?
  • Домашний путь пользователей в сценарии bash
  • Interesting Posts

    Почему приложения Mono запускаются только из своего собственного каталога?

    Есть ли способ генерировать вывод команды без использования bashrc / bash_profile?

    Используйте команду sed, чтобы проверить, существует ли конкретная строка, если нет, добавьте ее

    Связь между портом, номером порта и протоколом?

    python Импорт запросов error

    setxkbmap для macbook pro (США)

    сделать HAPROXY в локальном файле вместо syslog?

    Изменение размера страницы Wmctrl

    Трубопровод нескольких строк в сценарии bash

    Сценарий оболочки для резервного копирования VMware VM, экспорт каждой виртуальной машины в список, а затем запрос пользователя на ввод

    Подстановочные знаки: как я могу перечислить файлы, заканчивающиеся на `.txt`, только без использования символа точки?

    Как проверить, используется ли звуковая карта и, если возможно, какой процесс ее использует?

    Как установить полное имя хоста на CentOS 7.0?

    Как использовать gtalk для Linux?

    Поверните консоль при запуске (Debian)

    Linux и Unix - лучшая ОС в мире.