Los siguientes métodos hacen innecesario llamar date
dos 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
printf
osed
y también esecat
archivo "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 comodate
un 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
date
para 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
0
como 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 el1
es 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
dround
un argumento negativo:O para adherirse a su formato:
fuente
dateutils.dround '2018-11-12 13:55' -15m
produce .2018-11-12T13:15:00
2018-11-12T13:45:00
/-15m
es 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
date
comando 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
1
a0
) 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
busybox
podrí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
date
ybusybox date
superiores imprimirán las horas UTC. Elimine la-u
opció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