Często chcę dokonać szybkich obliczeń dat, takich jak:
- Jaka jest różnica między tymi dwiema datami?
- Jaka jest data n tygodni po tej drugiej dacie?
Zwykle otwieram kalendarz i liczę dni, ale myślę, że powinien istnieć program / skrypt, którego można użyć do tego rodzaju obliczeń. Jakieś sugestie?
Odpowiedzi:
„N tygodni po dacie” jest łatwe dzięki GNU date (1):
Nie znam prostego sposobu obliczenia różnicy między dwiema datami, ale można zawrzeć trochę logiki wokół date (1) za pomocą funkcji powłoki.
Zamień
d1
id2
jeśli chcesz obliczyć datę w inny sposób, lub zdobądź nieco bardziej fanatyzmu, aby to nie miało znaczenia. Co więcej, w przypadku, gdy w danym przedziale czasowym nastąpi przejście bez DST na DST , jeden z dni będzie trwał tylko 23 godziny; możesz to zrekompensować, dodając do sumy ½ dnia.źródło
Aby uzyskać zestaw przenośnych narzędzi, wypróbuj moje własne dateutils . Twoje dwa przykłady sprowadzałyby się do jednowierszowych:
lub w tygodniach i dniach:
i
źródło
dateadd -i '%m%d%Y' 01012015 +1d
wydaje się, że nie działa, po prostu zawiesza się tam w nieskończoność ... działa, jeśli specyfikacje daty są oddzielone char, dowolny char ... jakiś pomysł, co jest nie tak?)Przykład pythonowy do obliczania liczby dni, kiedy chodziłem po planecie:
źródło
ychaouche@ychaouche-PC ~ $ python -c "from datetime import date as d; print (d.today() - d(1980, 6, 14)).days"
12813
ychaouche@ychaouche-PC ~ $
Zwykle wolę mieć czas / datę w formacie uniksowym (liczba sekund od epoki, kiedy zaczęły się lata siedemdziesiąte, UTC). W ten sposób zawsze sprowadza się do zwykłego odejmowania lub dodawania sekund.
Problemem zwykle staje się przekształcenie daty / godziny w ten format.
W środowisku powłoki / skrypcie można go uzyskać.
date '+%s'
W chwili pisania tego aktualny czas to1321358027
.Aby porównać z 2011-11-04 (moje urodziny)
date '+%s' -d 2011-11-04
, przynosząc1320361200
. Odejmij:expr 1321358027 - 1320361200
daje996827
sekundy, czyliexpr 996827 / 86400
= 11 dni temu.Konwertowanie z utime (format 1320361200) na datę jest bardzo proste, na przykład w C, PHP lub Perlu, przy użyciu standardowych bibliotek. GNU
date
The-d
argument może być poprzedzane@
wskazać „sekund od Epoki” formatu.źródło
date -d @1234567890
konwertuje od sekundy od epoki do dowolnego określonego formatu daty.info date
zwłaszcza Sekundy od węzła Epoki : „Jeśli poprzedzisz liczbę znakiem„ @ ”, oznacza ona wewnętrzny znacznik czasu jako liczbę sekund.”Pojawiło się to podczas
date -d "$death_date - $y years - $m months - $d days"
uzyskiwania daty urodzenia (dla genealogii). To polecenie jest NIEPRAWIDŁOWE. Miesiące nie są jednakowej długości, więc(date + offset) - offset != date
. Wiek, w roku / miesiącu / dniu, jest miarą naprzód od daty urodzenia.Data daje poprawny wynik w obu przypadkach, ale w drugim przypadku zadałeś niewłaściwe pytanie. Ma znaczenie, KTÓRE 11 miesięcy w roku pokrywa +/- 11, przed dodaniem / odjęciem dni. Na przykład:
Aby odjęcie było odwrotną operacją dodawania, kolejność operacji musiałaby zostać odwrócona. Dodanie dodaje lata, NASTĘPNIE miesiące, NASTĘPNIE dni. Jeśli odejmujesz w odwrotnej kolejności, wrócisz do punktu początkowego. Nie zmienia się, więc nie, jeśli przesunięcie dni przekracza granicę miesiąca w innym miesiącu długości.
Jeśli musisz cofnąć się od daty i wieku zakończenia, możesz to zrobić za pomocą wielu wywołań
date
. Najpierw odejmij dni, potem miesiące, a potem lata. (Nie sądzę, że łączenie lat i miesięcy w jednymdate
wywołaniu jest bezpieczne, ponieważ lata przestępne zmieniają długość lutego).źródło
Jeśli narzędzie graficzne jest dla Ciebie w porządku, szczerze polecam
qalculate
(kalkulator z naciskiem na konwersje jednostek, jest wyposażony w interfejs GTK i KDE, IIRC). Tam możesz powiedzieć npaby uzyskać liczbę dni (140, ponieważ rok 1900 nie był rokiem przestępnym) między datami, ale oczywiście można również zrobić to samo dla czasów:
daje
8.4591667
godzin lub, jeśli ustawisz wyjście do formatowania czasu8:27:33
.źródło
qalc
więchelp days
.qcalc
przykład:qalc -t 'days(1900-05-21, 1900-01-01)'
-> 140Często używam SQL do obliczania daty. Na przykład MySQL , PostgreSQL lub SQLite :
Innym razem mam ochotę na JavaScript. Na przykład SpiderMonkey , WebKit , Seed lub Node.js :
(Uważaj podczas przekazywania miesiąca do konstruktora
Date
obiektu JavaScript . Zaczyna się od 0.)źródło
Można użyć tego innego sposobu obliczenia różnicy między dwiema datami tego samego roku kalendarzowego:
date
do zmiennej DATEpierwszy.-d
Flaga wyświetla ciąg w formacie czasowym w tej sprawie 14 maja 2014 roku i+"%j"
opowiadadate
o sformatowanie wyjście tylko dzień roku (1-365).DAYSdif
do różnicy dwóch dni.DAYSdif
.Działa to z wersją GNU
date
, ale nie w wersji PC-BSD / FreeBSD. Zainstalowałemcoreutils
z drzewa portów i/usr/local/bin/gdate
zamiast tego użyłem polecenia .źródło
DATEfirstnum=$(date -d "$1" +%s)
DATElastnum=$(date -d "$2" +%s)
Ponadto ten skrypt nie będzie w stanie obliczyć różnicy między dwoma różnymi latami.+%j
odnosi się do dnia roku (001..366), więc./date_difference.sh 12/31/2001 12/30/2014
wyniki -1. Jak zauważyły inne odpowiedzi, musisz przekonwertować obie daty na sekundy od 1970-01-01 00:00:00 UTC.$
wewnętrznej wyrażenia arytmetycznego:$((DATElastnum - DATEfirstnum))
zadziała również.Za pomocą rozwiązań dannas można to zrobić w jednym wierszu za pomocą następującego kodu:
(Działa zarówno w Python 2.x jak i Python 3.)
źródło
date
i bash może różnic w datach (pokazane opcje OS X). Najpierw umieść tę drugą datę.źródło
Istnieją również obliczenia czasu jednostki GNU w połączeniu z datą GNU:
(Gunits to jednostki w Linuksie, gdate to data)
źródło
datediff.sh na github: gist
źródło
odpowiedź camh zajmuje się większością z nich, ale możemy poprawić radzenie sobie z zaokrąglaniem, strefami czasowymi itp., a także uzyskać dodatkową precyzję i możliwość doboru naszych jednostek:
-d
informuje,date
że podajemy datę i godzinę do konwersji.+%s.%N
zmienia datę i godzinę na sekundy. nanosekundy od 1970-01-01 00:00:00 UTC.bc
oblicza różnicę między dwiema liczbami, a czynnik dzielący daje nam różne jednostki.printf
w razie potrzeby dodaje 0 przed miejscem po przecinku (bc
nie) i zapewnia zaokrąglanie do najbliższego (bc
po prostu obcina). Możesz także użyćawk
.Teraz uruchommy to z funky testowym przypadkiem,
Zwróć uwagę, że ponieważ długość miesiąca lub roku nie zawsze jest taka sama, nie ma tam jednej „poprawnej” odpowiedzi, choć w dzisiejszych czasach można by użyć 365,24 dni jako rozsądnego przybliżenia.
źródło
Możesz użyć biblioteki awk Velor :
Lub:
Wynik:
źródło