Validación de fecha en shell

14

Quiero validar el siguiente formato de fecha en el script de shell

2015-Jul-13

Estoy usando date -d "2015-Jul-13" +"%Y-%b-%d"pero está dando error como

date: invalid date '2015-Jul-13'
chhaya vishwakarma
fuente
@Pandya: OP es claro acerca de su pregunta. OP quiere validar (verificar que la fecha ingresada sea válida o no) el formato de fecha mencionado pero indica que la fecha ingresada no es válida.
Thushi
GNU dateno reconoce YYYY-MMM-DD. ¿Podrías usar YYYY-MM-DDo en su DD MMM YYYYlugar?
roaima
Estoy bastante seguro de que atsí, y creo touchque también. Escribí un funvtion fecha de cáscara de validación basado en touchuna vez ... No, no touch- que sólo se ocupa de los números, pero athace algunos análisis muy profundo ...
mikeserv
@Thushi aclaremos el comentario redundante de nosotros
Pandya
66
Leyó mal el título: La validación de la fecha es un infierno
Adam Davis

Respuestas:

12

GNU dateno es compatible YYYY-MMM-DD. Sin embargo, lo entiende DD-MMM-YYYY. Entonces, si realmente tiene que manejar las fechas de este formato, puede hacerlo con algo como esto, que simplemente intercambia los argumentos a un formato que dateespera:

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

Aquí hay una solución completa. Desglosándolo, las IFS=-instrucciones le dicen al shell que divida una línea de comando próxima por guión en -lugar de espacios en blanco. El set $ymdanálisis sintáctico de la $ymdvariable como una línea de comandos, pero ahora se divide por el guión, la asignación de valores a los parámetros $1, $2 y siguientes . El echo "$3-$2-$1"trivial muestra los tres valores capturados en orden inverso.

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
fuente
@mikeserv: ¡Genial! Funcionó con: ymd=$(IFS=-;set $ymd; echo "$3-$2-$1") ¿Podrías revelar la magia detrás del setcomando?
joepd
11

Desde la página de manual: -

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.

Pero parece no reconocer el YYYY-MMM-DDformato. Por lo tanto, puede usar desde abajo o similar como:

$ 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

¡O tiene que convertirlo / formatearlo antes de enviarlo date!

Consulte también ¿Cómo se especifica un formato para la entrada hasta la fecha?


Recomiendo visitar: formatos de entrada de fecha .

Estas son las reglas.

Para los meses numéricos , se permite el formato ISO 8601 'año-mes-día', donde el año es cualquier número positivo, el mes es un número entre 01 y 12 y el día es un número entre 01 y 31. Debe haber un cero inicial si un número es menor que diez. Si el año es 68 o menor, entonces se le agrega 2000; de lo contrario, si el año es inferior a 100, se le agrega 1900. Se acepta el constructo 'mes / día / año', popular en los Estados Unidos. También 'mes / día', omitiendo el año.

Los meses literales se pueden detallar en su totalidad: 'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', ' Noviembre 'o' diciembre '. Los meses literales se pueden abreviar a sus primeras tres letras, posiblemente seguidas de un punto abreviado. También está permitido escribir 'Sept' en lugar de 'Septiembre'.

Cuando los meses se escriben literalmente , la fecha del calendario se puede dar de la siguiente manera:

 día mes año
 día mes
 mes día año
 día-mes-año

enfatizado por mí

¡Aquí puedes ver que no hay formato como año-mes-día ! (durante meses se escriben literalmente)

Pandya
fuente
7

Con zshusted podría usar el strftimebuiltin (disponible a través de zsh/datetime) con -r(reverso):

strftime -r formato timetring

que usa el formato para analizar la cadena de tiempo y generar el número de segundos desde la época:

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

Esto elimina el error si la fecha no es válida:

strftime -r %Y-%b-%d 2015-Jul-33
zsh: strftime: 5: el formato no coincide

También puede convertir los segundos desde época a cualquier otro formato de fecha estándar / personalizado, por ejemplo

strftime '%A, %B %d, %Y' 1447970400
Viernes 20 de noviembre de 2015
don_crissti
fuente