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?

59
demandé sur codeforester 2011-02-09 18:17:35

17 réponses

si vous avez GNU date , cela permet d'Imprimer la représentation d'une date arbitraire (option -d ). Dans ce cas, convertissez les dates en secondes depuis L'époque, soustrayez et divisez par 24*3600.

ou vous avez besoin d'un moyen portable?

24
répondu 2011-02-09 15:26:33

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) ))
49
répondu techjacker 2014-01-14 19:47:42

et en python

$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
14
répondu Fred Laurent 2011-11-18 08:10:09

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.

13
répondu evan_b 2017-12-27 22:22:42

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!

5
répondu nickl- 2018-05-30 02:45:44

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`
4
répondu Ruchi 2011-02-09 17:09:02

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
4
répondu glenn jackman 2013-06-18 20:01:52

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
1
répondu GreyCat 2011-02-10 15:52:03

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 
1
répondu mattymik 2013-12-01 00:41:55

ç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?

  1. valides chaîne de temps en Un et B
  2. Utiliser date -d pour gérer les chaines de temps
  3. utilisez date %s pour convertir les chaînes de temps en secondes depuis 1970 (unix epoche)
  4. Utiliser bash paramètre d'extension pour soustraire secondes
  5. diviser par secondes par jour (86400=60*60*24) pour obtenir la différence en jours
  6. ! heure d'été n'est pas pris en compte ! Voir cette réponse à unix.stackexchange !
1
répondu jschnasse 2018-04-09 08:32:07

essayez ceci:

perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'
0
répondu Dennis Williamson 2011-02-09 18:00:13

une autre version de Python:

python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()"
0
répondu Ulf 2011-12-12 19:17:46

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.

0
répondu Alex Cherkas 2013-03-19 18:13:01

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

0
répondu Chris F.A. Johnson 2013-06-18 17:35:30

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

0
répondu bruce 2013-06-20 10:25:12

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])
}
0
répondu Steven Penny 2016-12-29 03:35:42

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

0
répondu osexp2003 2017-06-11 13:05:02