Uzyskaj datę (dzień przed bieżącą godziną) w Bash


171

Jak mogę wydrukować datę, która jest dzień przed bieżącą godziną w Bash?


Data
próby,

Znalazłem inne świetne rozwiązanie, instalując datę gnu (pakiet coreutil) z sunfreeware.
conandor

ani też nie ma przełącznika -d w dacie AIX
frankster

Opcja --datelub -djest dostępna tylko w dniu GNU
Chris FA Johnson

Zobacz stackoverflow.com/q/15374752/462865, aby uzyskać wersję tego pytania bezpieczną dla DST.
Amir Ali Akbari

Odpowiedzi:


262

jeśli masz datę GNU i dobrze cię zrozumiałem

$ date +%Y:%m:%d -d "yesterday"
2009:11:09

lub

$ date +%Y:%m:%d -d "1 day ago"
2009:11:09

1
Okazało się, że większość jest
zgodna z

3
Do użytku w systemie Ubuntu z funkcją daty: $ (data +% Y:% m:% d -d "1 dzień temu"), wynik to: 2013: 04: 21. A jeśli chcesz mieć datę 10 dni wcześniej, możesz użyć $ (data +% Y:% m:% d -d "10 dni temu") lub $ (data +% Y:% m:% d -d "10 dzień temu ”)
zhihong

Na OS X możesz zainstalować coreutils przez brew: patrz stackoverflow.com/questions/15374752/ ...
kasterma

11
date -v-1dna OSX (minus), -v+1d(plus)
bgs

2
Ta funkcja bash będzie działać zarówno w systemie Linux, jak i OSX. Zasadniczo najpierw próbuje stylu GNU Linux. Jeśli to się nie powiedzie, spróbuje stylu OSX. Nazwij to z argumentem liczby dni w przeszłości, w których chcesz ustawić datę. Jeśli nie podasz żadnego argumentu, przyjmiemy 0 dni. Ten kod jest jednolinijkowy, więc wycinanie i wklejanie powinno działać - nie zakłada się zakończenia linii. date_days_past () { days_past=${1:-0}; if ! date -v-${days_past}d +%Y%m%d 2>/dev/null; then date --date="-${days_past} day" +%Y%m%d; fi }
Noah Spurrier

50

Jeśli masz BSD (OSX) date, możesz to zrobić w ten sposób:

date -j -v-1d
Wed Dec 14 15:34:14 CET 2011

Lub jeśli chcesz wykonać obliczenia daty w dowolnym dniu:

date -j -v-1d -f "%Y-%m-%d" "2011-09-01" "+%Y-%m-%d"
2011-08-31

41
date --date='-1 day'

4
Błędy w systemie macOS Sierra:date: illegal option -- -
kuanb

2
Musisz zainstalować wersję GNU date, dostępną w coreutilspakiecie, aby ta składnia działała w systemie macOS. Jeśli używasz Homebrew, możesz go zainstalować przez brew install coreutils, po czym powinieneś być w stanie użyć daty GNU za pomocą gdatepolecenia. Zobacz: topbug.net/blog/2013/04/14/…
sumitsu


7

Cóż, to późna odpowiedź, ale wydaje się, że działa !!

     YESTERDAY=`TZ=GMT+24 date +%d-%m-%Y`;
     echo $YESTERDAY;


4

Przepraszam, że nie wspominam o mnie w systemie Solaris. W związku z tym przełącznik -date nie jest dostępny w systemie Solaris bash.

Dowiedziałem się, że mogę uzyskać poprzednią datę za pomocą małej sztuczki w strefie czasowej.

DATE=`TZ=MYT+16 date +%Y-%m-%d_%r`
echo $DATE

Ta metoda nie jest w 100% niezawodna (około 98%), jeśli mieszkasz w miejscu, w którym obowiązuje czas letni.
jlliagre

Niezupełnie, możesz użyć bash $(TZ=America/New_York date +%Y-%m-%d)
phray2002

3

Może zamiast tego użyć Perla?

perl -e 'print scalar localtime( time - 86400 ) . "\n";'

Lub użyj nawk i (ab) użyj / usr / bin / adb:

nawk 'BEGIN{printf "0t%d=Y\n", srand()-86400}' | adb

Przeszedłem też przez to ... szaleństwo!

/usr/bin/truss /usr/bin/date 2>&1 | nawk -F= '/^time\(\)/ {gsub(/ /,"",$2);printf "0t%d=Y\n", $2-86400}' | adb


1
yesterday=`date -d "-1 day" %F`

Wstawia wczorajszą datę w formacie RRRR-MM-DD do zmiennej $yesterday.


1
#!/bin/bash
OFFSET=1;
eval `date "+day=%d; month=%m; year=%Y"`
# Subtract offset from day, if it goes below one use 'cal'
# to determine the number of days in the previous month.
day=`expr $day - $OFFSET`
if [ $day -le 0 ] ;then
month=`expr $month - 1`
if [ $month -eq 0 ] ;then
year=`expr $year - 1`
month=12
fi
set `cal $month $year`
xday=${$#}
day=`expr $xday + $day`
fi
echo $year-$month-$day

+1 za korektę, ciekawa metoda, chociaż jest trochę rozwlekła.
Peter Lindqvist

1
Cześć medoix, nie jestem w stanie znaleźć znaczenia $ {$ #}. Wiem, że $ # oznacza liczbę argumentów skryptu / funkcji. Ale nie mogę się do tego odnieść. Proszę pomóż.
Karthick S

To nie działa dla poprzedniego dnia przy zmianie miesiąca. Na przykład dzisiejszy 1 July , 2013wynik to wydrukowany wynik 2013-6-1347, podczas gdy oczekiwany wynik to2013-6-30
błędny.

Zamiast 3 linii między „fi” try „day = echo $(cal $month $year)|tr ' ' '\n'|tail -n 1
Anton Roslov

1

Możesz wykonać proste obliczenia, uzupełnione wyrażeniem regularnym, jeśli wybrany format daty to „RRRRMM”:

echo $(($(date +"%Y%m") - 1)) | sed -e 's/99$/12/'

W styczniu 2020 zwróci 201912 ;-) Ale to tylko obejście, gdy data nie ma opcji obliczeniowych, a inne opcje interpretatora daty (np. Przy użyciu perla) nie są dostępne ;-)



0

Wypróbuj poniższy kod, który zajmie się również częścią DST.

if [ $(date +%w) -eq $(date -u +%w) ]; then
  tz=$(( 10#$gmthour - 10#$localhour ))
else
  tz=$(( 24 - 10#$gmthour + 10#$localhour ))
fi
echo $tz
myTime=`TZ=GMT+$tz date +'%Y%m%d'`

Courtsey Ansgar Wiechers


0

Rozwiązanie uwzględniające czas letni:

Manipulowanie strefą czasową jest możliwe w celu zmiany zegara o kilka godzin. Ze względu na czas letni, 24 godziny temu może być dzisiaj lub przedwczoraj.

Jesteś pewien, że wczoraj było 20 lub 30 godzin temu. Który? Cóż, najnowszy, którego nie ma dzisiaj.

echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

Parametr -e użyty w poleceniu echo jest potrzebny w bash, ale nie będzie działał z ksh. W ksh możesz użyć tego samego polecenia bez flagi -e.

Gdy twój skrypt będzie używany w różnych środowiskach, możesz uruchomić skrypt za pomocą #! / Bin / ksh lub #! / Bin / bash. Możesz także zastąpić \ n nową linią:

echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1

0

Niezbyt seksowne, ale może wystarczyć:

perl -e 'my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time - 86400);$year += 1900; $mon+= 1; printf ("YESTERDAY: %04d%02d%02d \n", $year, $mon, $mday)'

Utworzone na podstawie odpowiedzi „Martin Clayton”.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.