ManInMoon
ManInMoon

Reputation: 7005

How can I convert a string to DateTime with specific format?

I can't see any way to specify a parsing format for date, and my input format is not recognized:

dt1=`date --date="20151020T113100.475"`; echo $dt1  # fails with 'invalid date'

Upvotes: 2

Views: 1965

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84521

As you can see, there are a number of different ways to approach this problem. As correctly noted, the key is finding a format that date -d "string" with consider a valid date/time string. Starting with the original string:

20151020T113100.475

One close format that date will accept is:

20151020 11:31:00.475

Getting the current string into the new format, just takes a few iterations of substring removal and piecing back together again. A short script that would work is:

#!/bin/bash

d="20151020T113100.475"

dt=${d%T*}          ## 20151020
tm=${d#*T}          ## 113100.475
tfrac=${tm#*.}      ## 475
tm=${tm%.$tfrac}    ## 113100

## add : between time components
for ((i = 0; i < ${#tm}; i+=2)); do
    nt=$nt:${tm:$i:2}
done
nt=${nt:1}          ## 11:31:00
nt=${nt}.$tfrac     ## 11:31:00.475

echo "date : '$(date -d "$dt $nt" +"%x %X (+.%N nanosecs)")'"

exit 0

Output

$ bash parsedtstamp4.sh
date : '10/20/2015 11:31:00 AM (+.475000000 nanosec)'

Upvotes: 0

amdixon
amdixon

Reputation: 3833

As suggested by DevSolar, if you arent doing any other date processing with these values, can just use

if [[ $dt1 < $dt2 ]]; then
  # your logic here..
  printf "less than..\n";
else
  # your logic here..
  printf "greater than or equal..\n";
fi

if you need to convert these to date form and/or want to validate the string input, can use bash substring extraction :

$ dt1="20151020T113100.475"
$ date -d "${dt1:0:4}-${dt1:4:2}-${dt1:6:2} ${dt1:9:2}:${dt1:11:2}:${dt1:13:6}"
Tue Oct 20 11:31:00 AEDT 2015

output formats can be applied also here eg :

$ date -d "${dt1:0:4}-${dt1:4:2}-${dt1:6:2} ${dt1:9:2}:${dt1:11:2}:${dt1:13:6}" +"%s"
1445301060

here %s gives seconds since 1970-01-01 00:00:00 UTC

so to compare with another date ( dt2 ), can use something like

dt1="20151020T113100.475"
dt2="20151021T113100.475"
ts1=$(date -d "${dt1:0:4}-${dt1:4:2}-${dt1:6:2} ${dt1:9:2}:${dt1:11:2}:${dt1:13:6}" +"%s")
ts2=$(date -d "${dt2:0:4}-${dt2:4:2}-${dt2:6:2} ${dt2:9:2}:${dt2:11:2}:${dt2:13:6}" +"%s")
if ((ts1<ts2)); then
  # your logic here..
  printf "less than..\n"
else
  # your logic here..
  printf "greater than or equal..\n"
fi

which outputs

less than..

see man date for valid output formats

Upvotes: 2

Related Questions