Your particular problem is that the + 30
is interpreted as an invalid time zone.
You could fix that by working in UTC time (which would also avoid problems around DST changes) and use:
date -ud "$start_ts +0 + 30 minutes" +'%Y%m%d %T'
(note the +0 to specify a timezone with 0 offset to UTC so the next +30 minute
is interpreted as offset).
Or, to still work with local time, insert today
or now
after the timestamp, to make sure what follows is interpreted as offset:
date -d "$start_ts now + 30 minutes" +'%Y%m%d %T'
Though here, while you're at using GNU-specific extensions, you could do:
start_ts=$(date -ud '2021-08-07 15:00:00' +%s)
end_ts=$(date -ud '2021-08-11 05:00:00' +%s)
seq -f "@%.0f" "$start_ts" "$((30 * 60))" "$end_ts" |
date -uf - +'%Y%m%d %T'
To avoid running one date
per timestamp. Note that seq
is not a standard command, but as you have GNU date
, you'll also have GNU seq
which is part of the same GNU software bundle (coreutils
).
Or use the zsh shell which has builtin support for timestamp parsing and formatting which would avoid the dependency on GNU date
:
#! /bin/zsh -
zmodload zsh/datetime
format='%Y%m%d %T'
TZ=UTC0 strftime -rs start_ts $format '20210807 15:00:00'
TZ=UTC0 strftime -rs end_ts $format '20210811 05:00:00'
for ((t = start_ts; t <= end_ts; t += 30 * 60))
TZ=UTC0 strftime $format $t
Beware those may generate timestamps that don't correspond to any time in your timezone. For instance, in mainland UK here, there was no 2021-03-28 01:30:00
, because on that day we switched to summer time, so wallclock time jumped from 00:59:59.99 straight to 02:00:00.00. Conversely, on 2021-10-31, timestamps from 01:00:00 to 02:00:00 will occur twice. Still those codes above on that day, will iterate on 00:30:00, 01:00:00, 01:30:00, 02:00:00, 02:30:00 without going over the 01:00 -> 02:00 interval twice.
If that's not what you want, you should remove the parts that make it work with UTC time (the -u
, +0
and TZ=UTC0
), but then your format should include the timezone offset (%z
) to make the timestamps non-ambiguous (assuming you timezone offset is always a whole number of minutes which should be the case everywhere these days).