**Aritmetica di** `TimeType`

**e** `Period`

It’s good practice when using any language/date framework to be familiar with how date-period arithmetic is handled as there are some tricky issues to deal with (though much less so for day-precision types).

The ** Dates** module approach tries to follow the simple principle of trying to change as little as possible when doing

**arithmetic. This approach is also often known as calendrical arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let’s take a classic example: add 1 month to January 31st, 2014. What’s the answer? Javascript will say March 3 (assumes 31 days). PHP says March 2 (assumes 30 days). The fact is, there is no right answer. In the**

`Period`

**module, it gives the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 gambling game in casinos.**

`Dates`

Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. Then the day number is checked if it is greater than the last valid day of the new month; if it is (as in the case above), the day number is adjusted down to the last valid day (28). What are the ramifications with this approach? Go ahead and add another month to our date, 2014-02-28 + Month(1) == 2014-03-28. What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, and boom, we’re done because that’s a valid date. On the other hand, if we were to add 2 months to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things in different orders results in different outcomes). For example:

What’s going on there? In the first line, we’re adding 1 day to January 29th, which results in 2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. In the second example, we add 1 month first, where we get 2014-02-29, which adjusts down to 2014-02-28, and then add 1 day, which results in 2014-03-01. One design principle that helps in this case is that, in the presence of multiple ** Period**s, the operations will be ordered by the

**s’ types, not their value or positional order; this means**

`Period`

**will always be added first, then**

`Year`

**, then**

`Month`

**, etc. Hence the following does result in associativity and Just Works:**

`Week`

Tricky? Perhaps. What is an innocent ** Dates** user to do? The bottom line is to be aware that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected results, but otherwise, everything should work as expected. Thankfully, that’s pretty much the extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the “joys” of dealing with daylight savings, leap seconds, etc.).

As a bonus, all period arithmetic objects work directly with ranges:

**Fuzioni di regolarizzazione**

As convenient as date-period arithmetics are, often the kinds of calculations needed on dates take on a calendrical or temporal nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as “Memorial Day = Last Monday of May”, or “Thanksgiving = 4th Thursday of November” [e “la Fera ‘d Piobes = ters martes ‘d november”] . These kinds of temporal expressions deal with rules relative to the calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc.

The ** Dates** module provides the adjuster API through several convenient methods that aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal with the first and last of weeks, months, quarters, and years. They each take a single

**as input and return or adjust to the first or last of the desired period relative to the input.**

`TimeType`

The next two higher-order methods, ** tonext()**, and

**, generalize working with temporal expressions by taking a**

`toprev()`

**as first argument, along with a starting**

`DateFunction`

**. A**

`TimeType`

**is just a function, usually anonymous, that takes a single**

`DateFunction`

**as input and returns a**

`TimeType`

**, true indicating a satisfied adjustment criterion. For example:**

`Bool`

This is useful with the do-block syntax for more complex temporal expressions:

* Uh!* la Fera:

The ** Base.filter()** method can be used to obtain all valid dates/moments in a specified range:

Additional examples and tests are available in test/dates/adjusters.jl.

ðŸ¤¢

## Trackback

[…] da qui, copio […]