2012-10-31 11 views
30

Używam poniżej, aby uzyskać poprzedni, bieżący i następny miesiąc pod Ubuntu 11.04:Używając polecenia `dzień spełnienia wymogu, aby poprzedni, bieżący i następny miesiąc

LAST_MONTH=`date +'%m' -d 'last month'` 
NEXT_MONTH=`date +'%m' -d 'next month'` 
THIS_MONTH=`date +'%m' -d 'now'` 

To działa dobrze aż do dzisiaj, ostatniego dnia października 2012 (31.10.2012)

uzyskać wynik poniżej już teraz:

$ date 
Wed Oct 31 15:35:26 PDT 2012 
$ date +'%m' -d 'last month' 
10 
$ date +'%m' -d 'now' 
10 
$ $ date +'%m' -d 'next month' 
12 

Przypuszczam wyjścia powinna być 9, 10, 11 odpowiednio.

Nie rozumiem, dlaczego wyjścia wyjściowe zachowują się w ten sposób. Jaki powinien być dobry sposób, aby uzyskać stały miesiąc w postaci: previous, current i next?

+0

Nie możesz po prostu dostać miesiąca dla 'teraz', a następnie dodać lub odjąć 1? –

+0

Dzięki. Rozumiem, że to dzieło pod warunkiem, że zajmujesz się 'Dec + 1 = Jan' itp. Moje pytanie brzmi: dlaczego powyższe nie działa. – greeness

+0

Możesz uzyskać więcej informacji, drukując pełną datę obliczoną dla "ostatniego miesiąca" i "następnego miesiąca". Nie mam teraz terminalu uniksowego, ale domyślam się, że po prostu dodaje/odejmuje 30 dni do/od 'teraz'. –

Odpowiedz

70

Problem polega na tym, że date dosłownie przyjmuje Twoją prośbę i próbuje użyć daty 31 września (31 października minus jeden miesiąc), a następnie, ponieważ nie istnieje, przenosi się do następnego dnia, który to robi. Dokumentacja (od info date) date ma następującą radę:

fuzz w jednostkach może powodować problemy z względnych pozycji. Dla przykładu przykład "2003-07-31 -1 miesiąc" może być oceniony do 2003-07-01, ponieważ 2003-06-31 jest nieprawidłową datą. Aby niezawodnie ustalić poprzedni miesiąc, bardziej , możesz poprosić o miesiąc przed 15 bieżącym miesiąca. Na przykład:

$ date -R 
Thu, 31 Jul 2003 13:02:39 -0700 
$ date --date='-1 month' +'Last month was %B?' 
Last month was July? 
$ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!' 
Last month was June! 
+0

Dzięki! Bardzo pomocne! – greeness

+1

Nie przenosi się do następnego dnia, zajmuje liczbę dni w poprzednim miesiącu i odejmuje go od DoY, w oparciu o to, co widziałem. date --date = "03/31/2015 -1 miesiąc" + "Data:% m-% d-% Y" "Data: 03-03-2015". 3/31/2016 zwraca 3/2/2016. Sam byłem tylko miesiącem! Uwielbiam to rozwiązanie. – Iamiuru

+0

Uwaga: chciałem skorzystać z tego podejścia, ale utknąłem w BusyBox, który jest nieco mniej w pełni funkcjonalny i nie ma wbudowanej arytmetyki czasu. Ta nieco niedorzeczna modyfikacja zadziałała zamiast: 'date -d $ (data +% Y) - $ (($ (data +% m) - 1)) - 15 +% B'. I tak, działa to przez lata: całkiem dobrze jest zaakceptować zero (grudzień) i ujemne (liczenie wstecz) miesięcy. – Aesin

0

główny problem występuje, gdy nie masz data opcja --date dostępne i nie ma uprawnień, aby go zainstalować, a następnie spróbuj poniżej -

Previous month 
#cal -3|awk 'NR==1{print toupper(substr($1,1,3))"-"$2}' 
DEC-2016 
Current month 
#cal -3|awk 'NR==1{print toupper(substr($3,1,3))"-"$4}' 
JAN-2017 
Next month 
#cal -3|awk 'NR==1{print toupper(substr($5,1,3))"-"$6}' 
FEB-2017 
4

Jeśli zdarzy się przy użyciu datę w środowisku MacOS, spróbuj tego:

ST1:~ ejf$ date 
Mon Feb 20 21:55:48 CST 2017 
ST1:~ ejf$ date -v-1m +%m 
01 
ST1:~ ejf$ date -v+1m +%m 
03 

również wolałbym obliczyć poprzedni i następny miesiąc w pierwszym dniu każdego miesiąca, th jest tak, że nie będziesz mieć problemów z miesiącami kończącymi 30/31 lub 28/29 (luty/luty rok przestępny)

Powiązane problemy