7
$\begingroup$

The following code attempts to measure the difference in months between the last day of a year and the first day of a month in the following year.

QuantityMagnitude@DateDifference[{2018, 12, 31}, {2019, #, 1}, "Month"] & /@ Range@12

which produces

{0.0322581, 1.03571, 2.03571, 3.03333, 4.03333, .03333,
6.03333, 7.03226, 8.03333, 9.03333, 10.0333, 11.0333}

However, the results are not what I would expect. Specifically, I would expect the denominator in calculating the fractional part to be the number of days in that particular month, i.e.

1/{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // N

{0.0322581, 0.0357143, 0.0322581, 0.0333333, 0.0322581, 0.0333333, 0.0322581, 0.0322581, 0.0333333, 0.0322581, 0.0333333, 0.0322581}

What appears to be used instead is a sequence of days in each month of the year which is;

31, 28, 28, 30, 30, 30, 30, 31, 30, 30, 30, 30

which doesn't make much sense. Not only that, but it leads to nonsensical results such as the following;

In[359]:= DateDifference[{2018, 12, 31}, {2019, 3, 28}, "Month"]

Out[359]= Quantity[3, "Months"]

In[360]:= DateDifference[{2018, 12, 31}, {2019, 3, 29}, "Month"]

Out[360]= Quantity[3.03571, "Months"]

In[361]:= DateDifference[{2018, 12, 31}, {2019, 3, 30}, "Month"]

Out[361]= Quantity[3.07143, "Months"]

In[362]:= DateDifference[{2018, 12, 31}, {2019, 3, 31}, "Month"]

Out[362]= Quantity[3, "Months"]

Is this a bug or am I missing something? I can't see how this would be a feature.

Many thanks for your thoughts.

$\endgroup$
5
  • $\begingroup$ This seems perfectly reasonable. UnitConvert[Quantity[1.0, "Months"], "Days"] is not an integer multiple of days so this is expected. $\endgroup$
    – flinty
    Jul 16 '20 at 12:37
  • $\begingroup$ I disagree. Your example above takes a month in isolation. The result is 30.4167 which is the average length of a month in a year (multiply by 12 to get 365). However, DateDifference in taking the difference between two specific dates - there is a context provided. Also, if you reread my post, you'll see that the denominator that is being used for the number of days in a month is not constant but does not appear to fit a pattern that makes sense (at least to me). $\endgroup$ Jul 16 '20 at 12:39
  • 2
    $\begingroup$ You're asking for the date difference in units of months which is units of 30.4167 days. It's documented behaviour, not a bug. The unit cannot change depending on which month it's in. Use mixed radix units {"Month", "Day"} instead. $\endgroup$
    – flinty
    Jul 16 '20 at 12:44
  • $\begingroup$ It sounds like some application of DateRange is really what you need instead: DateRange[{2018, 12, 31}, {2019, 3, 1}, "Month"]. Also your expectation1/{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // N is wrong, you probably meant 1/Accumulate[{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}] // N because you started with a fixed date {2018, 12, 31} $\endgroup$
    – flinty
    Jul 16 '20 at 12:52
  • $\begingroup$ @flinty: Oh I see. OK thanks, I will use mixed radix units instead then. $\endgroup$ Jul 16 '20 at 12:52
7
$\begingroup$

I have noticed this problem too. First, the OP's version.

Denominator@Rationalize@
    DateDifference[{2018, 12, 31}, {2019, #, 1}, "Month"][[1]] & /@ Range@12

{31, 28, 28, 30, 30, 30, 30, 31, 30, 30, 30, 30}

This was my solution.

dateDifference[from_, to_, u:"Month"] :=
 DateDifference[from + {0, 0, 1}, to + {0, 0, 1}, u]

Denominator@Rationalize@
    dateDifference[{2018, 12, 31}, {2019, #, 1}, "Month"][[1]] & /@ Range@12

{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

$\endgroup$
1
  • $\begingroup$ Quick and dirty but it works. Thanks! $\endgroup$ Jul 17 '20 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.