Comment trouver la différence de jours entre deux dates?
A= "2002-20-10 "
B = "2003-22-11 "
Comment trouver la différence de jours entre deux dates?
17 réponses
The bash way - convertissez les dates en%Y % m % d format et puis vous pouvez le faire directement à partir de la ligne de commande:
echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
et en python
$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
attention! Bon nombre des solutions de bash ici sont brisées pour les plages de dates qui couvrent la date où l'heure d'été commence (le cas échéant). Ceci est dû au fait que la construction $(( math )) effectue une opération "plancher" /troncature sur la valeur résultante, en retournant seulement le nombre entier. Permettez-moi d'illustrer:
DST a commencé le 8 mars de cette année aux États-Unis, donc utilisons une gamme de date couvrant que:
start_ts=$(date -d "2015-03-05" '+%s')
end_ts=$(date -d "2015-03-11" '+%s')
voyons ce que nous obtenons avec le double parenthèse:
echo $(( ( end_ts - start_ts )/(60*60*24) ))
renvoie "5".
faire ceci en utilisant 'bc' avec plus de précision nous donne un résultat différent:
echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc
retourne '5.95' - le 0.05 manquant étant l'heure perdue à partir du passage au DST.
alors comment faire correctement?
Je suggérerais d'utiliser ceci à la place:
printf "%.0f" $(echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc)
ici, le 'printf' fait le tour du résultat plus précis calculé par "bc", nous donnant la plage de date correcte de "6".
Edit: mettre en évidence la réponse dans un commentaire de @hank-schultz ci-dessous, que j'ai utilisé dernièrement:
date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s) )/(60*60*24) ))
cela devrait également être leap second safe aussi longtemps que vous soustrayez toujours la date précédente de la plus récente, puisque les secondes intercalaires ne feront qu'ajouter à la différence - troncature tourne effectivement vers le bas au bon résultat.
Voici la version MAC OS X pour votre confort.
$ A="2002-20-10"; B="2003-22-11";
$ echo $(((`date -jf %Y-%d-%m $B +%s` - `date -jf %Y-%d-%m $A +%s`)/86400))
nJoy!
Si l'option -d fonctionne dans votre système, voici une autre façon de le faire. Il y a une mise en garde que cela ne tiendrait pas compte des années bissextiles puisque j'ai considéré 365 jours par année.
date1yrs=`date -d "20100209" +%Y`
date1days=`date -d "20100209" +%j`
date2yrs=`date +%Y`
date2days=`date +%j`
diffyr=`expr $date2yrs - $date1yrs`
diffyr2days=`expr $diffyr \* 365`
diffdays=`expr $date2days - $date1days`
echo `expr $diffyr2days + $diffdays`
même si vous N'avez pas GNU date, Perl sera probablement installé:
use Time::Local;
sub to_epoch {
my ($t) = @_;
my ($y, $d, $m) = ($t =~ /(\d{4})-(\d{2})-(\d{2})/);
return timelocal(0, 0, 0, $d+0, $m-1, $y-1900);
}
sub diff_days {
my ($t1, $t2) = @_;
return (abs(to_epoch($t2) - to_epoch($t1))) / 86400;
}
print diff_days("2002-20-10", "2003-22-11"), "\n";
retourne 398.041666666667
-- 398 jours et une heure en raison de l'heure avancée.
La question est revenue sur mon alimentation. Voici une méthode plus concise en utilisant un module Perl bundled
days=$(perl -MDateTime -le '
sub parse_date {
@f = split /-/, shift;
return DateTime->new(year=>$f[0], month=>$f[2], day=>$f[1]);
}
print parse_date(shift)->delta_days(parse_date(shift))->in_units("days");
' $A $B)
echo $days # => 398
je proposerais une autre solution à Ruby. On dirait que c'est le plus petit et le plus propre à l'air jusqu'à présent:
A=2003-12-11
B=2002-10-10
DIFF=$(ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')")
echo $DIFF
sur unix, vous devriez avoir GNU dates installé. vous n'avez pas besoin de s'écarter de bash. voici la solution épuisée considérant les jours, juste pour montrer les étapes. elle peut être simplifiée et étendue à des dates complètes.
DATE=$(echo `date`)
DATENOW=$(echo `date -d "$DATE" +%j`)
DATECOMING=$(echo `date -d "20131220" +%j`)
THEDAY=$(echo `expr $DATECOMING - $DATENOW`)
echo $THEDAY
ça marche pour moi:
A="2002-10-20"
B="2003-11-22"
echo $(( (`date -d $B +%s` - `date -d $A +%s`) / 86400 )) days
Imprime
398 days
que se passe-t-il?
- valides chaîne de temps en Un et B
- Utiliser
date -d
pour gérer les chaines de temps - utilisez
date %s
pour convertir les chaînes de temps en secondes depuis 1970 (unix epoche) - Utiliser bash paramètre d'extension pour soustraire secondes
- diviser par secondes par jour (86400=60*60*24) pour obtenir la différence en jours
- ! heure d'été n'est pas pris en compte ! Voir cette réponse à unix.stackexchange !
essayez ceci:
perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'
une autre version de Python:
python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()"
supposons que nous rsync Oracle DB sauvegardes sur un disque tertiaire manuellement. Ensuite, nous voulons supprimer les anciennes sauvegardes sur le disque. Voici donc un petit script bash:
#!/bin/sh
for backup_dir in {'/backup/cmsprd/local/backupset','/backup/cmsprd/local/autobackup','/backup/cfprd/backupset','/backup/cfprd/autobackup'}
do
for f in `find $backup_dir -type d -regex '.*_.*_.*' -printf "%f\n"`
do
f2=`echo $f | sed -e 's/_//g'`
days=$(((`date "+%s"` - `date -d "${f2}" "+%s"`)/86400))
if [ $days -gt 30 ]; then
rm -rf $backup_dir/$f
fi
done
done
modifier le RIF et la période de conservation ("30 jours") en fonction de vos besoins.
utiliser les fonctions shell de http://cfajohnson.com/shell/ssr/ssr-scripts.tar.gz ; ils fonctionnent dans N'importe quel shell Unix standard.
date1=2012-09-22
date2=2013-01-31
. date-funcs-sh
_date2julian "$date1"
jd1=$_DATE2JULIAN
_date2julian "$date2"
echo $(( _DATE2JULIAN - jd1 ))
voir la documentation à http://cfajohnson.com/shell/ssr/08-The-Dating-Game.shtml
utilisant la commande mysql
$ echo "select datediff('2013-06-20 18:12:54+08:00', '2013-05-30 18:12:54+08:00');" | mysql -N
résultat: 21
NOTE: seules les parties date des valeurs sont utilisées dans le calcul
référence: http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_datediff
cela suppose qu'un mois est 1/12 d'une année:
#!/usr/bin/awk -f
function mktm(datespec) {
split(datespec, q, "-")
return q[1] * 365.25 + q[3] * 365.25 / 12 + q[2]
}
BEGIN {
printf "%d\n", mktm(ARGV[2]) - mktm(ARGV[1])
}
For MacOS sierra (maybe from Mac OS X yosemate),
pour obtenir le temps d'époque (secondes à partir de 1970) à partir d'un fichier, et le sauver à un var:
old_dt=`date -j -r YOUR_FILE "+%s"`
pour obtenir l'époque de l'heure actuelle
new_dt=`date -j "+%s"`
pour calculer la différence de plus de deux temps d'époque
(( diff = new_dt - old_dt ))
pour vérifier si la différence est supérieure à 23 jours
(( new_dt - old_dt > (23*86400) )) && echo Is more than 23 days