Sprawdzanie poprawności daty w powłoce

14

Chcę sprawdzić poprawność poniższego formatu daty w skrypcie powłoki

2015-Jul-13

Używam, date -d "2015-Jul-13" +"%Y-%b-%d"ale daje błąd jako

date: invalid date '2015-Jul-13'
chhaya vishwakarma
źródło
@Pandya: OP ma jasność co do swojego pytania. OP chce zweryfikować (sprawdzić, czy wprowadzona data jest poprawna, czy nie) wspomniany format daty, ale mówi, że wprowadzona data jest nieprawidłowa.
Thushi,
GNU datenie rozpoznaje YYYY-MMM-DD. Czy możesz użyć YYYY-MM-DDlub DD MMM YYYYzamiast tego?
roaima
Jestem pewien at, że tak, i - tak myślę - touchrównież. Napisałem funkcję powłoki sprawdzania poprawności daty opartą na touchraz ... nie, nie touch- obsługuje tylko cyfry, ale atwykonuje dość głęboką analizę ...
mikeserv
@Thushi usuńmy przez nas zbędny komentarz
Pandya
6
Źle odczytany tytuł: Walidacja daty to piekło
Adam Davis,

Odpowiedzi:

12

GNU datenie obsługuje YYYY-MMM-DD. Jednak to rozumie DD-MMM-YYYY. Więc jeśli naprawdę musisz poradzić sobie z datami tego formatu, możesz to zrobić za pomocą czegoś takiego, co po prostu zamienia argumenty na format, który dateoczekuje:

ymd='2015-Jul-13'

dmy=$(echo "$ymd" | awk -F- '{ OFS=FS; print $3,$2,$1 }')
if date --date "$dmy" >/dev/null 2>&1
then
    echo OK
fi

Oto rozwiązanie dla wszystkich powłok. Po rozbiciu IFS=-instrukcji instruuje powłokę, by podzieliła nadchodzącą linię poleceń łącznikiem -zamiast białych znaków. set $ymdAnalizuje $ymdzmiennej za pomocą linii poleceń, ale rozdziela się przez łącznik, przypisując wartości parametrów $1, $2 i nast . echo "$3-$2-$1"Trywialny wyjścia trzech wykonanych wartości w odwrotnej kolejności.

ymd='2015-Jul-13'

dmy=$(IFS=-; set $ymd; echo "$3-$2-$1")
if date --date "$dmy" >/dev/null 2>&1
then
    echo OK
fi
roaima
źródło
@mikeserv: Coolness! Działa z: ymd=$(IFS=-;set $ymd; echo "$3-$2-$1") Czy możesz odkryć magię stojącą za tym setpoleceniem?
joepd
11

Z strony podręcznika: -

DATE STRING
       The --date=STRING is a mostly free format human readable date string such as "Sun, 29 Feb 2004 16:21:42 -0800"
       or  "2004-02-29  16:21:42" or even "next Thursday".  A date string may contain items indicating calendar date,
       time of day, time zone, day of week, relative time, relative date, and numbers.  An empty string indicates the
       beginning  of  the  day.   The  date string format is more complex than is easily documented here but is fully
       described in the info documentation.

Ale wydaje się, że nie rozpoznaje YYYY-MMM-DDformatu. Możesz więc użyć albo od dołu, albo w podobny sposób:

$ date -d "2015-07-13" +"%Y-%b-%d"
2015-Jul-13
$ date -d "Jul 13 2015" +"%Y-%b-%d"
2015-Jul-13
$ date -d "13 Jul 2015" +"%Y-%b-%d"
2015-Jul-13

LUB musisz przekonwertować / sformatować go przed wysłaniem dodate !

Zobacz także Jak określić format danych wejściowych do tej pory?


Polecam odwiedzić: Formaty wprowadzania daty .

Oto zasady.

W przypadku miesięcy numerycznych dozwolony jest format ISO 8601 „rok-miesiąc-dzień”, gdzie rok jest dowolną liczbą dodatnią, miesiąc jest liczbą od 01 do 12, a dzień jest liczbą od 01 do 31. Zero wiodące musi być obecne jeśli liczba jest mniejsza niż dziesięć. Jeśli rok ma 68 lat lub mniej, wówczas dodaje się do niego 2000; w przeciwnym razie, jeśli rok jest krótszy niż 100, wówczas dodaje się do niego 1900. Popularny w Stanach Zjednoczonych konstrukt „miesiąc / dzień / rok” jest akceptowany. Również „miesiąc / dzień” z pominięciem roku.

Dosłowne miesiące można wyrazić w całości: „styczeń”, „luty”, „marzec”, „kwiecień”, „maj”, „czerwiec”, „lipiec”, „sierpień”, „wrzesień”, „październik”, „ Listopad ”lub„ grudzień ”. Dosłowne miesiące mogą być skracane do pierwszych trzech liter, po których może następować kropka skracająca. Dozwolone jest również pisanie „Sept” zamiast „September”.

Gdy miesiące są pisane dosłownie , datę kalendarzową można podać jako jedną z następujących czynności:

 dzień miesiąc rok
 dzień miesiąc
 miesiąc dzień rok
 dzień-miesiąc-rok

podkreślone przeze mnie

Tutaj możesz zobaczyć, że nie ma takiego formatu jak rok-miesiąc-dzień ! (od miesięcy są pisane dosłownie)

Pandya
źródło
7

Z zshmożna wykorzystać strftimepolecenie wbudowane (dostępne za pośrednictwem zsh/datetime) z -r(reverse):

strftime -r formatowanie czasu

który używa formatu do parsowania timestringu i wyświetla liczbę sekund od epoki:

zmodload zsh/datetime
strftime -r %Y-%b-%d 2015-Jul-13
1436734800

Błąd ten pojawia się, jeśli data jest nieprawidłowa:

strftime -r %Y-%b-%d 2015-Jul-33
zsh: strftime: 5: format niezgodny

Możesz także przekonwertować sekundy od epoki na dowolny inny standardowy / niestandardowy format daty, np

strftime '%A, %B %d, %Y' 1447970400
Piątek, 20 listopada 2015 r
don_crissti
źródło