Validation de la date dans le shell

14

Je veux valider le format de date ci-dessous dans le script shell

2015-Jul-13

J'utilise date -d "2015-Jul-13" +"%Y-%b-%d"mais son erreur donne

date: invalid date '2015-Jul-13'
chhaya vishwakarma
la source
@Pandya: OP est clair sur sa question. OP veut valider (vérifier que la date entrée est valide ou non) le format de date mentionné mais il dit que la date entrée n'est pas valide.
Thushi
GNU datene reconnaît pas YYYY-MMM-DD. Pourriez-vous utiliser YYYY-MM-DDou à la DD MMM YYYYplace?
roaima
J'en suis presque sûr at, et - je pense - touchaussi. J'ai écrit une coquille de validation de la date funvtion basée sur touchune fois ... Non, non touch- il ne gère que des chiffres, mais atfait un peu l' analyse syntaxique assez profonde ...
mikeserv
@Thushi clarifions les commentaires redondants de notre part
Pandya
6
Lecture erronée du titre: la validation de la date est un enfer
Adam Davis

Réponses:

12

GNU datene prend pas en charge YYYY-MMM-DD. Cependant, il comprend DD-MMM-YYYY. Donc, si vous devez vraiment gérer les dates de ce format, vous pouvez le faire avec quelque chose comme ça, qui permute simplement les arguments autour d'un format qui dateattend:

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

Voici une solution entièrement shell. En le décomposant, les IFS=-instructions indiquent au shell de diviser une ligne de commande à venir par un trait d'union -au lieu d'un espace. Le set $ymdparse la $ymdvariable comme pour une ligne de commande, mais se divise maintenant par trait d'union, affectant des valeurs aux paramètres $1, $2 et suivants . Le echo "$3-$2-$1"sort trivialement les trois valeurs capturées dans l'ordre inverse.

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
la source
@mikeserv: Coolness! Cela a fonctionné avec: ymd=$(IFS=-;set $ymd; echo "$3-$2-$1") Pourriez-vous peut-être révéler la magie derrière la setcommande?
joepd
11

Depuis la page de manuel: -

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.

Mais il ne semble pas reconnaître le YYYY-MMM-DDformat. Ainsi, vous pouvez utiliser soit par le bas ou similaire comme:

$ 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

OU vous devez le convertir / reformater avant de l'envoyer àdate !

Voir également Comment spécifier un format pour l'entrée à ce jour?


Je recommande de visiter: les formats d'entrée de date .

Voici les règles.

Pour les mois numériques , le format ISO 8601 «année-mois-jour» est autorisé, où l'année est un nombre positif, le mois est un nombre compris entre 01 et 12 et le jour est un nombre compris entre 01 et 31. Un zéro non significatif doit être présent si un nombre est inférieur à dix. Si l'année est inférieure ou égale à 68, alors 2000 y est ajoutée; sinon, si l'année est inférieure à 100, 1900 y est ajouté. La construction «mois / jour / année», populaire aux États-Unis, est acceptée. Aussi «mois / jour», en omettant l'année.

Les mois littéraux peuvent être précisés en entier: «janvier», «février», «mars», «avril», «mai», «juin», «juillet», «août», «septembre», «octobre», « Novembre 'ou' décembre '. Les mois littéraux peuvent être abrégés en leurs trois premières lettres, éventuellement suivies d'un point abrégé. Il est également permis d'écrire «Sept» au lieu de «Septembre».

Lorsque les mois sont écrits littéralement , la date du calendrier peut être indiquée comme suit:

 jour mois année
 jour mois
 mois jour année
 jour-mois-année

souligné par moi

Ici, vous pouvez voir qu'il n'y a pas de format comme l' année-mois-jour ! (pendant des mois sont écrits littéralement)

Pandya
la source
7

Avec zshvous pouvez utiliser la fonction strftimeintégrée (disponible via zsh/datetime) avec -r(inverser):

strftime -r format d'horodatage

qui utilise le format pour analyser l' horodatage et afficher le nombre de secondes depuis l'époque:

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

Cela entraîne une erreur si la date n'est pas valide:

strftime -r %Y-%b-%d 2015-Jul-33
zsh: strftime: 5: format non adapté

Vous pouvez également convertir les secondes depuis l'époque en tout autre format de date standard / personnalisé, par exemple

strftime '%A, %B %d, %Y' 1447970400
Vendredi 20 novembre 2015
don_crissti
la source