it-swarm.com.de

Wie finde ich den Unterschied zwischen zwei Terminen in Tagen?

A = "2002-20-10"
B = "2003-22-11" 

Wie finde ich den Unterschied zwischen zwei Terminen in Tagen?

64
Tree

Wenn Sie GNU date haben, können Sie die Darstellung eines beliebigen Datums drucken (Option -d) ..__ In diesem Fall konvertieren Sie die Datumsangaben in Sekunden seit Epoche.

Oder brauchen Sie einen tragbaren Weg?

25
user332325

Bash-Methode: Konvertieren Sie die Datumsangaben in das Format% y% m% d. Anschließend können Sie dies direkt von der Befehlszeile aus tun:

echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
52
techjacker

Und in Python

$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
15
Fred Laurent

Achtung! Viele der bash-Lösungen sind für Datumsbereiche, die das Datum umfassen, zu dem die Sommerzeit beginnt (falls zutreffend), kaputt. Dies liegt daran, dass das Konstrukt $ ((math)) den resultierenden Wert abschneidet und nur die ganze Zahl zurückgibt. Lass mich illustrieren:

DST begann dieses Jahr in den USA am 8. März, also verwenden wir einen Zeitraum, der Folgendes umfasst:

start_ts=$(date -d "2015-03-05" '+%s')
end_ts=$(date -d "2015-03-11" '+%s')

Mal sehen, was wir mit den doppelten Klammern bekommen:

echo $(( ( end_ts - start_ts )/(60*60*24) ))

Gibt '5' zurück. 

Wenn Sie 'bc' mit größerer Genauigkeit verwenden, erhalten Sie ein anderes Ergebnis:

echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc

Gibt '5.95' zurück - der fehlende 0,05 ist die verlorene Stunde von der DST-Umschaltung. 

Wie soll das richtig gemacht werden?
Ich würde stattdessen Folgendes verwenden: 

printf "%.0f" $(echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc)

Hier rundet das 'printf' das genauere Ergebnis, das mit 'bc' berechnet wurde, und gibt den korrekten Datumsbereich von '6' an. 

Bearbeiten: Hervorheben der Antwort in einem Kommentar von @ hank-schultz, den ich in letzter Zeit verwendet habe: 

date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s) )/(60*60*24) ))

Dies sollte auch sicherheitsrelevant sein, solange Sie immer das frühere Datum vom späteren subtrahieren, da die Schaltsekunden immer nur zu der Differenz beitragen - eine Verkürzung rundet das Ergebnis effektiv ab.

14
evan_b

Hier ist die MAC OS X-Version für Ihre Bequemlichkeit.

$ 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!

6
nickl-

Selbst wenn Sie kein GNU Datum haben, haben Sie wahrscheinlich Perl installiert:

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";

Dies gibt 398.041666666667 zurück - 398 Tage und eine Stunde aufgrund von Sommerzeit.


Die Frage kam wieder auf meinen Feed. Hier ist eine prägnantere Methode, die ein Perl-Modul verwendet

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
glenn jackman

Wenn die Option -d in Ihrem System funktioniert, können Sie dies auf andere Weise tun. Es gibt eine Einschränkung, die keine Schaltjahre berücksichtigen würde, da ich 365 Tage im Jahr berücksichtigt habe.

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
Ruchi

Das funktioniert für mich:

A="2002-10-20"
B="2003-11-22"
echo $(( ($(date -d $B +%s) - $(date -d $A +%s)) / 86400 )) days

Drucke

398 days

Was ist los?

  1. Geben Sie eine gültige Zeitzeichenfolge in A und B an. 
  2. Verwenden Sie date -d, um Zeitzeichenfolgen zu behandeln
  3. Verwenden Sie date %s, um seit 1970 Zeichenketten in Sekunden umzuwandeln (Unix-Epoche).
  4. Verwenden Sie bash-Parametererweiterung , um Sekunden abzuziehen
  5. teilen Sie die Anzahl pro Sekunde (86400 = 60 * 60 * 24), um die Differenz in Tagen zu erhalten 
  6. ! DST wird nicht berücksichtigt! Diese Antwort finden Sie unter unix.stackexchange !
3
jschnasse

Ich würde eine andere mögliche Lösung in Ruby einreichen. Es sieht so aus, als sei es der kleinste und sauberste, der bisher aussieht:

A=2003-12-11
B=2002-10-10
DIFF=$(Ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')")
echo $DIFF
1
GreyCat

auf Unix sollten Sie GNU -Daten installiert haben. Sie müssen nicht von bash abweichen. Hier ist die aufgereihte Lösung unter Berücksichtigung der Tage, nur um die Schritte zu zeigen. es kann vereinfacht und auf vollständige Daten erweitert werden. 

DATE=$(echo `date`)
DATENOW=$(echo `date -d "$DATE" +%j`)
DATECOMING=$(echo `date -d "20131220" +%j`)
THEDAY=$(echo `expr $DATECOMING - $DATENOW`)

echo $THEDAY 
1
mattymik

Für MacOS-Sierra (möglicherweise von Mac OS X-Yosemate),

So erhalten Sie eine Epoche (Sekunden aus 1970) aus einer Datei und speichern Sie sie in einer var: old_dt=`date -j -r YOUR_FILE "+%s"`

Um die Uhrzeit der aktuellen Uhrzeit zu erhalten new_dt=`date -j "+%s"`

Differenz zwischen zwei Epochen berechnen (( diff = new_dt - old_dt ))

Um zu überprüfen, ob diff mehr als 23 Tage beträgt (( new_dt - old_dt > (23*86400) )) && echo Is more than 23 days

0
osexp2003

Eine andere Python-Version:

python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()"
0
Ulf

Verwenden des mysql-Befehls

$ echo "select datediff('2013-06-20 18:12:54+08:00', '2013-05-30 18:12:54+08:00');"  | mysql -N

Ergebnis: 21

HINWEIS: Bei der Berechnung werden nur die Datumsteile der Werte verwendet

Referenz: http://dev.mysql.com/doc/refman/5.6/de/date-and-time-functions.html#function_datediff

0
bruce

Dies ist das einfachste, das ich mit Centos 7 arbeiten konnte:

OLDDATE="2018-12-31"
TODAY=$(date -d $(date +%Y-%m-%d) '+%s')
LINUXDATE=$(date -d "$OLDDATE" '+%s')
DIFFDAYS=$(( ($TODAY - $LINUXDATE) / (60*60*24) ))

echo $DIFFDAYS
0
Gotxi

Dies setzt voraus, dass ein Monat 1/12 eines Jahres ist:

#!/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
Steven Penny

Probieren Sie es aus:

Perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'
0

Angenommen, wir synchronisieren Oracle DB-Sicherungen manuell auf einer tertiären Festplatte. Dann möchten wir alte Sicherungen auf dieser Festplatte löschen. Hier ist ein kleines Bash-Skript:

#!/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

Ändern Sie das Verzeichnis und die Aufbewahrungsfrist ("30 Tage") entsprechend Ihren Bedürfnissen.

0
Alex Cherkas

Verwenden Sie die Shell-Funktionen von http://cfajohnson.com/Shell/ssr/ssr-scripts.tar.gz ; Sie arbeiten in jeder Standard-Unix-Shell.

date1=2012-09-22
date2=2013-01-31
. date-funcs-sh
_date2julian "$date1"
jd1=$_DATE2JULIAN
_date2julian "$date2"
echo $(( _DATE2JULIAN - jd1 ))

Siehe die Dokumentation unter http://cfajohnson.com/Shell/ssr/08-The-Dating-Game.shtml

0