1

How can I validate that my datetime string has a valid ISO-8601 format with timezone (+0200) through a bash script?

The acceptable format is only %Y-%m-%dT%H:%M:%S+0200.

EDIT: I'm fine with having the year as 0001, 9999 or any random permutation of 4 digits. I just need to enforce the syntactical check.

Masquerade
  • 3,580
  • 5
  • 20
  • 37

3 Answers3

4

Here's a simple bash script which tests the given parameter against a regex for an extended (not basic/shortened) ISO-8601 format which, following the question, requires all the fields to be present:

#!/bin/bash

if [[ $1 =~ ^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T?[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}([\.,][[:digit:]]+)?\+0200$ ]]
then
  echo correct format
else
  echo incorrect format
fi

Wikipedia's article on ISO-8601 says that the format allows the omission of the day field, but the above regex requires it, following the question's example. The regex allows the T to be optional, following the Wikipedia article. I've added optional support for fractional seconds (the ([\.,][[:digit:]]+)? portion), again based on the Wikipedia article.

The regex does not do any range checking of the values.

Jeff Schaller
  • 2,352
  • 5
  • 23
  • 38
1

If you want your ISO date to be validated for any timezone, including the format

1970-01-01T00:00:00Z
1970-01-01T00:00:00+0200

Then you can use this regex:

[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|\+[0-9]{4})$
#!/bin/bash

if [[ $1 =~ [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|\+[0-9]{4})$ ]]
then
  echo "ISO date";
else
  echo "Malformed date";
fi
  • Keep in mind that [[ ]] is not POSIX compliant, this limits its portability.
Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
0

Here is a solution that doesn't use any regex and uses date parsing of gnu-date:

s='2021-08-23T12:10:35+200'

[[ $s == *'+200' && $(TZ=CET date -d "$s" '+%FT%T' 2>/dev/null) == "${s%+*}" ]] &&
echo 'ok' || echo 'nope'
anubhava
  • 761,203
  • 64
  • 569
  • 643