Subject: Re: bug#13938: Bug: date(1) -d "relative-to-skipped-time" problem (also in touch(1) -d)

From: Bob Proulx <[email-masked]>
Date: Tue, 12 Mar 2013 23:23:27 -0600

tag 13938 + moreinfo
thanks

Aleš Kantor wrote:
> Set date to Mar 10, 2013  (the day clocks moved fwd)

In which timezone?  Please tell us what timezone you are in because
the tzdata is different for everyone.

Instead of setting the time simply include the date in the timestamp.
But for the purpose of recreating the problem please do include the
timezone too.  The -R,--rfc-2822 option is good to use to avoid the
ambiguous timezone naming used in the traditional legacy output.

  $ env TZ=US/Mountain date -R -d "2013-03-10 12:00"
  Sun, 10 Mar 2013 12:00:00 -0600

> This command
>     date -d 2:30am
> gives "Invalid date," probably reasonable, since that time didn't exist.

Correct.  In US timezones at least that time does not exist.

> This one should work, but fails as well:
>   date  -d "2:00am yesterday"
> date: invalid date `2:00am yesterday'

You didn't say what timezone you are using.  I will assume a US
timezone until I learn otherwise.

That is correct behavior in the my own timezone.  The tzdata zone can
be dumped using the zdump command.

  $ zdump -v US/Mountain | grep 2013
  US/Mountain  Sun Mar 10 08:59:59 2013 UTC = Sun Mar 10 01:59:59 2013 MST isdst=0 gmtoff=-25200
  US/Mountain  Sun Mar 10 09:00:00 2013 UTC = Sun Mar 10 03:00:00 2013 MDT isdst=1 gmtoff=-21600
  US/Mountain  Sun Nov  3 07:59:59 2013 UTC = Sun Nov  3 01:59:59 2013 MDT isdst=1 gmtoff=-21600
  US/Mountain  Sun Nov  3 08:00:00 2013 UTC = Sun Nov  3 01:00:00 2013 MST isdst=0 gmtoff=-25200

This shows that last second before is "Sun Mar 10 01:59:59 2013 MST"
and the next second after that one is "Sun Mar 10 03:00:00 2013 MDT".
Since 2:00am does not exist it is an invalid timezone.  All
references to it are invalid in the specified timezone.

> Any _relative_ reference to the missing chunk of time will produce an error.
> ...
> root@ft:~# date  -d "2:00am yesterday"
> date: invalid date `2:00am yesterday'
> root@ft:~# date  -d "2:00am Monday"
> date: invalid date `2:00am Monday'
> root@ft:~# date  -d "2:10am Monday"
> date: invalid date `2:10am Monday'
> root@ft:~# date  -d "2:10am Jan 1"
> Tue Jan  1 02:10:00 PST 2013
> root@ft:~# date  -d "2:10am yesterday"
> date: invalid date `2:10am yesterday'
> root@ft:~# date  -d "2:10am tomorrow"
> date: invalid date `2:10am tomorrow'
> root@ft:~# date  -d "2:10am next week"
> date: invalid date `2:10am next week'
> root@ft:~# date  -d "1:10am next week"
> Sun Mar 17 01:10:00 PDT 2013

All correct.  A relative reference to an invalid time is still an
invalid time.

  $ env TZ=US/Mountain date -R -d "2013-03-10 1:59"
  Sun, 10 Mar 2013 01:59:00 -0700

  $ env TZ=US/Mountain date -R -d "2013-03-10 1:59 -1 day"
  Sun, 10 Mar 2013 20:59:00 -0600

That timestamp exists.  All good.  But 2am does not exist.  It is
invalid.

  $ env TZ=US/Mountain date -R -d "2013-03-10 2:00"
  date: invalid date ‘2013-03-10 2:00’

  $ env TZ=US/Mountain date -R -d "2013-03-10 2:00 yesterday"
  date: invalid date ‘2013-03-10 2:00 yesterday’

Since 2am is invalid then any time relative to the invalid time is
also invalid.  It does not exist therefore describing another time as
relative to a nonexistent time is also nonexistent.

To avoid these types of problems it is best to use UTC.  If the local
time must be used then using a time around 12:00 noon should avoid all
DST changes in practice.

  $ env TZ=US/Mountain date -u -R -d "2013-03-10 yesterday"
  Sat, 09 Mar 2013 00:00:00 +0000

  $ env TZ=US/Mountain date -R -d "2013-03-10 12:00 yesterday"
  Sat, 09 Mar 2013 12:00:00 -0700

Please see the date FAQ entry.  This topic is described in more detail
there.

  http://www.gnu.org/software/coreutils/faq/#The-date-command-is-not-working-right_002e

Bob