Pourquoi y a-t-il une différence avec la date Unix entre 2 et 3 mois

16

Comment est-ce possible et comment y faire face? Je fais un script de sauvegarde qui dépend d'Unix dateet j'ai découvert un bug intéressant:

[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
la source
Serait-ce un bug pour l'année bissextile / 29 février? Peu probable dans un outil comme datesi ...
Mark Henderson

Réponses:

44

Vous voyez ce comportement en raison de l'heure d'été (heure d'été).

Parce que vous êtes actuellement à l'heure d'été, où votre horloge a une heure d'avance, lorsque vous demandez il y a trois mois juste après minuit le premier juin, l'heure finit par être une heure "plus tôt" car ce n'était pas l'heure d'été trois il y a des mois.

La documentation de la date GNU suggère de contourner ce problème en utilisant midi et le 15 du mois comme points de départ, lors de la demande de jours ou de mois relatifs, respectivement. Par exemple:

date +%y-%m-%d --date="$(date +%Y-%m-15) -3 month"
Michael Hampton
la source
Merci. Oui, exactement "il y a 3 mois" à 01h00:[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
Ah! Je pense que je dois parcourir grep certains de mes scripts car je soupçonne que j'ai négligé cette suggestion sur l' dateutilisation.
Caleb
14

Si le timing absolu est votre principale préoccupation, il est probablement préférable de travailler à partir de l' UTC tel qu'il existe à cet effet. La réponse de Michael est très utile lorsque vous devez travailler à l'intérieur du problème, mais c'est généralement une bonne idée de l'éviter entièrement où vous le pouvez.

Lorsque votre système n'est pas défini sur UTC par défaut, le moyen le plus simple de passer le fuseau horaire est de préfixer votre commande avec la TZvariable d'environnement. Cela limite le commutateur de zone à une seule commande et empêche la variable de fuir dans vos commandes suivantes.

$ 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

Ce que vous ne devriez pas faire, c'est exporter la TZvariable car cela peut rendre les choses très difficiles à résoudre, comme le montre ce qui suit.

$ 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
la source
-3

En cette année spécifique où votre ordinateur pense qu'il fonctionne, et à la date précise que vous avez choisie pour un test "il y a 1 mois, 2 mois et 3 mois, oui - il s'agit probablement d'une détection le 29 février. Pas toujours une erreur, mais ..

Aujourd'hui, ce n'est PAS le 2014-06-01. Réessayer. Réglez la date de l'ordinateur sur 2013-06-01. Réessayer.
Réglez la date de l'ordinateur sur 2014-09-01. Réessayer.

user225906
la source
6
Si vous fournissez des dates au MDYformat américain , utilisez les /es pour la séparation. Encore mieux, comme nous sommes une communauté internationale ici, utilisez des dates ISO appropriées telles que 2014-09-01.
glglgl