> On Mar 15, 2017, at 09:43, Ulf Zibis <ulf.zi...@gmx.de> wrote: > > Am 15.03.2017 um 13:44 schrieb Eric Blake: >> Maybe you are confused on how date implements "subtract a month". It >> does NOT do "subtract 28, 29, 30, or 31 days as appropriate", but rather >> does "subtract 30 days, for lack of anything better to do". > > Are you really sure ??? > Here on my 8.25 version I get: > $ date -d "-12 month" +%F > 2016-03-15 > $ date -d "-360 day" +%F > 2016-03-20
To give more details about the inter working of date adjustments: Assuming the current date is 2017-03-15: "2017-03-15 - 12 months": Year = 2017 Month = -9 (yes, it is stored temporarily as -9) Day = 15 Then it is normalized to: Year = 2016 Month = 3 Day = 15 While "2017-03-15 - 360 days" = Year = 2017 Month = 3 Day = -345 (yes, stored as -345) then normalized to: Year = 2016 Month = 3 Day = 20 More about the normalization: When adjusting months (e..g "-12 months), The value of 'day' isn't touched. It will be (unexpectedly) modified only in cases where the month does not have that day, e.g.: "2017-03-30 - 1 month" becomes: Year = 2017 Month = 2 Day = 30 then normalized to: Year = 2017 Month = 3 Day = 2 (because "2017-02-30" means "2 days after 2017-02-28" which is "2017-03-02"). When adjusting days, it is equivalent to subtracting the number of seconds from the current unix epoch (i.e. seconds since 1970-01-01). Example: Current unix time: $ date -d '20170315' +%s 1489536000 Number of days you want to subtract, in seconds: $ bc -l<<<'360*86400' 31104000 Resulting unix time: $ bc -l<<<'1489536000-360*86400' 1458432000 Which is equivalent to: $ date -d @1458432000 +%F 2016-03-20 Technical note: date adjustment (years/months/days) is done directly on the member variables of a 'struct tm' , which is why it ignores the number of days in months. time adjustment (hours/minutes/seconds) is done on the unix time, AFTER the normalized date has been converted to unix time. > So I think my list for enhancements is still fully applicable. I'm late-comer to the thread, so I'll verify: You'd like to be able to do date calculations in some predictable way, in your case to be able to change a file's timestamp. However, consider that adjusting by any scale (years/months/days/hours/minutes) will have side-effects. Adjusting by months can shift days (e.g. "2016-03-30 - 1 month" is still march). Adjusting by days can shift hours (e.g. on Day light saving time), Adjusting by hours can stay in the same day (e.g. "+24 hours" on a when day light saving results in 25 "hours"). etc. It is the edge-cases that make day adjustment tricky (e.g. "+1 month" is not "+30 days", "+1 day" is not always "+24 hours", etc.). If you can come up with reliable and predictable rules for date adjustment that will not have these unexpected results - there's definitely room for improvements. However, there's also the existing behavior and backwards compatibility that will need to be taken into account. regards, -assaf