Web lists-archives.com

bash date behavior (buggy) (was: Re: policy around 'wontfix' bug tag)




Just an attempt to get a more informative subject line--maybe somebody can 
improve it.

On Tuesday, February 06, 2018 08:49:39 AM Greg Wooledge wrote:
> On Tue, Feb 06, 2018 at 01:48:19PM +0100, Vincent Lefevre wrote:
> > On 2018-02-05 09:39:12 -0500, Greg Wooledge wrote:
> > > Anyway, here's what I came up with:
> > > 
> > > lastday() {
> > > 
> > >     date +%Y-%m-%d -d "$1 1 day ago + 1 month"
> > > 
> > > }
> > 
> > But the exact meaning of "month" seems undocumented, which may
> > silently break in a future version (e.g. possibly as a consequence
> > of a bug fix). So this is a good example of what you should *not*
> > do.
> 
> If I have the luxury of writing in a real language, then I prefer
> to use that language's date/time libraries, if they exist and don't
> suck.
> 
> In bash, you get this, or you get to write your own date/time code
> by hand.
> 
> > This is completely crazy:
> > 
> > Where is the logic behind that?
> 
> As noted by someone else earlier in this thread, date recently learned
> a --debug option (this is my first time hearing about it), so let's
> try that:
> 
> wooledg:~$ date --debug +%Y-%m-%d -d '2003-09-01 1 day ago + 1 month'
> date: parsed date part: (Y-M-D) 2003-09-01
> date: parsed relative part: -1 day(s)
> date: parsed relative part: +1 month(s) -1 day(s)
> date: input timezone: -05:00 (set from system default)
> date: warning: using midnight as starting time: 00:00:00
> date: starting date/time: '(Y-M-D) 2003-09-01 00:00:00 TZ=-05:00'
> date: warning: when adding relative months/years, it is recommended to
> specify the 15th of the months date: warning: when adding relative days,
> it is recommended to specify 12:00pm date: after date adjustment (+0
> years, +1 months, -1 days),
> date:     new date/time = '(Y-M-D) 2003-09-30 00:00:00 TZ=-05:00'
> date: '(Y-M-D) 2003-09-30 00:00:00 TZ=-05:00' = 1064894400 epoch-seconds
> date: output timezone: -05:00 (set from system default)
> date: final: 1064894400.000000000 (epoch-seconds)
> date: final: (Y-M-D) 2003-09-30 04:00:00 (UTC0)
> date: final: (Y-M-D) 2003-09-30 00:00:00 (output timezone TZ=-05:00)
> 2003-09-30
> 
> So, it adds "a month" first, then subtracts "a day" second.  I suppose
> I could have rearranged the sub-arguments to make that clearer, but
> honestly, I stopped tweaking it once I had a working invocation.  It's
> so fragile that I didn't want to change *anything* for fear of breaking
> it.
> 
> In some cases, I dealt with this stuff using a truly ancient version
> of GNU date from the sh-utils package, before coreutils existed.  Some
> of the more modern invocations didn't work with the older program, so
> I often had to find different tricks that would work.  I don't know
> whether this was one such case.  It could have been.