Получить вчера дату в bash в Linux, DST-safe

У меня есть оболочка script, которая работает в Linux и использует этот вызов для получения вчерашней даты в формате YYYY-MM-DD:

date -d "1 day ago" '+%Y-%m-%d'

Он работает большую часть времени, но когда script запускался вчера утром в 2013-03-11 0:35 CDT, он возвращал "2013-03-09" вместо "2013-03-10".

Предположительно, летнее время (которое началось вчера) виновато. Я предполагаю, что способ "1 day ago" реализован, он вычитал 24 часа, а за 24 часа до 2013-03-11 0:35 CDT был 2013-03-09 23:35 CST, что привело к результату "2013-03-09".

Итак, какой хороший DST-безопасный способ получить вчера дату в bash на Linux?

Ответ 1

Я думаю, что это должно работать, независимо от того, как часто и когда вы запускаете его...

date -d "yesterday 13:00" '+%Y-%m-%d'

Ответ 2

Bash в Mac OSX немного отличается.

За вчерашний день

echo `date -v-1d +%F`

За последнюю неделю

echo `date -v-1w +%F`

Ответ 3

Это также должно работать, но, возможно, это слишком много:

date -d @$(( $(date +"%s") - 86400)) +"%Y-%m-%d"

Ответ 4

Если вы уверены, что script работает в первые часы дня, вы можете просто сделать

  date -d "12 hours ago" '+%Y-%m-%d'

BTW, если script работает ежедневно в 00:35 (через crontab?), вы должны спросить себя, что произойдет, если изменение DST упадет в этот час; script не может работать или запускаться дважды в некоторых случаях. Однако современные реализации cron достаточно умны в этом отношении.

Ответ 5

Здесь также будет решение, которое будет работать с Solaris и AIX.

Управление часовым поясом возможно для изменения часов в несколько часов. Из-за летнего времени, 24 часа назад может быть сегодня или позавчера.

Вы уверены, что вчера прошло 20 или 30 часов назад. Который из? Ну, последнее, что не сегодня.

echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

Параметр -e, используемый в команде echo, необходим с bash, но не будет работать с ksh. В ksh вы можете использовать ту же команду без флага -e.

Когда ваш script будет использоваться в разных средах, вы можете запустить script с помощью #!/bin/ksh или #!/bin/bash. Вы также можете заменить \n на новую строку:

echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

Ответ 6

вы можете использовать

date -d "30 days ago" +"%d/%m/%Y"

чтобы получить дату с 30 дней назад, аналогично вы можете заменить 30 на x количество дней