Obliczyć datę sprzed 1125 dni w systemach innych niż GNU?

W linii poleceń Unix Bash chcę obliczyć datę sprzed 1125 dni przy użyciu podstawowego systemu operacyjnego (np. bez Perla lub Pythona).

W systemach z GNU Date mogę zrobić coś takiego:

ubuntu $ date --date="1125 days ago" Wed Nov 7 15:12:33 PST 2007 

Systemy FreeBSD lub MacOSX nie są dostarczane z datą GNU i nie obsługują wartości takich jak „X dni temu”.

freebsd81 $ date --date="+1125 days ago" date: illegal option -- - 

I może obliczyć datę sprzed kilku dni na komputerze Mac lub FreeBSD, ale jest to ograniczone do kilku dni:

# Today is really Dec 6, 2010. 4 days ago it was: macosx $ TZ=GMT+96 date +%Y%m%d 20101202 # But that doesn"t work if I want to see the date 8 days ago: macosx $ TZ=GMT+192 date +%Y%m%d 20101206 

Czy mogę obliczać stare daty w systemach innych niż GNU bez zagłębiania się w narzędzia takie jak Perl czy Python? A może muszę użyć mocniejszego języka skryptowego?

Odpowiedź

Cóż, możesz zrobić coś podstępnego, na przykład:

 $ echo "`date +%s` - (1125 * 24 * 60 *60)" |bc 1194478815 $ date -r 1194478689 Wed, 07 Nov 2007 18:38:09 -0500 

Testowany na OpenBSD (data zdecydowanie nie oparta na GNU) i wygląda na to, że działa.

Podział na etapy:

  • pobierz aktualny czas unixtime (sekundy od początku epoki unix):
 $ date +%s 1291679934 
  • pobierz liczbę sekund w 1125 dni
 $ echo "1125 * 24 * 60 *60" | bc 97200000 
  • odejmij jeden od drugiego (1291679934 – 97200000) = 1194478815

  • użyj nowego unixtime (1194478815), aby wydrukować ładną datę

     $ date -r 1194478689 Wed, 07 Nov 2007 18:38:09 -0500 
  • Alternatywnie na solaris możesz to zrobić, aby wydrukować datę *:

    /bin/echo "0t1194478815>Y\n<Y=Y" |adb

*, do którego odwołuje się http://www.sun.com/bigadmin/shellme/

Alternatywą w systemie Solaris do pobierania aktualnego znacznika czasu z polecenia daty ** jest:

/usr/bin/truss /usr/bin/date 2>&1 | nawk -F= "/^time()/ {gsub(/ /,"",$2);print $2}"

** odwołuje się do http://www.commandlinefu.com/commands/view/7647/unix-timestamp-solaris

Komentarze

  • Zwróć uwagę, że %s i date -r to BSDizmy (od samego początku, więc ' re na wszystkich platformach BSD). Nie ' nie spodziewaj się ich na platformach Systemu V (np. Solaris nie ma żadnego).
  • Ach, Solaris, jak bardzo cię kocham … (;
  • @Gilles: Jesteś pewien? Solaris ma wiele katalogów bin, takich jak / usr / ucb / bin, które zawierają wersje z innych odmian unixa, w końcu SunOS 4.X był oparty na BSD.
  • Nie udaje się to, gdy którykolwiek z dni pomiędzy nimi ma więcej lub mniej niż 60 * 60 * 24 sekund, na przykład sekundy przestępne i zmiany kalendarza.
  • @Sparr: Słuszna uwaga. podejście polega na odjęciu bieżącej godziny od bieżącej daty bezwzględnej i dodaniu 12 * 60 * 60. Zwraca to godzinę między 10:59 a 13:01. Dodając do tego okresy 24-godzinne i uzyskując odpowiednia data jest bezpieczna.

Odpowiedź

Poprzednia odpowiedź była zbyt skomplikowana. FreeBSD / macOS mają -v flaga dla date, ze strony MAN (skrócony opis):

Dostosuj (tj. weź aktualną datę i wyświetl wynik korekty; właściwie nie ustawia daty) sekunda, minuta, godzina, dzień miesiąca, dzień tygodnia, miesiąc lub rok zgodnie z val. Jeśli val jest poprzedzony znakiem plus lub minus, data jest korygowana do przodu lub do tyłu zgodnie z pozostałym ciągiem, w przeciwnym razie ustawiana jest odpowiednia część daty. Datę można zmieniać dowolną liczbę razy za pomocą tych flag. Flagi są przetwarzane w podanej kolejności.

Dlatego date -v1125d po prostu zrobi to, czego potrzebujesz

$ date; date -v-1125d Thu 19 Oct 2017 11:35:25 EDT Sat 20 Sep 2014 11:35:25 EDT 

Odpowiedź

Miałem podobny problem i znalazłem pakiet dateutils dla OpenBSD 6.4. To był dla mnie prosty dateutils pkg_add.

#!/bin/ksh # Using dateutils dadd (get current date) -1month -f (format to strftime) # Set Year in YYYY formant y is YY format lastMonth=$(dadd date -1mo -f "%Y.%m") echo $lastMonth mkdir /home/$usr/History/$lastMonth 

Moje wyjście to

#2018.11 

UPDATE 1

Uruchamiam to polecenie w dniu 2018.12.10

HostNameHere# dadd date -1125d -f "%Y.%m" 

Wynik

 2015.11 

Obsługuje dowolne dodawanie lub odejmowanie, które mogę stwierdzić. Oto polecenia pomagające wydrukować. #dadd -h (to nie jest całość wydruku. Jest więcej informacji o opcjach.

 Usage: dadd [OPTION]... [DATE/TIME] [DURATION] Add DURATION to DATE/TIME and print the result. If DATE/TIME is omitted but DURATION is given, read a list of DATE/TIMEs from stdin. If DURATION is omitted but DATE/TIME is given, read a list of DURATIONs from stdin. Durations are specified as nY, nMO, nW, or nD for years, months, weeks, or days respectively, or nH, nM, nS for hours, minutes, and seconds, where N is a (possibly negative) number. The unit symbols can be written lower-case as well (y, mo, w, d, h, m, s) and the unit symbol `d" can be omitted. Note that duration addition is not commutative! 2000-03-30 +1mo +1d -> 2000-05-01 2000-03-30 +1d +1mo -> 2000-04-30 

Tutaj są polecenia.

Tutaj są opcje formatowania.

Komentarze

  • (1) To ' fajnie, że ten program obsługuje -1mo. Czy możesz wykazać, że pozwala użytkownikowi obliczyć datę sprzed 1125 dni, zgodnie z pytaniem? (2) Pytanie brzmi: ” przy użyciu podstawy system operacyjny (np. No Perl lub Python). ” To wydaje się wykluczać dodanie nowego pakietu.
  • @ G-Man Dziękuję za komentarz. Jestem nowym uczestnikiem w StackExchange. Dziękuję za pomoc. Zobacz AKTUALIZACJĘ 1

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *