Bash 'date -d' bug? - linux

I am using Ubuntu 10.04 LTS. In bash I am getting error while converting string to date like this:
date -d '20110327 02:00'
date: invalid date `20110327 02:00'
but these work:
date -d '20110327 03:00'
Sun Mar 27 03:00:00 CEST 2011
date -d '20110326 02:00'
Sat Mar 26 02:00:00 CET 2011
date -d '20110328 02:00'
Mon Mar 28 02:00:00 CEST 2011
Any ideas?
Thanks,
Jan

It's the summer time !
In 2011, we get an additionnal hour on the March 27th at 2:00 it was in fact 3:00.
So 27/03/2011 2:00 is not a valid date :-)

Nope, I'm sure there was a transition to/from Daylight Saving Time (DST) at 2:00 that day, so there wasn't 2:00 :)

Well there is no such local time - there was switch to summer time and the clock went from 1:59 to 3:00.

Related

Converting date in a different timezone with `date`

I am trying to convert dates from different timezones with UNIX date (I am on Ubuntu 20.04).
With current date, it works well:
$ date
dim. 12 déc. 2021 11:59:16 CET
$ TZ=Pacific/Tahiti date
dim. 12 déc. 2021 00:59:32 -10
But when I am working with a string, it fails:
$ export testdate="2021/10/28 17:47:26"
$ date -d "$test"
jeu. 28 oct. 2021 17:47:26 CEST
$ TZ=Pacific/Tahiti date -d "$test"
jeu. 28 oct. 2021 17:47:26 -10
as I am expecting:
jeu 28 oct. 2021 05:47:26 -10
I don't understand why I don't get the proper shift. And of course if I try with a date and time where the day should also change, it doesn't work either:
$ export test="2021/10/28 7:47:26"
$ date -d "$test"
jeu. 28 oct. 2021 07:47:26 CEST
$ TZ=Pacific/Tahiti date -d "$test" "+%F %T %Z"
2021-10-28 07:47:26 -10
while I am expecting:
mer 27 oct. 2021 19:47:26 -10
why I don't get the proper shift
test="2021/10/28 17:47:26"
Is a date in unknown timezone. No one knows what timezone it is in, what the daylight is. GNU date tries to "guess" what offset you meant, it generally traverses TZ database for current timezone and just picks the first offset that matches. Also, specifying timezone is not enough to know what daylight it is, you have to be specific.
Also, because of the daylight time you can "go back" in time, it's now known what the offset to UTC is even when you know the timezone.
Also, you don't have to export it - date does not care about test environment variable.
Converting date in a different timezone with date
If the input is in UTC, tell date that.
$ LC_ALL=C TZ=Pacific/Tahiti date -d "2021/10/28 17:47:26 UTC"
Thu Oct 28 07:47:26 -10 2021
If the input is with any other offset, tell date that.
$ LC_ALL=C TZ=Pacific/Tahiti date -d "2021/10/28 17:47:26 CEST"
Thu Oct 28 05:47:26 -10 2021
Te parsing of GNU date of input format is generally a mystery. The documentation lists 2004-02-29 16:21:42 format as an example input, so I recommend that format. If you want to be exact, I recommend strptime from dateutils (or a real programming language).
One simple way is to convert time first to epoch time :
test="2021/10/28 17:47:26"
TZ=Pacific/Tahiti date -d #$(date -d "$test" +%s)
date -d "$test" +%s converts local time to epoch time.
TZ=Pacific/Tahiti date -d #$(date -d "$test" +%s) prints Tahiti time from epoch time.
I'm not fully confident, but i get the impression you're looking the following syntax:
LC_TIME="es_ES.UTF8" TZ="America/New_York" date --date='TZ="Europe/Amsterdam" 2021/10/28 17:47:26' "+%A %F %T %B"
That takes a predefined datetime (interpreted as being local to Amsterdam), adjusts the datetime (based on the time difference) to New York-time at that same moment; Then it prints that result with Spanish names for the months/weekdays (provided that language' locale is present on your system).

get full date of a specific day of the current week with GNU date

Is there a way to get the date of Friday of the current week regardless whether it is in the future or past from current day ?
For example, today is 2021-07-10 so Friday of the current week would be one day ago. But if today was 2021-07-05 Friday of the current week would be four days in the future.
I am aware that with date utility you can get either last Friday or the coming Friday with :
date --date="last Friday" and
date --date="next Friday"
is there a way to get the date of Friday of the current week without complicated logic ?
The only way I know how to do what you want is to do something like the following
date -d "next monday - $(($(date +%u) -1)) days"
Of course, there are side issues such as which day is the start of the business week (it varies), etc.
Here is a simple script to print out a week's dates:
#!/bin/bash
for DAY in monday tuesday wednesday thursday friday saturday sunday
do
# date -d "next $DAY - $(($(date +%u) - 1)) days"
date -d "next $DAY - $(date +%u) days
done
It produces the following output based on today's date:
Mon Jul 5 12:00:00 AM PST 2021
Tue Jul 6 12:00:00 AM PST 2021
Wed Jul 7 12:00:00 AM PST 2021
Thu Jul 8 12:00:00 AM PST 2021
Fri Jul 9 12:00:00 AM PST 2021
Sat Jul 10 12:00:00 AM PST 2021
Sun Jul 11 12:00:00 AM PST 2021

why timestamps for two timezones with the same UTC offset are different?

Here is an example:
root#linux:~# timedatectl
Local time: Thu 2016-03-31 08:33:23 CEST
Universal time: Thu 2016-03-31 06:33:23 UTC
RTC time: n/a
Time zone: Africa/Ceuta (CEST, +0200)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: yes
Last DST change: DST began at
Sun 2016-03-27 01:59:59 CET
Sun 2016-03-27 03:00:00 CEST
Next DST change: DST ends (the clock jumps one hour backwards) at
Sun 2016-10-30 02:59:59 CEST
Sun 2016-10-30 02:00:00 CET
root#linux:~# echo $string
1970 01 01 0 0 0
root#linux:~# awk -v str="$string" 'BEGIN {print mktime(str)}'
0
root#linux:~# timedatectl set-timezone Europe/Berlin
root#linux:~# timedatectl
Local time: Thu 2016-03-31 08:59:01 CEST
Universal time: Thu 2016-03-31 06:59:01 UTC
RTC time: n/a
Time zone: Europe/Berlin (CEST, +0200)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: yes
Last DST change: DST began at
Sun 2016-03-27 01:59:59 CET
Sun 2016-03-27 03:00:00 CEST
Next DST change: DST ends (the clock jumps one hour backwards) at
Sun 2016-10-30 02:59:59 CEST
Sun 2016-10-30 02:00:00 CET
root#linux:~# echo $string
1970 01 01 0 0 0
root#linux:~# awk -v str="$string" 'BEGIN {print mktime(str)}'
-3600
2 question: And why mktime output (when input 1970-01-01T00:00:00 ) for Europe/Berlin timezone is -1 hour?
timedatectl (apparently) shows the current timezone rules in effect for the currently set timezone. However timezone rules change over time within the same timezone.
As of today, both Africa/Ceuta and Europe/Berlin have the same UTC offset, and follow the exact same rules for daylight savings. But they haven't always done so.
In 1970-01-01 Africa/Ceuta used a 0:00:00 UTC offset and did not use daylight saving.
In 1970-01-01 Europe/Berlin used a 1:00:00 UTC offset and did not use daylight saving.
It wasn't until 1986-03-30 01:00:00 UTC that Africa/Ceuta and Europe/Berlin adopted the same rules. Your computer knows this history, and accurately reflects it when doing conversions between UTC and local time for dates prior to 1986-03-30.
they change to Summer and Winter-times at different dates, which is why the times might be different even though they have the same UTC offset

Get Tuesday and Wednesday next week, with Linux date command

At a Linux shell, you can do something like:
date -d "next Tuesday"
To get next Tuesday.
My issue is this:
I want to get Tuesday of NEXT WEEK. So if I'm currently on Monday, I want it to go 7 days forward to next week, then evaluate "next Tuesday". Is there a way to chain the date evaluations somehow?
To further elaborate, if I am on a Wednesday, then next week's Tuesday is just 6 days away
date is cleverer than you'd think
~: date -d "next tuesday"
Tue Feb 2 00:00:00 GMT 2016
~: date -d "1 week next tuesday"
Tue Feb 9 00:00:00 GMT 2016
~:
If you want to get the Tuesday of next week you can find the start of next week, then add a day
~: date -d "1 day next monday"
Tue Feb 2 00:00:00 GMT 2016
If you want it to be slightly clear you can use
~: date -d "next Monday + 1 day"
Tue Feb 2 00:00:00 GMT 2016
Based on Charles Duffy's comments it might be worth noting on my machine
~: date --version #on RHEL6
date (GNU coreutils) 8.4
<license stuff (GPLv3)>
The only way to do this reliably is to first get the next "beginning of week day" (which might vary from region to region; for this I'll assume it's Sunday), then request a day 0-6 days in the future, where 0 through 6 stand in for Sunday through Saturday, respectively.
$ bow=$(date -d "next Sunday")
$ date -d "$bow + 0 days"

Real-time display of `date` changes on Linux

On an embedded Linux device that does not present /dev/rtc*, how can I set off a console window writing the value of the Real-Time Clock to the console, on the tick, every time it changes?
Results would be like:
$ **someCmd**
Mon Mar 14 16:43:22 UTC 2011
Mon Mar 14 16:43:23 UTC 2011
Mon Mar 14 16:43:24 UTC 2011
Mon Mar 14 16:43:25 UTC 2011
Mon Mar 14 16:43:26 UTC 2011
etc.
The device is armv5tejl running BusyBox v1.13.3.
Use the watch commad, try this is:
watch -n 1 date
I don't know how much the BusyBox shell supports, but in sh you could do something like this:
{ while true ; do date ; sleep 0.1 ; done } | uniq

Resources