Skip to content
HomeVideosBooksBlogs
AllTop postsTopics
Podcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K
    P

    Paul Ganssle

    blog.ganssle.io · Personal blog · on HN since 2018

    Paul Ganssle, a Python core developer, writes about datetime and time zone handling, packaging and testing in Python.

    Visit blogHN submissions
    ProgrammingOpen Source & Linux
    What HN says

    Commenters cite his articles as clear explanations of why not to use utcnow and of naive local datetimes, and call the first one great.

    Stats for nerds
    22HN people shared it
    15linked in comments
    297story points
    Dec 2025last shared
    2019people per year2025

    Top posts on HN

    1. 1
      Stop using utcnow and utcfromtimestamp
      6 people · 145 points · first shared 2019 · 103 comments on HN
    2. 2
      You shouldn't invoke setup.py directly
      6 people · 140 points · first shared 2021 · 123 comments on HN
    3. 3
      Pytz: The Fastest Footgun in the West
      5 people · 4 points · first shared 2018 · Discussion on HN
    4. 4
      Xfail and Code Coverage
      1 person · 2 points · first shared 2021 · Discussion on HN
    5. 5
      A pseudo-TDD workflow using expected failures
      1 person · 2 points · first shared 2021 · Discussion on HN
    6. 6
      Subtests in Python
      1 person · 2 points · first shared 2022 · Discussion on HN
    7. 7
      Attractive Nuisances in Software Design
      1 person · 1 points · first shared 2023 · Discussion on HN
    8. 8
      Semantics of timezone-aware datetime arithmetic
      1 person · 1 points · first shared 2024 · 1 comments on HN
    9. 9
      Naive local datetimes
      2 people · first shared 2022

    What HN people wrote when they linked it

    • svatMay 2019

      It took me some effort to understand the issue here, so an alternative explanation in case it helps someone.

      First, the part that's independent of programming language. You may want to read about absolute time and civil time (e.g. from https://abseil.io/docs/cpp/guides/time) but if you don't, in short: “civil time” refers to something like “2019 May 26 at 2:45 pm in New York City” (or “in the America/New_York time zone”), which means (roughly) whatever time the locals in New York City (or a larger shared geo-political zone) would agree is 2:45 pm on that date. To convert this to an absolute time, or in other words to make sense of “2019-05-26 14:45 in America/New_York”, we need data about the real world as of that date: most obviously we need to know whether Daylight-Saving Time was in effect on that date, but also what conventions were in use at the time. (This also means it's hard to know for certain what such a notation in the future means in terms of absolute time, as possibly DST could be abolished or the dates when it comes into effect could change.)

      It so happens that in 1884 the conventions of New York City were such that it was about 4 minutes ahead of the then-recently standardized Eastern Time, so about 4 hours and 56 behind GMT.

      So, in any “correct” library, we should see the following respected:

      • “2019 May 26 at 2:45 pm in New York” should mean “2019 May 26 at 18:45 UTC” (timezone is EDT i.e. UTC minus 4 hours).

      • “2019 Jan 26 at 2:45 pm in New York”…

    • zahlmanDec 2025

      > Isn't assigning out what all made things fast presumptive without benchmarks?

      We also have the benchmark of "pip now vs. pip years ago". That has to be controlled for pip version and Python version, but the former hasn't seen a lot of changes that are relevant for most cases, as far as I can tell.

      > This also doesn't cover subtle things. Unsure if rkyv is being used to reduce the number of times that TOML is parsed but TOML parse times do show up in benchmarks in Cargo and Cargo/uv's TOML parser is much faster than Python's (note: Cargo team member, `toml` maintainer). I wish the TOML comparison page was still up and showed actual numbers to be able to point to.

      This is interesting in that I wouldn't expect that the typical resolution involves a particularly large quantity of TOML. A package installer really only needs to look at it at all when building from source, and part of what these standards have done for us is improve wheel coverage. (Other relevant PEPs here include 600 and its predecessors.) Although that has also largely been driven by education within the community, things like e.g. https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html and https://pradyunsg.me/blog/2022/12/31/wheels-are-faster-pure-python/ .

    • SomeoneMar 2025

      Clickable footnotes:

      [0]: https://pypi.org/project/stringcase

      [1]: https://pypistats.org/packages/stringcase

      [2]: https://pradyunsg.me/blog/2022/12/31/wheels-are-faster-pure-python

      [3]: https://github.com/pypa/setuptools/issues/4910

      [4]: https://github.com/zahlman/stringcase-new

      [5]: https://pypi.org/project/stringcase-new

      [6]: https://github.com/dmlls/python-casefy

      [7]: https://pypistats.org/packages/casefy

      [8]: https://peps.python.org/pep-0541/#how-to-request-a-name-transfer

      [9]: https://github.com/frictionlessdata/frictionless-py

      [10]: https://github.com/frictionlessdata/frictionless-py/pull/1727

      [11]: https://github.com/notatallshaw

      [12]: https://discuss.python.org/t/_/85847

      [13]: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html

    • mr_mitmSep 2022

      What do you mean? You type `pip install west` and a binary will appear in `~/.local/bin/west`. This directory needs to be part of your $PATH variable. Done.

      Using virtual envs or pipx or poetry or whatever are non-standard.

      Packaging Python projects, however, ... don't get me started on the whole `setup.py`, `setup.cfg`, `pyproject.toml` debacle. This article has more information about it, but the fact that this is supposed to be the short version makes it even more infuriating: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html

    • pganssleMay 2023

      Actually, naïve times are considered aware in the system time zone. There's no good way to create a `tzinfo` object that behaves like "the system time zone" and doesn't have unfortunate consequences. See this article: https://blog.ganssle.io/articles/2022/04/naive-local-datetimes.html

      It's not an ideal situation, but given path dependence I don't think it can be improved much from here.

    • dharmabNov 2021

      Poetry still uses setuptools! It makes it a lot easier for mortals. This is the blog post that convinced me to switch away from my old build system: https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html

    Related

    Nick Drozdnickdrozd.github.io25 people

    Signed Char Lotte

    Nick Drozd
    Personal · last shared 2026
    Jake VanderPlasjakevdp.github.io140 people

    Python Data Science Handbook

    Jake VanderPlas
    Personal · last shared 2026
    Paul Harrisonlogarithmic.net26 people

    Cats and Dogs - a one dimensional theory of character

    Paul Harrison
    Personal · last shared 2025
    Chris Warrickchriswarrick.com19 people

    Pipenv: promises a lot, delivers very little

    Chris Warrick
    Personal · last shared 2025
    PyPy Blogpypy.org183 people

    PyPy has moved to Git, GitHub

    PyPy Blog
    Company · last shared 2026
    Bite Codebitecode.dev54 people

    A year of uv: pros, cons, and should you migrate

    Bite Code
    Personal · last shared 2026
    Andrew Godwinaeracode.org68 people

    Hello, This Is London Rising: 3D Printing Maps from LIDAR Data

    Andrew Godwin
    Personal · last shared 2025
    The Morning Paperblog.acolyer.org606 people

    Local-first software: you own your data, in spite of the cloud

    The Morning Paper
    Personal · last shared 2026