<div dir="ltr">Rather than prolonging the debate, let me just reject PEP 500. If you want to use datetime objects just as containers, you can implement a bunch of functions that manipulate them the way you want.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 19, 2015 at 10:23 AM, Chris Barker <span dir="ltr"><<a href="mailto:chris.barker@noaa.gov" target="_blank">chris.barker@noaa.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>IIUC, PEP 500 essentially says essentially anything that datetime does can be delegated to a tzinfo object. Which reduces the datetime object to a simple container of a datetime stamp: </div><div><br></div><div>years, months, days, hours, min, sec, microsec.</div><div><br></div><div>As the current implementation has a way to add on tzinfo object, it is a way forward to make them all-powerful, to add arbitrary functionality without changing the way an existing code will work -- but it it the only or best way?</div><div><br></div><div><br></div>I think it would be very helpful (maybe only to me) to spell out the goals of PEP 500, so we can determine if they are goals we want to support, and if PEP 500 is the best way to support them:<div><br></div><div><br></div><div>I see a number of different goals, all crammed in:</div><div><br></div><div> - Support different Calendars : anything other than Proleptic Gregorian Calendar -- maybe include Lunar Calendars, etc???</div><div><br></div><div> - Support leap-seconds - this strikes me as essentially a slightly different Calendar -- aside from having to use an updated database, it's very similar to leap years.</div><div><br></div><div> - Support different time arithmetic -- "Duration" and "Period" arithmetic -- or "strict", or ????</div><div><br></div><div>I think it's a fine idea to open the door to support all these, but is PEP 500 the way to do it?</div><div><br></div><div>Anything else?</div><div><br></div><div>We now have a few particular objects to work with:</div><div><br></div><div>time</div><div>date</div><div>datetime</div><div>timedelta</div><div>tzinfo</div><div><br></div><div>These each have their own purpose and protocol  -- can we leverage that to support the above?</div><div><br></div><div>*tzinfo* essentially provides the offset to/from UTC time for a given timezone at a given datetime. PEP 495 adds a feature that completes the ability to fully support  this functionality -- why not keep that clean?</div><div><br></div><div>*timedelta* is essentially a way to encode a time duration -- microseconds. Useful and simple.</div><div><br></div><div>*datetime* encodes a timestamp, and provides an implementation of the proleptic gregorian calendar, so that it can convert differences between datetimes to "real" timespans -- i.e. timedeltas. Thus is can support subtracting datetimes, and adding timedeltas to a datetime.</div><div><br></div><div>OK -- so given all this (and Tim, please correct me where I have it wrong, -- I probably do), how best to support the goals above? (and, of course not break any existing code)</div><div><br></div><div>**Arithmetic:**</div><div><br></div><div>We've identified two "kinds" of arithmetic -- 'Duration' -- actual seconds, and "Period", timestamps are important -- i.e., "the next day, same time", etc...). Currently strict arithmetic is not supported by "aware" datetime objects, but neither is much in the way of Period Arithmetic.</div><div><br></div><div> -  *Period arithmetic*: As I understand it, this is pretty well supported by dateutils right now -- are the datetuitls maintainers asking for anything to make this better / easier??? Also, Period arithmetic requires all sorts of things other than simple addition and subtraction -- "Next Tuesday", "next business day", who knows what? so it seems overloading __add__ and __sub__ doesn't really buy much anyway.</div><div><br></div><div> - *Duration arithmetic*: I think this is the most useful thing to add -- currently, if you have tz-aware datetimes, you have to convert both to UTC, do the math, and convert back to the timezone you want. This isn't too painful, and is considered best practice by some folks anyway (actually, best practice is to convert to UTC on I/O, and always use UTC internally). But despite best practices, sometimes someone simply wants to do it in the time zone they are in. And I suspect there is code out there that does a simple subtraction, and it works fine if they haven't crosses a DST border, so they haven't found the bug.</div><div><br></div><div>  -- so how to add Duration arithmetic? Since this is currently handled by datetime, that seems like the obvious place to put it. Either with a subclass, or, my preference, with a attribute that tells you want kind of arithmetic you want, which would, of course, default to the current behavior. The trick here is that if one were to subtract two datetimes with the flag set differently, you'd have to decide which to respect -- but we could document which takes precedence. And this is the same problem as when you have two datetime with different tzinfo implementations.</div><div><br></div><div>  - There was talk of having multiple kinds time deltas, which might represent either Durations or Periods, but as timedelta only supports Periods that map precisely and unambiguously to a particular Duration, that would be a much bigger API change to do anything useful. And probably not be the way to go anyway, as mapping all the kinds of Period arithmetic you want to binary operations isn't practical.</div><div><br></div><div> - Also -- one could make a new datetime object that did the same thing as the current one, but stored the timestamp as a "time_span_since_an_epoch", to get better performance for Duration arithmetic, while sacrificing performance for pulling out the human-readable representation. I don't know that anyone would do that, but it would be a way to go, and I don't think would be do-able by delegating to the tzinfo object.</div><div><br></div><div><br></div><div>** Different Calendars **</div><div>So how to handle different Calendars? -- again, the Calendar implementation is in datetime now, so subclassing datetime makes the most sense to me. It could be subclassed to support leap seconds, for instance, and all the rest of  the machinery would work fine: timedeltas, time, tzinfo objects.</div><div><br></div><div>Also, if you want to get really far out, then lunar calendars, etc, aren't suited to the year, month, day system currently used by datetime, so you'd have to re-implement that anyway -- it couldn't be crammed into a tzinfo object -- at least without a lot of pain.</div><div><br></div><div>And implementing a new Calendar with a new duck-typed datetime object would require no changes to the std lib -- so nothing to argue about here :-)</div><div><br></div><div>So all this reduces to one maybe-proposal for the stdlib: add a flag to datetime specifying whether you want "Duration" Arithmetic, rather than the current "naive" arithmetic.</div><div><br></div><div>I know on this list at some point someone suggested that the "strict" flag go in the tzinfo object, but I can't see why it should be there, other than that we're messing with that object in PEP 495 already.</div><div><br></div><div>So, in short:</div><div><br></div><div>I don't think the The PEP 500 "delegate everything to tzinfo objects" approach is the way to go. Python already has subclassing, when you want different behaviour of an object. But in any case, if everyone else thinks it's the way to go, then it needs an explanation for why it's better than putting the new functionality in datetime subclasses, or duck-typed classes. Or, for that matter, what I think Guido is suggesting -- a totally different datetime module.</div><span class=""><div><br></div><div>-Chris</div><div><br></div><div><br></div><div class="gmail_extra">-- <br><div><br>Christopher Barker, Ph.D.<br>Oceanographer<br><br>Emergency Response Division<br>NOAA/NOS/OR&R            <a href="tel:%28206%29%20526-6959" value="+12065266959" target="_blank">(206) 526-6959</a>   voice<br>7600 Sand Point Way NE   <a href="tel:%28206%29%20526-6329" value="+12065266329" target="_blank">(206) 526-6329</a>   fax<br>Seattle, WA  98115       <a href="tel:%28206%29%20526-6317" value="+12065266317" target="_blank">(206) 526-6317</a>   main reception<br><br><a href="mailto:Chris.Barker@noaa.gov" target="_blank">Chris.Barker@noaa.gov</a></div>
</div></span></div>
<br>_______________________________________________<br>
Datetime-SIG mailing list<br>
<a href="mailto:Datetime-SIG@python.org">Datetime-SIG@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/datetime-sig" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/datetime-sig</a><br>
The PSF Code of Conduct applies to this mailing list: <a href="https://www.python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">https://www.python.org/psf/codeofconduct/</a><br></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>