J'ai un script Shell qui fonctionne sur Linux et utilise cet appel pour obtenir la date d'hier au format YYYY-MM-DD
:
date -d "1 day ago" '+%Y-%m-%d'
Cela fonctionne la plupart du temps, mais lorsque le script a été exécuté hier matin à 2013-03-11 0:35 CDT
, il a renvoyé "2013-03-09"
au lieu de "2013-03-10"
.
L'heure d'été (qui a commencé hier) est probablement à blâmer. Je suppose que la façon dont "1 day ago"
est mis en œuvre est soustraite 24 heures et 24 heures avant que 2013-03-11 0:35 CDT
soit 2013-03-09 23:35 CST
, ce qui conduit au résultat de "2013-03-09"
.
Alors, quel est le bon moyen de vérifier la date d'hier avec Linux?
Je pense que cela devrait fonctionner, peu importe la fréquence et quand vous le lancez ...
date -d "yesterday 13:00" '+%Y-%m-%d'
Bash sous Mac OSX est légèrement différent.
Pour hier
echo `date -v-1d +%F`
Pour la semaine dernière
echo `date -v-1w +%F`
Cela devrait aussi marcher, mais c'est peut-être trop:
date -d @$(( $(date +"%s") - 86400)) +"%Y-%m-%d"
Si vous êtes certain que le script s'exécute dans les premières heures de la journée, vous pouvez simplement le faire.
date -d "12 hours ago" '+%Y-%m-%d'
En passant, si le script fonctionne quotidiennement à 00h35 (via crontab?), Vous devez vous demander ce qui se passera si un changement d'heure d'été tombe dans cette heure; le script n'a pas pu être exécuté ou exécuté deux fois dans certains cas. Les implémentations modernes de cron
sont assez intelligentes à cet égard, cependant.
Voici une solution qui fonctionnera également avec Solaris et AIX.
Il est possible de manipuler le fuseau horaire pour modifier l’horloge de quelques heures .
Vous êtes sûr qu'hier, c'est il y a 20 ou 30 heures. Laquelle? Eh bien, le plus récent n'est pas aujourd'hui.
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
Le paramètre -e utilisé dans la commande echo est nécessaire avec bash, mais ne fonctionnera pas avec ksh . Dans ksh, vous pouvez utiliser la même commande sans l'indicateur -e.
Lorsque votre script sera utilisé dans différents environnements, vous pouvez le démarrer avec #!/Bin/ksh ou #!/Bin/bash. Vous pouvez également remplacer le\n par une nouvelle ligne:
echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1
vous pouvez utiliser
date -d "30 days ago" +"%d/%m/%Y"
pour obtenir la date d'il y a 30 jours, vous pouvez également remplacer 30 par x nombre de jours
Utilisez juste date
et des secondes fiables:
Comme vous l'avez fait remarquer à juste titre, de nombreux détails sur le calcul sous-jacent sont masqués si vous utilisez l'arithmétique du temps anglais. Par exemple. -d yesterday
et -d 1 day ago
auront un comportement différent.
Au lieu de cela, vous pouvez compter de manière fiable sur les secondes (documentées avec précision) depuis l’Unix Epoch UTC et sur l’arithmétique de base pour obtenir le moment souhaité:
date -d @$(( $(date +"%s") - 24*3600)) +"%Y-%m-%d"
Cela a été souligné dans un autre réponse . Ce formulaire est plus portable sur toutes les plates-formes avec différents indicateurs de ligne de commande date
, est indépendant de la langue (par exemple, "hier" et "hier" en français), et franchement (à long terme) sera plus facile à mémoriser, car bon, tu le sais déjà. Vous pourriez autrement continuer à vous demander: "était-ce encore -d 2 hours ago
ou -d 2 hour ago
?" ou "Est-ce que c'est -d yesterday
ou -d 1 day ago
que je veux?"). Le seul élément délicat ici est le @
.
Armé de bash et de rien d'autre:
Bash uniquement sur bash, vous pouvez également obtenir l'heure d'hier, via le script printf intégré:
%(datefmt)T
causes printf to output the date-time string resulting from using
datefmt as a format string for strftime(3). The corresponding argu‐
ment is an integer representing the number of seconds since the
Epoch. Two special argument values may be used: -1 represents the
current time, and -2 represents the time the Shell was invoked.
If no argument is specified, conversion behaves as if -1 had
been given.
This is an exception to the usual printf behavior.
Alors,
# inner printf gets you the current unix time in seconds
# outer printf spits it out according to the format
printf "%(%Y-%m-%d)T\n" $(( $(printf "%(%s)T" -1) - 24*3600 ))
ou, de manière équivalente à une variable temp (sous-shell externe facultatif, mais conserve l'environnement vars propre).
(
now=$(printf "%(%s)T" -1);
printf "%(%Y-%m-%d)T\n" $((now - 24*3600));
)
Remarque: malgré la page de manuel indiquant qu'aucun argument pour le formateur %()T
assumera un -1
par défaut, il semblerait que j'obtienne un 0 (merci, version de bash manuel 4.3.48)}