2

I am trying to construct a daily 6-hourly date series for some 'N' number of years. I tried to do like this

for i in {1..1825}; do 
date -d "00:00 01-01-1998 +6 hours" +"%d-%m-%Y %H:%M"
done

But this is not what I wanted.

My goal is to create like this in order;

01-01-1998 00:00 
01-01-1998 06:00 
01-01-1998 12:00 
01-01-1998 18:00 
02-01-1998 00:00 
02-01-1998 06:00
02-01-1998 12:00 
02-01-1998 18:00 
.
.
.etc

How can I do this using the date command?

Any help is highly appreciated. Thanks in advance.

2
  • Maybe save the output of date in a variable in a format that can be parsed by date and use the old value to do the calculation for the next value.
    – Bodo
    Sep 8, 2020 at 11:23
  • Thank you for making this as the answer. Sep 9, 2020 at 5:56

3 Answers 3

1

You have to worry about daylight saving time. For example, my time zone is Canada/Eastern, and:

$ d=$(date -d "2020-03-08 00:00:00")
$ echo $d
Sun Mar 8 00:00:00 EST 2020
$ d=$(date -d "$d + 6 hours")
$ echo $d
Sun Mar 8 07:00:00 EDT 2020
# ........^^

and

$ d=$(date -d "2020-11-01 00:00:00")
$ echo $d
Sun Nov 1 00:00:00 EDT 2020
$ d=$(date -d "$d + 6 hours")
$ echo $d
Sun Nov 1 05:00:00 EST 2020
# ........^^

Make sure you specify UTC for the time zone.

$ d=$(date -u -d "2020-11-01 00:00:00")
$ echo $d
Sun Nov 1 00:00:00 UTC 2020
$ d=$(date -u -d "$d + 6 hours")
$ echo $d
Sun Nov 1 06:00:00 UTC 2020
# ........^^

So:

fmt='%d-%m-%Y %H:%M'
d=$(date -u -d "1998-01-01 00:00:00")
for i in {1..1825}; do 
    # print the current date
    date -u -d "$d" "+$fmt"
    # add 6 hours
    d=$(date -u -d "$d + 6 hours")
done

I would strongly recommend you use the ISO date format YYYY-mm-dd: that is an unambiguous date format, and it sorts the same lexically and chronologically.

1
  • Many thanks for your answer. I did work perfectly. Unfortunately, I can only accept one answer. I appreciate your suggestion on the ISO date format. But my purpose is different and want my dates strictly in dd-mm-yyyy format! Sep 9, 2020 at 6:08
0

You can save the date of every calculation in a variable and use it to calculate the next date. I use the default format in standard locale for storing the date because date cannot parse your specified format.

# start date
d=$(LC_ALL=C date -d "1998-01-01 00:00")
echo "# d=$d"
# convert format
date -d "$d" +"%d-%m-%Y %H:%M"

for i in {1..1825}; do 
    # add 6 hours
    d=$(LC_ALL=C date -d "$d +6 hours")
    # convert format
    date -d "$d" +"%d-%m-%Y %H:%M"
done

This prints

# d=Thu Jan  1 00:00:00 CET 1998
01-01-1998 00:00
01-01-1998 06:00
01-01-1998 12:00
01-01-1998 18:00
02-01-1998 00:00
02-01-1998 06:00
02-01-1998 12:00
02-01-1998 18:00
03-01-1998 00:00
03-01-1998 06:00
03-01-1998 12:00
03-01-1998 18:00
04-01-1998 00:00
04-01-1998 06:00
...

The results depend on your time zone and daylight saving time rules.

Your starting time specification may be ambiguous because it doesn't specify the time zone.

Edit based on Paul_Pedant's comment:

Make an outer loop for + $i days, and an inner loop hard-coded 00, 06, 12, 18. It runs a quarter as many date processes, and it does not care about DST variations.

# start date
d=$(LC_ALL=C date -d "1998-01-01 00:00")
echo "# d=$d"

for i in {1..456}; do 
    # convert (partial) format
    out=$(date -d "$d" +"%d-%m-%Y")
    for h in 00 06 12 18; do
        echo "$out $h:00"
    done
    # add 1 day
    d=$(LC_ALL=C date -d "$d +1 day")
done

Please specify in the question what result you expect when switching between normal time and daylight saving time occurs. (strictly printing 00:00, 06:00, 12:00, 18:00 or exactly 6 hours time difference when switching DST)

Edit based on glenn jackman's answer

Adding option -u to all date calls will make the script nearly the same as written by glenn jackman and result in strictly printing 00:00, 06:00, 12:00, 18:00 regardless of DST.

6
  • Make an outer loop for + $i days, and an inner loop hard-coded 00, 06, 12, 18. It runs a quarter as many date processes, and it does not care about DST variations. Sep 8, 2020 at 21:57
  • Thank you for the updation. Worked perfectly! My time zone is IST India. So I think DST is not a concern. Please enlighten me if I am wrong! Sep 9, 2020 at 6:02
  • @linux_lover I had to read about DST in India. You are lucky not to have this "daylight saving".
    – Bodo
    Sep 9, 2020 at 6:25
  • @Bodo Thanks for that. I can't tell that 'not having a DST' is a good thing from another perspective. Sometimes when I travel across the country I feel India needs DST! Anyway, that's not our topic here to discuss! :) Sep 9, 2020 at 7:38
  • @linux_lover Regardless of the general discussion of pros/cons of DST, in your technical use case you are lucky because you will get both strict 00, 06, 12, 18 clock hours and exact 6h time intervals with the same script which is not possible with DST.
    – Bodo
    Sep 9, 2020 at 8:18
0

With GNU date you can add an ever-increasing number of hours to your starting point

start="$(date +'%Y-%m-%d')"
for i in {0..1825}
do
    date --date "$start +$((i*6)) hours" +'%d-%m-%Y %H:%M'
done

The six hour interval remains constant but as a result in my locale (UK timezone) the actual times shift as a consequence of the switch between summer time and winter time.

24-10-2020 00:00
24-10-2020 06:00
24-10-2020 12:00
24-10-2020 18:00
25-10-2020 00:00
25-10-2020 05:00    ← Six hours on from midnight because the clock goes back one hour at 03:00
25-10-2020 11:00
25-10-2020 17:00
25-10-2020 23:00

It's not specified in your question whether you want the intervals to be at midnight, 6am, noon and 6pm regardless of any possible switch between summer/winter time, or you want the intervals to be fixed at precise six hour intervals.

Use date --utc instead of just date to guarantee generating a series of datetimes that appear to be six hours apart without regard to the timezone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.