look at my shell script

bbb=$(date -d "$aaa -5 minutes" +'%Y%m%d%H%M%S')

echo $bbb

i want to get:


but result is:


what happend?

How can I subtract 5 minutes from that aaa?

I want to see 20200101100510

  • My answer to your older question shows what happened. – muru Jan 21 at 5:26
  • Hi muru, thanks for the previous answer. But I don't know what to do in the above situation. Should I replace aaa with ISO-8601? – ohmg Jan 21 at 5:31
  • @muru please tell me how to parse that format as ISO-8601 – ohmg Jan 21 at 5:45
  • 1
    @ohmg. Rather than answer your Q, might I kindly suggest you think about HOW to break down the problem into smaller pieces. For example, first you can try this on the command line without the bbb=$(. Furthermore you can use echo to see what the parameter strings look like. Teaching you how to help yourself will be of more value to you than showing you the answer to any one problem I think. – Elliptical view Jan 21 at 5:48
  • If you can't change the input, you'll have to split it up: something like date -d "${aaa:0:4}-${aaa:4:2}-${aaa:6:2} ${aaa:8:2}:${aaa:10:2}:${aaa:12:2} +0 - 5 minutes" +%Y%m%d%H%M%S – muru Jan 21 at 5:54

You must be using the GNU implementation of date where that 20200101101010 is interpreted as 2020010110-10-10T00:00:00 local time.

-d is a non-standard option of date, supported by only a handful of implementations and on those where it's supported, if it is to input a date at all (like in GNU, busybox or ast-open's date; BSD date using -r and -v instead), it's done differently in different implementations.

ast-open and busybox date allow to specify the input format (busybox with -D, ast-open with -p) though not with an offset AFAIK. You could however remove the 5 minutes by converting first to epochtime, remove the 300 seconds and convert back to your format.

There was a proposal in July 2019 to add something similar to GNU date but it's not been released yet (as of 2020-01-21).

With GNU date specifically, you could convert the input ($aaa) first into a format it recognizes like in @RakeshShewale's ksh93 syntax approach.

Another option is to use the zsh shell which has the timestamp parsing and formatting feature built-in and avoid having to rely on non-portable behaviour of date:

zmodload zsh/datetime || exit
format=%Y%m%d%H%M%S min=60


strftime -r -s bbb -- "$format" "$aaa" || exit
strftime    -s bbb -- "$format" "$((bbb - 5 * min))"
print -r -- "$bbb"

You can adapt the $format as required for other formats but note that not all format directives supported by strftime() (called by strftime without -r to format timestamps) are supported by strptime() (called by strftime -r to parse timestamps). Check man 3 strftime and man 3 strptime on your system.

|improve this answer|||||
bbb=$(date --date "${a:0:4}-${a:4:2}-${a:6:2} ${a:8:2}:${a:10:2}:${a:12:2}")
ccc=$(date -d "$bbb -5 mins" +'%Y%m%d%H%M%S')
echo $ccc


|improve this answer|||||
  • 1
    That's ksh93 syntax though (also supported by bash/mksh/zsh/busybox ash), not sh syntax though. – Stéphane Chazelas Jan 21 at 6:44
  • 1
    Also using the default output format for $bbb is a bad idea as the timezone specification is ambiguous and it won't work properly in non-US-English locales. You should use a ISO-8601 type of format instead. – Stéphane Chazelas Jan 21 at 10:45

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.