Por que há uma diferença na data do Unix entre 2 e 3 meses

16

Como isso é possível e como faço para lidar com isso? Estou fazendo um script de backup que depende do Unix datee descobri um bug interessante:

[root@web000c zfs_test]# date +%y-%m-%d --date='2 months ago'
14-04-01
[root@web000c zfs_test]# date +%y-%m-%d --date='3 months ago'
14-02-28
[root@web000c zfs_test]# date
Sun Jun  1 00:08:50 CEST 2014
Shirker
fonte
Poderia ser um ano bissexto / bug de 29 de fevereiro? Não em uma ferramenta como dateembora ...
Mark Henderson

Respostas:

44

Você está vendo esse comportamento por causa do horário de verão (horário de verão).

Como você está no horário de verão, onde seu relógio está uma hora à frente, quando você pergunta há três meses, logo após a meia-noite de 1º de junho, o horário acaba sendo uma hora "mais cedo", porque não eram três horas de verão meses antes.

A documentação da data do GNU sugere contornar isso usando o meio-dia e o dia 15 do mês como ponto de partida, ao solicitar dias ou meses relativos, respectivamente. Por exemplo:

date +%y-%m-%d --date="$(date +%Y-%m-15) -3 month"
Michael Hampton
fonte
obrigado. Sim, exatamente "3 meses atrás" vindo de 01 horas:[root@web000c zfs_test]# date +%y-%m-%d --date='3 months ago' 14-03-01 [root@web000c zfs_test]# date Sun Jun 1 01:00:15 CEST 2014
shirker
Doh! Acho que preciso passar por alguns dos meus scripts, pois desconfio que tenha ignorado essa sugestão de dateuso.
Caleb
14

Se o tempo absoluto for a sua principal preocupação, provavelmente é melhor trabalhar com o UTC como ele existe para esse fim. A resposta de Michael é muito útil para quando você precisa trabalhar dentro do problema, mas geralmente é uma boa idéia evitá-lo totalmente onde puder.

Quando seu sistema não está definido como UTC por padrão, a maneira mais simples de passar o fuso horário é prefixando seu comando com a TZvariável de ambiente. Isso limita a opção de zona a um único comando e evita que a variável vaze nos comandos subseqüentes.

$ NOW=$(date '+%s')
$ date -d @$NOW
Wed Jun 11 23:44:35 EDT 2014
$ TZ=UTC date -d @$NOW
Thu Jun 12 03:44:35 UTC 2014

O que você não deve fazer é exportar a TZvariável, pois isso pode tornar as coisas muito confusas para solucionar problemas, conforme demonstrado a seguir.

$ export TZ=UTC
$ date -d @$NOW
Thu Jun 12 03:44:35 UTC 2014
$ TZ=EDT date -d @$NOW
Thu Jun 12 03:44:35 EDT 2014
Andrew B
fonte
-3

Nesse ano específico em que seu computador pensa que está sendo operado e na data específica que você escolheu para um teste de "1 mês atrás, 2 meses atrás e 3 meses atrás, sim - é provável que seja uma detecção em 29 de fevereiro. Nem sempre um erro, mas ..

Agora, hoje NÃO é 01/06/2014. Tente novamente. Defina a data do computador para 01/06/2013. Tente novamente.
Defina a data do computador para 01/09/2014. Tente novamente.

user225906
fonte
6
Se você estiver fornecendo datas no MDYformato americano , use /es para separar. Ainda melhor, como somos uma comunidade internacional aqui, use datas ISO adequadas, como 2014-09-01.
glglgl