Maya – Python Datetimes for Humans

  • Awesome! Timekeeping is hard and I'm glad we now have one more tool do deal with it.

    One thing that is bothering me is that when you ask for `maya.when('tomorrow')`, or give only a date, you get back a timestamp with millisecond precision, representing 00:00 of that day. I understand this simplifies the implementation, but shouldn't `tomorrow` be a range, from 00:00 to 23:59?

    Treating imprecise dates as ranges would allow for stuff like

        # Did this event happen "yesterday" according to the US/Eastern time zone?
        timestamp in maya.when('yesterday', to_timezone='US/Eastern')
    
        # Get me all events that happened last Friday (UTC)
        [event for event in events if event.time in maya.when('2016-12-16')]
    
    Maybe I'm being naive, and there's a reason why this won't work, but this seems the way most humans deal with time.

    PS: it failed to install on Windows, so I opened an issue at https://github.com/kennethreitz/maya/issues/10

  • I wish Kenneth would have contributed to an existed project for once.

    Arrow and pendulum (my current favorite) have a very decent API. The later one is especially well tested for the numerous corner cases of date handling, which I doubt Kenneth got right on first try.

    For request, a full rewrite made sense because urllib sucked so much and we had no good alternatives. But for date time, alternative exists and they are good. Do not split the open source effort, join forces!

  • I think its fascinating that the community has no consensus about a datetime library.

    A lot of Python is really solved. We don't argue about using requests (a not-coincidental example). If you're using Python, and you need to deal with http, you use requests. Everyone knows this.

    There are basically 3 platforms for web frameworks. Flask, Pyramid, and Django. Maybe we're a little more dissolute than C# or Ruby folks, but that's pretty impressive considering how much we Python people like to roll our own.

    The fact that there is real disagreement about this among ourselves about this particular issue says to me that this is more about the difficulty of the problem than it is anything else.

  • What's up buddy?

    My only real question:

    > rand_day = maya.when('2011-02-07', timezone='US/Eastern')

    This returning an object representing a DateTime on the 6th (in UTC time) strikes me as perhaps "not for humans."

    If I just see that line casually, I think I expect to get a Date and for it to be the 7th.

    It looks like, in order to get this (arguably expected) object, I need to take the resulting MayaDT epoch and run its `datetime` method, passing naive=True?

    And I also see that _tz can only ever be pytz.timezone('UTC') - is this the result of some belief that timezones are illusions or something? :-)

    For a while, I have kinda thought that timezones foment a confused mental model of time and teamwork. I prefer to think in terms of the astronomy - it's not actually a different time anywhere else, it's just that the sun is at a different position relative to the rest of the earth (and thus, ones faraway teammates and loved ones).

    Anyway, thanks for yet another set of interesting ideas. Hope you are well.

  • I wonder if the naming isn't a bit unfortunate, seeing that Maya is one of the major 3d packages out there and googling for Maya and Python will almost always lead there (also, not sure whether Autodesk might object...)

  • Not to undermine its merit, but most of the dirty work and heavy lifting is done by its dependencies:

    https://github.com/kennethreitz/maya/blob/d57a78c6bc6b5295f7...

    And i18n support in humanize is a bit lacking, as it only translates to French, Korean and Russian. Given that most of the translations needed to render human dates can be found in the CLDR database, maintaining their own looks like a bit of a wasted effort.

    Reference:

    http://cldr.unicode.org/

  • Kenneth Reitz is a testament to how important good interfaces are in the developer community. There are literally 0 interesting things in the code (all dependency driven, https://git.io/v15i3). It does have a nice interface and because of this it will probably become one of the more popular python datetime libs.

  • How does it differ from Arrow which was made several years ago? [1]

    [1] http://crsmithdev.com/arrow/

  • I have found that no matter what language/platform I use, the one thing that is always supported is UNIX timestamp. That makes date+time operations much easier:

      1) Whenever dealing with users, use local tz.
      2) Always save and manipulate in utc.

  • > Datetimes are a headache to deal with in Python, especially when dealing with timezones, especially when dealing with different machines with different locales.

    Anything with date/time calculations is always a pain, probably doesn't really have much to do with the library/language itself, but that the abstraction level that's used (and typically used in other libraries) means that the complexities of calendar and time systems are sprinkled all over application code.

    I do have to notice here that always using UTC is not always the right thing to do. For example, evaluating rrules in UTC is rather error-prone (DST).

  • I like Kenneth's work, but "I wrote a new datetime library" is a cliche now. We have datetime, dateutil, pytz, babel, arrow, pendulum, delorean, a bunch of lesser known stuff, and now this. I have yet to see the need for anything but the first four.

  • My first commit to ago.py was 'Fri Jun 29 19:25:55 2012'.

        >>> import ago
        >>> import dateutil
        >>> ago.human(dateutil.parser.parse('Fri Jun 29 19:25:55 2012'))
        '4 years, 172 days ago'
    
    
     The current implementation is 66 lines of code including docstrings:
    
    * https://bitbucket.org/russellballestrini/ago/src/tip/ago.py

    * https://pypi.python.org/pypi/ago

  • I'm competent with strptime(), but this looks really nice:

        # Automatically parse datetime strings and generate naive datetimes.
        >>> scraped = '2016-12-16 18:23:45.423992+00:00'
        >>> maya.parse(scraped).datetime(to_timezone='US/Eastern', naive=True)
        datetime.datetime(2016, 12, 16, 13, 23, 45, 423992)
    
    I'm happy not to have to write formatting arguments to strptime() anymore. Do the other datetime libraries have similar parsing functions?

  • I suppose this beats breaking out time delta, but I think it'll be hard for me to see an actual use in my projects that I couldn't accomplish with maybe just a couple extra lines

  • This is designed for programmers of user facing applications. For science and engineering, it does not address the problems, eg lack of leap seconds.

  • But does it get DST correct. I haven't found any python time libraries that do.

  • Bikeshedding. The Python "datetime" module does almost all of this. (Although I did try to get ISO8660 parsing put in, after finding eight libraries for it, all of which were broken in some way.)

  • People are asking why this is needed compared to Arrow and a few other libraries. Personally I was never happy using the python time libraries, it always felt like my use cases were slightly different then the library, and I always found myself getting frustrated over little things here and there. I think there are a LOT of use cases for time in python applications and there is plenty of room for small libraries to satisfy these conditions, versus one monolithic time library that attempts to solve all.

  • I understand the link with the maya believes but for a "digital" feature, this sound a lot like an Autodesk product... That said, nice API!

  •     <MayaDT epoch=1481850660.9>
    
    not the most human readable is it?

    I guess it would help with like, "X happened before Y" situations, but I don't think I'd trust my eyes for that!

    I think I would of preferred the "this happened in X month" case instead, I find it easier to trust my eyes for that, instead of trying to look for differing digits!

    - - -

    UTC default is a godsend though

  • [offtopic] I do not like the "for humans" thing. What could it be for instead? for kangaroos or giraffes?

  • Uh, Arrow? I'm not a big fan of it, really, as I've seen it to break silently on some edge cases API is not totally awesome, but this one doesn't seem to be any better. Still not sure if I should use this or that or write one of my own.

  • Hopefully we will have a "API for Humans" for each of the standard library modules.

  • The link to its github was posted on HN when it was brand new, and I left a comment [6], which I'm reproducing here -- since most of my points still apply.

    (...) take my very early comments with a grain of salt -- they refer to the progress as of this commit [1].

    I love Requests -- its API design is fantastic, and manages to distill down most of a complex problem domain to a clean, dare-I-say, elegant API. So I can eagerly anticipate this design applied to datetimes. But the progress being shown so far is definitely not it.

    >>> tomorrow = maya.when('tomorrow')

    <MayaDT epoch=1481919067.23>

    Why is "tomorrow" a precise-to-centisecond, infinitesimally small point on a giant cosmic timeline? I'm reasonably sure it's an abstract concept that describes the calendar day that starts after the current calendar day ends.

    At least, Pendulum normalizes tomorrow() and its ilk to represent midnight on the given day [2], while Delorean's natural language methods [3] like next_day() advance the day while leaving the time-of-day unchanged, but the method name makes this fairly clear.

    Even Arrow, which is heavily inspired by Moment.js to the point of conflating every single datetime idea into the same class, opts for mutators that are still more clear [4].

    > Timezones fit in here somewhere...

    Yeah, this needs more work.

    Java 8 / Threeten, and its predecessor Joda-Time took the approach of clearly modeling each and every concept that humans actually use to describe time; even if you take issue with their API, the designers have clearly done their homework, and their data model is solid.

    Formats like TOML wrestled with datetimes and realized [5] that datetimes aren't just woefully underspecified in most other specs and APIs, but that they're frequently mis-modeled, so they adopted large portions of Threeten's data model. Cases like this should merit strong consideration from anyone trying to propose new datetime APIs today.

    [1] https://github.com/kennethreitz/maya/commit/ecd0166ba215c1a5.... [2] https://pendulum.eustace.io/docs/#instantiation [3] http://delorean.readthedocs.io/en/latest/quickstart.html#nat.... [4] http://crsmithdev.com/arrow/#replace-shift [5] https://news.ycombinator.com/item?id=12364805 [6] https://news.ycombinator.com/item?id=13190314#13190657

  • i dont trust any piece of software that has all these made-up, unrelated, non-reflecting names. I mean come on, arrow, maya ? the main challenge about software engineering is correct naming. If you fail there you pretty much fail in the rest. Same goes for actually builtin name, "datetime". There is no such thing in real life as datetime. There is date and there is time. They are very separate notions and the root of the problem IMO is in trying to pile them together.

  • Yeah.. datetime is one of the rare part of the Python API that I really hate using. It's just badly designed, e.g. simple things are hard and confusing.

  • Slightly off topic:

    > Maya never panics, and always carrys a towel.

    Nice reference!

  • I don't understand the author's effort on solving this "problem"... I wonder if he considered at some point make a contribution to stable open-source existing libraries like arrow that even claim inspiration on one of his projects for the API. What's not for humans on the arrow API? what are the arguments for basically start yet another time library from scratch?, why is making a contribution not an option? probably the author of arrow will love your contributions and will love to hear the arguments on the changes you propose.

  • Kenneth: It would be really cool if you could put in support for TAI and MJD.

  • Great job, Mr. Reitz. I think I will use this in every project from now on. Thanks!

  • This is a joke. The whole "library" is 200 lines, has 9 tests, Kenneth probably wrote it in a couple of hours. It is totally not necessary, because, there are a gazillion datetime libraries and still, this is on the front page?

    Also:

        >>> dt = maya.now()
        >>> dt.datetime()
        datetime.datetime(2016, 12, 18, 19, 24, 50, 212663, tzinfo=<UTC>)
    
        >>> dt.datetime('Europe/Budapest')
        datetime.datetime(2016, 12, 18, 20, 24, 50, 212663, tzinfo=<UTC>)
    
    I would not use it...

  • why

  • It is heartbreaking to see such a contributor like Kenneth Reitz in conferences. I really enjoy using Kenneth Reitz's creation : I would like to see him smile.

    He is probably in the top 10% of the developers, he does not profit of his talent as much as an idiot that just code shit.

    When I sample over the vast majority of free software coder I know (100s) over the non free one (~same) and I compare the wealth/recognition I can't help but notice that for some of the 1% top FOSS devs you do have a breakthrough, but then, blind obedience seems to give more results in terms of social and wealth status.

    Something is rotten in the state of coding.

    My advice: don't make free software enjoy life, and close your ears to the voice of the voice of the crowd open them to the one you care about.

    And if you really want to make FOSS code, do it like others do knitting, pastry, moonshining, brewery.

    Keep the fun in your life.

  • Yet another library to handle dates in Python. Oh, boy... https://xkcd.com/927/

  • Python datetimes used with timezones, even UTC, are ridiculously slow and bloated. It's puzzling why this doesn't wrap np.datetime64 instead. Or wrap boost.datetime. There are many good options to claw some performance back so it's really head-scratch inducing that someone would recognize that stdlib datetime is a dog and then wrap it instead of scrapping it.