Los siguientes métodos hacen innecesario llamar datedos veces.
La sobrecarga de una llamada del sistema puede hacer que un comando "simple" sea 100 veces más lento que bash haciendo lo mismo en su propio entorno local.
ACTUALIZACIÓN Solo una mención rápida sobre mi comentario anterior: "100 veces más lento". Ahora puede leer " 500 veces más lento" ... Recientemente caí (no, caminé a ciegas) en este mismo problema. aquí está el enlace: forma rápida de crear un archivo de prueba
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
o
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M
Ambas versiones solo devolverán
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
Aquí está el primero con un bucle TEST para los 60 valores {00..59}
for X in {00..59} ; ###### TEST
do ###### TEST
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
M=$X ###### TEST
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
done ###### TEST
printfosedy también esecatarchivo "innecesario" vs <hace una gran diferencia real en el tiempo de ejecución. al hacer un bucle, como en mi ejemplo "500 veces más lento". Parece que usar el shell siempre que sea posible y permitir que un programa comodateun proceso por lotes sea lo que quiero decir ... por ejemplo. Ejemplo de Gilles 'Left-Pad-0, vs printfAquí hay una manera de trabajar en fechas en el shell. Primera llamada
datepara obtener los componentes, y llenar los parámetros posicionales ($1,$2, etc.) con los componentes (nota que este es uno de esos casos raros en los que usted desee utilizar$(…)fuera de las comillas dobles, para romper la cadena en palabras). Luego realice aritmética, pruebas o lo que sea que necesite hacer en los componentes. Finalmente ensamblar los componentes.La parte aritmética puede ser un poco complicada porque las conchas se tratan
0como un prefijo octal; por ejemplo, aquí$(($5/15))fallarían a las 8 o 9 minutos después de la hora. Como hay a lo sumo un líder0,${5#0}es seguro para la aritmética. Agregar 100 y luego quitar el1es una forma de obtener un número fijo de dígitos en la salida.fuente
Tal vez ya no importa, pero puedes probar mis propias dateutils . El redondeo (hacia abajo) a minutos se realiza con
droundun argumento negativo:O para adherirse a su formato:
fuente
dateutils.dround '2018-11-12 13:55' -15mproduce .2018-11-12T13:15:002018-11-12T13:45:00/-15mes decir, redondear al siguiente múltiplo de 15 minutos en la hora. Esta característica tiene la sintaxis más engorrosa porque acepta menos valores, / -13m no es posible, por ejemplo, porque 13 no es un divisor de 60 (minutos en la hora)dateutils.dround '2018-11-12 12:52:31' /450s /-15m, ¡gracias!Algunos shells pueden hacer el trabajo sin llamar a un
datecomando externo :ksh
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"bash
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"zsh
zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))Los tres anteriores proporcionan la hora local (no UTC). Use una TZ = UTC0 inicial si es necesario.
La sintaxis de ksh y bash es casi idéntica (excepto la requerida
#en ksh). El zsh requiere cargar un módulo (incluido con la distribución zsh).También es posible hacerlo con (GNU) awk:
papar moscas
awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'Esto proporciona un resultado UTC (cambie el último
1a0) si se necesita local. Pero cargar un awk externo o un módulo zsh externo puede ser tan lento como llamar a la fecha:gnu-date
a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'Un pequeño ejecutable como
busyboxpodría proporcionar resultados similares:busybox-date
a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'Tenga en cuenta que la palabra principal de busybox puede omitirse si busybox está vinculado a esos nombres en un directorio de la RUTA.
Ambos
dateybusybox datesuperiores imprimirán las horas UTC. Elimine la-uopción para horas locales.Si su sistema operativo tiene una versión de fecha más limitada (y eso es lo que debe usar), intente:
O, si está en FreeBSD, intente:
fuente
Si puede vivir con la fecha de llamada dos veces, esta funciona en bash en Solaris:
Editado en nombre del comentario para:
fuente
No estoy seguro acerca de su requerimiento exacto. Sin embargo, si desea generar el tiempo después de 15 minutos, puede usar algo como
date -d '+15 min'. La salida se muestra a continuación:fuente