Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Bash command calculates wrong time

I am using bash script and want to do a for loop of time from 3 hours ago to 3 hours later. For example, the pseudo codes follow:

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

And the part do some calculation from time_beg to time_tmp is a model to simulate something from 1996-01-01-00 to 1996-01-01-03 (for example). Then next run would start from 1996-01-01-03 to 1996-01-01-06.

To do the part of time_tmp = time_beg + 3 hours, I use following codes:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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}

I tested it worked well but got an error when $YYYYMMDDHH=1996033101. Running the codes above yield results of $YYYYMMDDHH=1996033105 which is wrong and should be $YYYYMMDDHH=1996033104

So what happened? or is there any smarter way to do this? like using python? something like $(python -c "print(blablabla about YYYYMMDDHH)")?

Thanks!

>Solution :

The issue you’re encountering is likely due to Daylight Saving Time. On March 31, 1996, many countries moved their clocks forward one hour at 1:00 AM, effectively skipping the hour from 2:00 AM to 3:00 AM. This is why when you add 3 hours to 1:00 AM, you end up at 5:00 AM instead of 4:00 AM.

If you want to avoid this issue, you can use UTC time, which does not observe Daylight Saving Time. You can specify UTC time in the date command by appending a Z to the time string:

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}

Note the -u option in the date command, which tells it to use UTC time, and the T and Z in the date string, which specify the time in ISO 8601 format in UTC.

Alternatively, you can use Python to do the date arithmetic, which can handle these edge cases more gracefully:

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}

This Python script parses the date string into a datetime object, adds the specified number of hours to it, and then formats it back into a string.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading