El comando Bash calcula el tiempo incorrecto

Resuelto Xu Shan asked hace 10 meses • 1 respuestas

Estoy usando un script bash y quiero hacer un bucle de tiempo desde hace 3 horas hasta 3 horas después. Por ejemplo, los pseudocódigos son los siguientes:

time_end = 2000010100              #YYYYMMDDHH
time_beg = 1996010100              #YYYYMMDDHH
for time_beg -le time_end          # while time_beg<=time_end
    time_tmp = time_beg + 3 hours
    do some calculation from time_beg to time_tmp
    time_beg = time_tmp
end for

Y la pieza do some calculation from time_beg to time_tmpes un modelo para simular algo de 1996-01-01-00a 1996-01-01-03(por ejemplo). Luego, la siguiente ejecución comenzaría desde 1996-01-01-03hasta 1996-01-01-06.

Para hacer la parte de time_tmp = time_beg + 3 hours, utilizo los siguientes códigos:

YMDH=$YYYYMMDDHH
time_resolution=3
INC=+${time_resolution}hours
YMDH_newend=`date +%Y%m%d%H -d "${YMDH::8} ${YMDH:8:2} ${INC}"`
echo ${YMDH_newend}

Probé que funcionó bien pero recibí un error cuando $YYYYMMDDHH=1996033101. La ejecución de los códigos anteriores produce resultados $YYYYMMDDHH=1996033105incorrectos y debería ser $YYYYMMDDHH=1996033104...

¿Entonces qué pasó? ¿O hay alguna forma más inteligente de hacer esto? ¿Te gusta usar Python? algo como $(python -c "print(blablabla about YYYYMMDDHH)")?

¡Gracias!

Xu Shan avatar Feb 16 '24 17:02 Xu Shan
Aceptado

El problema que estás encontrando probablemente se deba al horario de verano. El 31 de marzo de 1996, muchos países adelantaron sus relojes una hora a la 1:00 a. m., saltándose efectivamente la hora de las 2:00 a. m. a las 3:00 a. m. Es por eso que cuando agregas 3 horas a la 1:00 a. m., terminas a las 5:00 a. m. en lugar de a las 4:00 a. m.

Si desea evitar este problema, puede utilizar la hora UTC, que no respeta el horario de verano. Puede especificar la hora UTC en el comando de fecha agregando una Z a la cadena de hora:

YMDH=$YYYYMMDDHH
time_resolution=3
INC=+${time_resolution}hours
YMDH_newend=`date -u +%Y%m%d%H -d "${YMDH::8}T${YMDH:8:2}Z ${INC}"`
echo ${YMDH_newend}

Tenga en cuenta la opción -u en el comando de fecha, que le indica que use la hora UTC, y la T y la Z en la cadena de fecha, que especifican la hora en formato ISO 8601 en UTC.

Alternativamente, puede usar Python para realizar la aritmética de fechas, lo que puede manejar estos casos extremos con mayor elegancia:

YMDH=$YYYYMMDDHH
time_resolution=3
YMDH_newend=$(python -c "from datetime import datetime, timedelta; dt = datetime.strptime('$YMDH', '%Y%m%d%H'); dt += timedelta(hours=$time_resolution); print(dt.strftime('%Y%m%d%H'))")
echo ${YMDH_newend}

Este script de Python analiza la cadena de fecha en un objeto de fecha y hora, le agrega la cantidad especificada de horas y luego la formatea nuevamente en una cadena.

msalam avatar Feb 16 '2024 10:02 msalam