Parse non standard date format - bash

Say I have the following format outputted for my date:
date --utc +%d.%m.%Y,\ %H:%M\ UTC
# Outputs: 12.06.2014, 09:03 UTC
How can I display the outputted date above, in another date call, in another format? I tried:
date --utc --date="12.06.2014, 09:03 UTC" +%d.%m.%Y,\ %H:%M\ UTC
but with no success (it says invalid date).
I am primarily trying to do this in order to be able to tell from an outputted date how many hours have passed (or days, or whatever time measuring unit).

Here is what the man date page says about format for the --date option:
The --date=STRING is a mostly free format human readable date string such as
"Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29 16:21:42" or even "next
Thursday". A date string may contain items indicating calendar date, time of day,
time zone, day of week, relative time, relative date, and numbers. An empty
string indicates the beginning of the day. The date string format is more
complex than is easily documented here but is fully described in the info
documentation.
Hence you can use, for example:
date --date "2014-06-12 09:03 UTC" --utc +%d.%m.%Y,\ %H:%M\ UTC
# Output: 12.06.2014, 09:03 UTC
to get what you desire.
You could get this second form easily from your first output with a sed line as follows:
sed 's/\([0-9]\{2\}\)\.\([0-9]\{2\}\)\.\([0-9]\{4\}\), \(.*\)/\3-\2-\1 \4/'
<<< '12.06.2014, 09:03 UTC'
# Output: 2014-06-12 09:03 UTC
Note that it would probably be faster to output date at ISO 8601 format in the first time for reuse, e.g. with:
date --utc +%F\ %H:%M\ UTC
# Output: 2014-06-12 10:12 UTC

I think you cannot specify input format, so you'll have to change it with another command like this:
date --utc --date="$(echo "12.06.2014, 09:03 UTC" | sed -r 's/(..).(..).(....), (..):(..) UTC/\3-\2-\1 \4:\5 UTC/')"
Also if you want to make arithmethic on this you could use +%s:
DATE1=$(date "+%s" --date="$(echo "12.06.2014, 09:03 UTC" | sed -r 's/(..).(..).(....), (..):(..) UTC/\3-\2-\1 \4:\5 UTC/')")
DATE2=$(date "+%s" --date="$(echo "17.06.2014, 08:30 UTC" | sed -r 's/(..).(..).(....), (..):(..) UTC/\3-\2-\1 \4:\5 UTC/')")
DIFF_IN_SECONDS=$(($DATE2-$DATE1))
DIFF_IN_RAW_DAYS=$(( ($DATE2-$DATE1)/86400 ))
DIFF_IN_DATES=$(( (($DATE2/86400) - ($DATE1/86400)) ))

Related

The date command appears to convert timezones the wrong way?

I'm working on a script where I need to convert the current time, in UTC to something else:
fmt="%Y-%m-%d %H:%M:%S"
tzone=America/Detroit
nowinutc=$(TZ=UTC date +"$fmt");echo $nowinutc
nowintz=$(date -d "TZ=\"$tzone\" $nowinutc" +"$fmt");echo $nowintz
yestintz=$(date -d "$nowintz - 1 day" +"$fmt");echo $yestintz
I know America/Detroit is 5 hours behind UTC, so 08:00:00 should become 03:00:00, but:
$ fmt="%Y-%m-%d %H:%M:%S"
$ tzone=America/Detroit
$ nowinutc=$(TZ=UTC date +"$fmt");echo $nowinutc
2022-02-11 08:49:51
$ nowintz=$(date -d "TZ=\"$tzone\" $nowinutc" +"$fmt");echo $nowintz
2022-02-11 13:49:51
$ yestintz=$(date -d "$nowintz - 1 day" +"$fmt");echo $yestintz
2022-02-12 14:49:51
It's probably not the date command that gets it wrong, but what am I doing wrong here? It looks like everything works the opposite way of expected. Not only does the timezone conversion add 5 hours, but subtracting 1 day adds 25 hours - what is going on here?
so 08:00:00 should become 03:00:00
Then the input is in UTC and you are in Detroit.
TZ=America/Detroit date -d "08:00:00 UTC" +%H:%M:%S
TZ=America/Detroit date -d "TZ=\"UTC\" 08:00:00" +%H:%M:%S
TZ=America/Detroit date -d "08:00:00+00:00" +%H:%M:%S
From man date examples:
Show the time on the west coast of the US (use tzselect(1) to find TZ)
$ TZ='America/Los_Angeles' date
Show the local time for 9AM next Friday on the west coast of the US
$ date --date='TZ="America/Los_Angeles" 09:00 next Fri'

How to add or subtract from date with format DDMMYYYY in bash?

This is working
date -d '2019-12-13 -5 day' +%d%m%Y
However, the following is throwing an error to me
date -d "13122019 -5 day" +%d%m%Y
From man date
The --date=STRING is a mostly free format human readable date string such as "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29 16:21:42" or even "next Thursday". [...] The date string format is more complex than is easily documented here but is fully described in the info documentation.
tl;dr: Seems like you cannot specify the format of the input. Use one of the known formats, for instance
date -d '2019-12-13 -5 day' +%d%m%Y
To automatically convert a date from DDMMYYYY format to YYYY-MM-DD you can use sed ...
date -d "$(sed -E 's/(..)(..)(.*)/\3-\2-\1/' <<< 13122019) -5 day" +%d%m%Y
... or bash ...
d=13122019
date -d "${d:4}-${d:2:2}-${d:0:2} -5 day" +%d%m%Y

Convert human readable time into EPOCH using shell script

I have a human readable time as
08-18-2016 09:18:25
I want it to be converted into epoch time using shell script.
I tried with date "+%s" but I am getting the error
date: invalid date `08-18-2016 09:32:42'
The canonical way to convert a datetime into epoch is to use:
date "+%s" # for this moment's date
date -d" some date" "+%s" # for a specific date
However, in this case the format is not valid:
$ date -d"08 18 2016 09:18:25" "+%s"
date: invalid date ‘08 18 2016 09:18:25’
You need, then, to massage the string a bit before passing it to date -d.
This converts the two first spaces into slashes:
$ sed 's# #/#;s# #/#' <<< "08 18 2016 09:18:25"
08/18/2016 09:18:25
So this works:
$ date -d"$(sed 's# #/#;s# #/#' <<< "08 18 2016 09:18:25")" "+%s"
1471504705
Or using variables:
$ nice_date=$(sed 's# #/#;s# #/#' <<< "08 18 2016 09:18:25")
$ date -d"$nice_date" "+%s"
1471504705
Thanks for the explanation fedorqui. But 1471511905 is the epoch time
for 08 18 2016 09:18:25, not 1471504705. – Mohit Rane
date -u … will print Coordinated Universal Time.

convert input timestamp from ist to utc (UNIX)

I am getting date as an input parameter which is IST from some source but I have to convert it into UTC format i.e., I have to substract 5 hours 30 minutes to the date which I am receiving.
echo "Date format DD/MM/YYYY HH:SS"
read $input
I can do this writing small function which will grep HH and SS from the $input and then add which checking conditions which is tedious task, instead I want to know is there any way to do this ?
I found date command option which works like this:
date -d "15/05/2014 10:12 -5 hours -30 minutes"
not working
date -d "15/05/2014 10:12 5 hours ago 30 minutes ago" also not working.
Assuming you are getting your IST date in $date variable you can do this to get GMT date:
date="15/05/2014 10:15"
As a 1st step convert your dd/mm/yyyy date to mm/dd/yyyy:
date=$(awk 'BEGIN{FS=OFS="/"} {print $2, $1, $3}' <<< "$date")
Convert to GMT:
( export TZ='GMT' && date -d 'TZ="Asia/Kolkata" '"$date" )
Thu May 15 04:45:00 GMT 2014
To get EPOCH GMT value:
( export TZ='GMT' && date -d 'TZ="Asia/Kolkata" '"$date" '+%s' )
1400129100

converting month number to date using KornShell

I am trying to convert month number to name, but it is giving output as current month instead of the date given in the variable.
KornShell (ksh) Code:
datep= 2013-10-22
echo $datep |printf "%(%B)T\n"
printf doesn't read from standard input, so it is assuming today's date as the default argument for the %T format; you need to provide the date as an argument instead.
printf "%(%B)T\n" "$datep"
Do it like this:
$ datep="2013-10-22"
$ date -d"$datep" "+%B"
October
As per man date,
-d, --date=STRING
display time described by STRING, not 'now'
So we get:
$ date -d"$datep"
Tue Oct 22 00:00:00 CEST 2013
Then you say you want the %B, that is, also from man date:
%B
locale's full month name (e.g., January)
So it is just a matter of using the format at the end of the string.
Other examples:
$ date -d"$datep" "+%Y" #year
2013
$ date -d"$datep" "+%F" #date
2013-10-22
$ date -d"$datep" "+%T" #time (if not given, gets the default)
00:00:00

Resources