dateutils
dateutils copied to clipboard
dseq 'fixes' incorrect input, rather than throwing an error
An example:
$ dseq 2013-02-30 2013-02-30
2013-02-28
Not sure if you'd like to consider this an error and fail, but in scripts it could cause problems, where the user puts in a false date, and the script churns out fine-looking output, just for the wrong day(s).
Yes, this also does occur on my system as well.
Hm, I quite liked that feature. This allows you to write things like 2014-${m}-31 for
some user input $m in scripts and not worry about the logic to handle the edge cases.
On the other hand, you're right, if I returned an error for that you could just propagate
the error to the user.
I'm a bit hesitant to change the behaviour now. On the one hand, it appears to be undocumented (as far as I can see) and hence if anyone actively or accidentally uses it, it's their own fault. On the other hand, changing established behaviour is just rude.
Well, here's the list of options:
- leave everything as is
- go strict and error on invalid dates
- return an error code (2 for instance) but still output the date just like now
- print a warning about the rounding on stderr but still output the date as now
- provide an option --strict to handle dates strictly and keep the default behaviour
- handle dates strictly by default, and as now when an option --slack (or so) is used
- none of the above/something else
Let's make a poll :) I kind of favour 1, 3, or 5 but I'm fine to implement any of them.
Hi Sebastian,
Yes I completely agree, in fact I'm already making use of the behaviour!
I would favour a combination of 3 and 6: output date, as it is now, and then error code (2) unless --slack is provided. This shouldn't break existing scripts (unless they're testing the error code, in which case they might actually care to see the error) but it would also make the behaviour documented.
Perhaps it's also worth asking whether the error behaviour should be more fine-grained: I don't see an obvious valid use case for rounding the START date to earlier (rounding the end date, definitely, as when you use '31' to signify end of month). Especially when both the start and end date are the same, and wrong, (say February 30), this should at least generate no dates rather than a single Feb 28, surely?
Apart from anything, thank you many times over for your wonderful toolkit, and for the speedy response! Very much appreciated.
Cheers, Rob.
On 2 October 2014 13:41, Sebastian Freundt [email protected] wrote:
Hm, I quite liked that feature. This allows you to write things like 2014-${m}-31 for some user input $m in scripts and not worry about the logic to handle the edge cases. On the other hand, you're right, if I returned an error for that you could just propagate the error to the user.
I'm a bit hesitant to change the behaviour now. On the one hand, it appears to be undocumented (as far as I can see) and hence if anyone actively or accidentally uses it, it's their own fault. On the other hand, changing established behaviour is just rude.
Well, here's the list of options:
- leave everything as is
- go strict and error on invalid dates
- return an error code (2 for instance) but still output the date just like now
- print a warning about the rounding on stderr but still output the date as now
- provide an option --strict to handle dates strictly and keep the default behaviour
- handle dates strictly by default, and as now when an option --slack (or so) is used
- none of the above/something else
Let's make a poll :) I kind of favour 1, 3, or 5 but I'm fine to implement any of them.
— Reply to this email directly or view it on GitHub https://github.com/hroptatyr/dateutils/issues/27#issuecomment-57615880.
Yes, I like #3 as well. It should be fairly obvious what is happening to someone typing on a command line, and a script could easily catch the error.
Ok, the public has spoken. I agree, 3 is just a beautiful way out of/around this peculiar issue.
As for pairing it with proposal 6, I reused the -q|--quiet flag, justified by the fact that
if someone wants the error code and yet quieten things, they could just use 2>/dev/null
to mute the warnings.
@Robert As for the fine-grain control, the fixing-up takes place very early, in the parser to be precise. It thus happens for all tools and dates in the same way, i.e. dseq will not even see a "wrong" date.
If that's a good choice for dseq (or ddiff, both happen to take 2 dates as inputs) is another question/issue in my eyes. There is a toy mode in dateutils (can be enabled at compile time only with --enable-fast-arith), that does no fixing up and keeps other properties as well, so the difference in days between 2014-02-28 and 2014-02-30 is 2. And yet 2014-02-30 comes before 2014-03-01 because something in February is always before something in March.
I got convinced pretty early in the development that this way of seeing things is unacceptable and counterintuitive and at that stage I developed the "fixing-up" strategy. Also note other systems do things differently, the built-in libc date arithmetic defines 2013-02-30 to be equivalent to 2013-03-02, but they allow a much wider range of inputs in every time unit, 2013-13-32 is in fact just 2014-02-01, etc.
0.3.1 is out now with the 3rd workaround in place.
I'm still looking into the original issue whether to make dseq output nothing at all when presented "off" dates. I just can't find a consistent way to do it.
Essentially, dseq A B should be equivalent to
seq 0 `ddiff A B` | dadd A
or, alternatively (and without involving dadd):
dseq A B | ddiff A
should output a sequence of integers starting with 0.
Which means to forbid A from being an "off" date and producing output,
at least ddiff must follow the same semantics, i.e. the first argument mustn't
be an "off" date (just so ddiff A B produces empty output). Furtherly though,
because ddiff (or subtraction in general) is anti-commutative (A - B = -(B - A))
the second argument mustn't be an off-date either. All in all, a move I'd pity
because I like calculating the number of days till the month's end.
Anyway, I can imagine how that particular dseq example may seem confusing, especially to the casual user, but secretly -- as in don't tell anyone :) -- I target power users and they'd be more confused when the tool set as a whole isn't consistent.
I'm keeping the issue open for now, maybe someone comes up with a brilliant solution. And really I should go and put some effort into documenting these peculiarities, I mean design choices.