Converting timestamp with time zone to local time in Bash - bash

I am trying to do basic time math in Bash having following timestamps from OpenDj:
createtimestamp: 20161123165725Z
I don't know what time zone the system will be set with, it can be with "Zulu" timezone (UTC) as above, or might be with some other timezone. The above timestamp is for the users on LDAP servers. What I need to do is to compare the timestamp of the user with a certain timestamp.
Question: how do I convert the timestamp with zone (Z) above to local timestamp or epoch time in Bash?

Maybe Dateutils will help
http://www.fresse.org/dateutils/
dateconv -i '%s' -f '%A, %d %b %Y' 1234567890
Friday, 13 Feb 2009
dateutils tools default to UTC (add -z your/timezone if needed).

Related

I want to get local time in shell script in the specified format HH:MM:SS

I want to get startTime as start of current time (for eg current time is 12:55 pm) then startTime will be 12:00:00 and endTime will be 12:59:59.
I tried using startTime="$(date +'%H:%M:%S')" but this is giving time according to UTC time format i.e: 07:25:43. But I want result according to my local time zone. Zone is '+0530'.
You need to export the TZ before you run date like:
export TZ=Asia/Kolkata
startTime="$(date +'%H:%M:%S')"
or in one line:
startTime="$(TZ=Asia/Kolkata date +'%H:%M:%S')"

Why do I always get extra one day with date difference in bash?

I'm trying to calculate the seconds between a date from now, however, I always get extra one day when adding the seconds from now.
echo $(($(date -ud "2020-03-15 19:13" +'%s') - $(date +'%s')))
As of posting, the result is 1744204
Using this website to check, I gets 16 March, not 15 March as expected. Any idea why?
verify the result of your date commands and verify the timezone of both.
The first result of the command shows the timestamp in UTC, and the second one shows the timestamp using the timezone of the system.
Here is the difference:
$ date -ud "2020-03-15 19:13" +'%s'
1584299580
With UTC-3 in my system:
$ date -d "2020-03-15 19:13" +'%s'
1584310380
I hope that help you.

Strange behaviour of bash date and time arithmetics

When I issue bash command:
date --date="2018-03-03 12:16:13 -1hour" "+%Y:%m:%d %H:%M:%S"
I expect the result would be:
2018:03:03 11:16:13
but instead, I get:
2018:03:03 15:16:13
I wonder if this has to make with time zones, and how to avoid this behaviour.
I can reproduce this. My timezone is America/New_York
$ date --date="2018-03-03 12:16:13 - 1 hour" "+%Y:%m:%d %H:%M:%S"
2018:03:03 09:16:13
$ env TZ='Europe/Belgrade' date --date="2018-03-03 12:16:13 - 1 hour" "+%Y:%m:%d %H:%M:%S"
2018:03:03 15:16:13
The parser appears to be taking the -1 as the timezone GMT+01:00, then converting that to your local timezone.
If we rearrange the phrases to avoid the timezone parsing ambiguity, we can get your desired result:
$ date --date="- 1 hour 2018-03-03 12:16:13" "+%Y:%m:%d %H:%M:%S"
2018:03:03 11:16:13
From info coreutils 'date invocation'
When a relative item causes the resulting date to cross a boundary where the clocks were adjusted, typically for daylight saving time,
the resulting date and time are adjusted accordingly.
The fuzz in units can cause problems with relative items. For
example, '2003-07-31 -1 month' might evaluate to 2003-07-01, because
2003-06-31 is an invalid date. To determine the previous month more
reliably, you can ask for the month before the 15th of the current
month. For example:
$ date -R
Thu, 31 Jul 2003 13:02:39 -0700
$ date --date='-1 month' +'Last month was %B?'
Last month was July?
$ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
Last month was June!
Also, take care when manipulating dates around clock changes such
as daylight saving leaps. In a few cases these have added or
subtracted as much as 24 hours from the clock, so it is often wise to
adopt universal time by setting the 'TZ' environment variable to
'UTC0' before embarking on calendrical calculations.
One can avoid that by putting -1 hour before the string,
$ date --date='-1 hour 2018-03-03 12:16:13' "+%Y:%m:%d %H:%M:%S"
2018:03:03 11:16:13

How to subtract a day from an invalid date in shell script?

I'm working on a script to automate the download of information from a customer in the period from 00:00 to 23:59 on the same day. To make the correct treatment of the first day of daylight saving time (10/15/2017, in my timezone - BRST), I need to check the timezone of the previous day. However, when I will subtract one day from the first valid time,
date --date="20171015 01:00 -1 day" +%Y-%m-%d
the result is the next day 2017-10-16, not the previous day 2017-10-14. Could anyone help me understand what I might be doing wrong and how should I do this operation in the right way?
I don't really trust GNU date's arithmetic. Instead, I would convert your starting time to seconds since the UNIX epoch, subtract 86400 seconds, and convert the result back to a day. Those conversion routines take daylight saving time into account.
$ TZ=BRST date +%s --date "20171015 01:00"
1508029200
$ TZ=BRST date +%F-%T --date #$((1508029200 - 86400))
2017-10-14-01:00:00
It appears the "BRST" timezone is not very useful: stick to Olson timezone names
$ TZ=BRST date --date="20171015 00:30" "+%F %T"
2017-10-15 00:30:00
$ TZ=America/Sao_Paulo date --date="20171015 00:30" "+%F %T"
date: invalid date ‘20171015 00:30’

How to get diff between utc time and localtime in seconds?

How to get in bash diff between utc time and localtime in seconds ?
%s isn't trivially part of the answer without some time-related antics, epoch seconds is explicitly UTC (or maybe GMT if you're old-school), so setting TZ won't affect it.
Similar to twalberg's suggestion:
IFS=":" read hh mm < <(date +%:z)
echo $(($hh*3600+$mm*60))
You can test that this is doing what you want by setting TZ for the date command:
IFS=":" read hh mm < <(TZ=Australia/Sydney date %:z) # answer is 39600
IFS=":" read hh mm < <(TZ=US/Eastern date +%:z) # answer is -18000
(This isn't strictly a bash answer, since it requires GNU date or equivalent, 5.90 and later support %:z and %::z)
You'll probably have to do a little work to get it in seconds, but date +%z will report your configured timezone offset as [+-]HHMM. Parse the output of that and do the appropriate math to figure it out in seconds.
This will only work in places with whole hours and not minutes.
echo $(($( date +%z)*36))

Resources