September 17, 2010 [phobos] next release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Schveighoffer | On Friday 17 September 2010 12:10:56 Steve Schveighoffer wrote:
> Ah, I see.
>
> Yes, in my implementation (on Tango), TimeSpan only dealt with up to days. It did not deal with years or months because those were calendar functions.
>
> Months are very tricky to deal with. For instance, if a date is 1/30, and one wants to add a month, what happens? You run into weird situations, and I left that awkwardness in another module. The Span type (Duration, whatever) I think should be calendar-free. This allows a very very simple implementation, and can be used in areas where you don't need the complexity of calendars (for instance, in thread.sleep).
>
> In the calendar class, I had addMonths and addYears (which essentially was
> addMonths(x * 12)) to deal with dates/times.
>
> > So, if
> > you want to be able to have durations of months or years, you have to
> > have at
> >
> > least 2 duration types - one which covers months and years and one which
> >
> >covers
> >
> > the smaller units (presumably by being in ticks as you suggest).
>
> No matter what solution you use, there will be some awkwardness. For example, if you wanted to determine how many months were between two dates, d1 and d2, how does that work? Intuitively, you'd do:
>
> d2 - d1
>
> But the type may not have enough information to convert to months. If you want to have a separate months/years type, then you need to have functions like monthsBetween(d1, d2) which returns a months type.
>
> I guess I will wait and see what the final API looks like and then see how I like it.
>
> -Steve
Well, obviously, it'll be clearer once you see the code, but I have addX() functions for all of the time units which make sense for any given time point as well as the ability to add Durations to them (as well as a generic addTimeUnit() where you give it the unit to add to - Durations actually use that when being added to a a time point). addMonths() and addYears() allow you to choose how you want to deal with the day overflowing the month after adding however many months or years you added: whether it should overflow into the next month, incrementing the month, or whether it should snap to the end of the current month. Adding Durations always overflows.
As for subtracting two time points, the result is always a Duration in the highest precision units for that type - so subtracting Dates would result in a Duration!(TUnit.day) while subtracting SysTimes would result in Duration! (TUnit.tick). Additional functions could be added for stuff like monthsBetween(), but I haven't at this point. It does seem like it would be a good idea though, since you couldn't get the number of months between Dates from a Duration! (TUnit.day).
In any case, dealing with months is ugly all around because they aren't uniform. What I have is highly generic so that each of the various time points work in the same way, but months are a bit of a wart. Hopefully my solution isn't too far off from ideal. But obviously, everyone can judge that for themselves when I post the finished code.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation