coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to calculate date relative to another date?


From: Assaf Gordon
Subject: Re: How to calculate date relative to another date?
Date: Sat, 1 Jun 2019 12:00:44 -0600
User-agent: Mutt/1.11.4 (2019-03-13)

Hello,

> On Tue, May 21, 2019 at 9:17 PM Peng Yu <address@hidden> wrote:
> > > $ date --iso --date='2018-05-01 5 years ago'
> > > 2013-05-01
> >
> > What is special about --iso?

On Wed, May 22, 2019 at 06:44:40AM -0400, Steeve McCauley wrote:
> --iso seems to be an undocumented equivalent to the --iso-8601 date format,
> that gives you YYYY-MM-DD as the default format.

Not "undocumented" - in standard GNU programs (and many others too),
long options (those starting with two minus characters) can be
abbreviated if the shortened form is unique.

Example: date(1) has a "--reference" long option which can be shortened
to "--ref"

    $ date --ref
    date: option '--reference' requires an argument
    Try 'date --help' for more information.

While just "--rfc" will result in an error:

    $ date --rfc
    date: option '--rfc' is ambiguous; possibilities: '--rfc-email'
    '--rfc-3339'

And "--rfc-e" is acceptable:

    $ date --rfc-e
    Wed, 22 May 2019 21:47:19 -0600

Generally,
1. If your shell supports auto-completion, typing "--iso<TAB><TAB>" will
   auto-complete the long option to its full name.
2. It's fine to use the shortened form when typing comnnads
   interactively on the shell prompt.
3. It's discouraged to use the shortened form in scripts, because a
   future new option might break it (e.g. if "--iso-foo" and "--iso-bar"
   are added in the future, "--iso" alone wouldn't be unique and will break
   the script).


> On Tue, May 21, 2019 at 9:17 PM Peng Yu <address@hidden> wrote:
> > If I use the following date string, I get
> > a future time. Why?
> >
> > $ date --date='2018-05-01 4 years 11 months ago' +%Y%m
> > 202106
> >

For all such issues, "date --debug" should be the first thing to try.
It will show:

    $ date --debug --date='2018-05-01 4 years 11 months ago' +%Y%m
    date: parsed date part: (Y-M-D) 2018-05-01
  **date: parsed relative part: +4 year(s)
  **date: parsed relative part: +4 year(s) -11 month(s)
    date: input timezone: system default
    date: warning: using midnight as starting time: 00:00:00
    [...]
    date: final: (Y-M-D) 2021-06-01 00:00:00 (UTC-06)
    202106

So date(1) parsed your date string as "add 4 years and subtract 11
months" - that's why the resulting date is in the future.

While it doesn't yet explain how to fix it, it clearly shows the parsing
and processing flow.

> You seem to have fallen on a bug in that either,
>
> 1) date string is corrupt and doesn't emit an error
> 2) date string is correct but fails to generate a correct result

This is not a bug at all.

> According to the man page it is fully documented in the "info"
> documentation.  From what I can tell the more complex relative date string
> (4 years 11 months ago) is not supported,
>
[...]
>
> It would be pretty awesome if one could specify "4 years 11 months 3 days 4
> hours and 7 minutes ago" but that seems not possible.  In your case I also
> tried "4 years 11 months from 2018-05" but that just failed.

Once the parsing rules and reasoning are understood, it is easy to do
so. The parser is quite limited, certainly not "AI"
level or natual language level (although the 'ago' string might wrongly hint
it understand natural language).

The parser simply tries to break each part of the string (greedily)
and see if thy match a known 'type' (date, time, timezone, relative
date, relative time), and apply each part in sequence.

"Ago" should be thought as a simple "minus" character, negating the last
part's value.  While a human might understand the string as:

  "2018-05-01 and ((4 years and 11 months) ago)"

the date(1) program is not so sophisticated, and the parsing is:

  "2018-05-01" - date
  "4 years"    - relative date (add 4 years)
  "11 months ago" - relative date (subtract 11 months)

Using "--debug" shows it clearly.

However:

  $ date --date='2018-05-01 -4 years -11 months' +%Y%m
  201306

  $ date --date='2018-05-01 4 years ago 11 months ago' +%Y%m
  201306

And also:

    $ date -u --debug -d '2018-05-01 -4 years -11 months -3 days -4 hours -7 
minutes'
    date: parsed date part: (Y-M-D) 2018-05-01
    date: parsed relative part: -4 year(s)
    date: parsed relative part: -4 year(s) -11 month(s)
    date: parsed relative part: -4 year(s) -11 month(s) -3 day(s)
    date: parsed relative part: -4 year(s) -11 month(s) -3 day(s) -4 hour(s)
    date: parsed relative part: -4 year(s) -11 month(s) -3 day(s) -4 hour(s) -7 
minutes
    [...]
    date: final: (Y-M-D) 2013-05-28 19:53:00 (UTC+00)
    Tue May 28 19:53:00 UTC 2013


Hope this helps,
 -assaf




reply via email to

[Prev in Thread] Current Thread [Next in Thread]