[HN Gopher] datetime.utcnow() is now deprecated
___________________________________________________________________
datetime.utcnow() is now deprecated
Author : Brajeshwar
Score : 197 points
Date : 2023-11-19 14:49 UTC (8 hours ago)
(HTM) web link (blog.miguelgrinberg.com)
(TXT) w3m dump (blog.miguelgrinberg.com)
| Belphemur wrote:
| They should have gone further like .NET 8.0 with a full class
| abstraction for datetime provider:
| https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotn...
|
| This is 10x better and helps to assure the code can be unit
| tested with providing the exact date we want in the exact
| format/timezone
| lallysingh wrote:
| That's a lot of complexity. How's that better than requiring an
| arg with the timezone?
| rjbwork wrote:
| Because you can now fully simulate arbitrary times during
| testing by providing your own implementation of the time
| provider. If you just take in a timezone as an argument, how
| will you simulate it being 2041-08-23T21:17:05.023743Z?
| SpaghettiCthulu wrote:
| Uh, just assign your mock function to `<insert name here>`?
| Python is really the wrong language to be complaining about
| a lack of mockability.
| rjbwork wrote:
| True. When you can just make any function be whatever you
| want whenever you want that sort of abstraction does seem
| a big much. I was responding to the specific question in
| reference to the time provider in .net 8.
| talboren wrote:
| Paul Ganssle released a great article[1] explaining why you
| shouldn't use utcnow in 2019.
|
| [1] https://blog.ganssle.io/articles/2019/11/utcnow.html
| m12k wrote:
| Time handling seems like one of those cases where a type system
| could really come to the rescue - times with and without time
| zones in them shouldn't be the same type, and using one in a
| place where the other is expected should ideally just give you a
| compile error.
| vore wrote:
| Timezoneless time I think is just a mistake in general - all
| times inherently have some timezone, even if the timezone is
| UTC.
| IggleSniggle wrote:
| All timestamps even have a position in space that will
| experience discrepancies relative to all other timestamps,
| even if they are UTC, we just usually don't care about it
| that much.
|
| Since our time is at least all Earth-based, we could do even
| better than timezone and make timestamps have a lat/long
| attached for the place in which it was produced. Maybe a
| linked list for any timestamps that are calculated from that
| based type.
|
| Are we having fun yet?
| vore wrote:
| The social solution is to abolish timezones (mine is of
| course objectively the right one, other people must deal
| with breakfast at 9pm wherever they are).
| 0cf8612b2e1e wrote:
| I need a null value for when the timezone is unknown. If a
| user enters 9:30, they do not want to be bothered with
| specifying a timezone if they keep everything local to their
| life.
| WirelessGigabit wrote:
| I disagree.
|
| If we have a call at 9:30 and you drive to the next state
| now that call is at 10:30 or 8:30 for you.
|
| If you set 9:30 as an alarm to feed your cat every day,
| fine.
| rileymat2 wrote:
| If that is the case, can't the UI encode the timezone for
| the user, whether they want to be bothered or not?
| 0cf8612b2e1e wrote:
| Right now, I am dealing with this problem that I have
| historical data recorded in Eastern and Mountain Time.
| Everything is local and nary a timezone in sight. Data
| files are mixed, and no obvious way to determine
| provenance.
|
| I cannot just guess what timezone these data points were
| collected, so I have to suffice for local time. Which is
| 100% fine for the users, because that's exactly how they
| think about the problem. There are probably no global
| events against which they need to sync, just interested
| in the relative differences between events.
| rileymat2 wrote:
| It may not matter, but without UTC and offsets, you can't
| get relative differences between all events accurately
| because of DST. But it may not matter for your use case.
| bobbylarrybobby wrote:
| But UTC "times" aren't times at all. They're durations (since
| midnight Jan 1, 1970 in Greenwich), so they don't need a time
| zone.
| Hamuko wrote:
| Are you thinking of Unix time?
| SpaghettiCthulu wrote:
| Well then maybe they should store the epoch alongside the
| duration value too! Wouldn't want to get confused thinking
| it was duration since some other epoch!
| gcbirzan wrote:
| They don't, not always. I want to wake up at 7am every
| morning, regardless of where I am.
| vore wrote:
| That's true!
| garblegarble wrote:
| Here are two counter examples that sprang to mind:
|
| 1. I've set my alarm for 8am local time every day. I don't
| want my alarm clock to go off at 3am just because I'm in a
| different country
|
| 2. If I have an appointment at 10am next November, that's
| actually a datetime with a locale (given that my appointment
| is at 10am local time, no matter whether the DST rules change
| between now and then).
| marcosdumay wrote:
| Well, you'll need another type meaning "local time" for #1.
| That's not a time without time zone, it's an entirely
| different thing.
|
| Most environments simply can't represent that thing. They
| never could. With those changes this becomes more obvious,
| and with some luck people will finally fix this.
|
| (The most absurd case is the "timestamp with local time
| zone" from SQL, that reads exactly like what you want, but
| represents a timestamp in a specific time zone, that is
| discoverable but mostly unknown.)
| int_19h wrote:
| "8AM local time" is exactly time without a timezone. It's
| not _date_ time without timezone, but that's a different
| question.
| wayfinder wrote:
| 1. That isn't date data. That's just storing a local time.
|
| 2. That's why you WANT time zones in this example. It will
| automatically stay at 10am instead of bouncing around when
| DST rules change.
|
| I've never ever needed timezone-less dates. Even using UTC
| or timestamps, it's still UTC.
|
| A date without a time zone is like "10 inches" but without
| the inches so it's just "10". Absolutely meaningless. You
| start moving just "10" around without the units in your
| code and then your Mars Orbiter explodes.
| ndriscoll wrote:
| Christmas is on December 25. It is not on December 25
| UTC, or any other particular time zone.
| wayfinder wrote:
| That's not a date-time though. You would not store that
| using the same type-compatible objects as your regular
| date-times or that's how you end up one day blowing up a
| Mars Orbiter.
| ndriscoll wrote:
| Yes, you need both zoned and zoneless versions of dates
| and times. This is why e.g. java.time has both (and it
| has LocalDateTime for when you need to say Santa delivers
| presents at 00:00 on December 25).
|
| Zoneless time is not a mistake. Using it when you meant
| to use a zoned time is.
| int_19h wrote:
| Making it easier to use zoneless over zoned is a mistake,
| though. An even more grave one is making zoneless the
| default. Unfortunately, that's a mistake that we've made
| decades ago, and now we have to fix it in a way that
| deals with all the accumulated mess.
|
| Really, though, this is a recurring lesson in software
| engineering: don't be in a rush to make something a
| default just because it's "obvious"; explicit is better
| than implicit. Strings are another example; we've treated
| them as arrays of characters for so long that it's still
| a common default semantics for indexing a string, except
| now what you often get instead is UTF-8 or UTF-16 code
| units rather than actual code points. All of which is
| likely not what you actually need - but what you do need
| depends so much on the task that it should _always_ be
| explicit.
| wayfinder wrote:
| You do.
|
| Python does not. It's all one object and I think that was
| a terrible idea.
| onetoo wrote:
| Christmas is on December 24 where I'm from.
| ndriscoll wrote:
| Which days are recognized by an administrative region as
| holidays is an orthogonal concern from timezones. e.g.
| the US recognizes the 25th but spans multiple timezones.
| garblegarble wrote:
| >2. That's why you WANT time zones in this example. It
| will automatically stay at 10am instead of bouncing
| around when DST rules change.
|
| Respectfully, no - in my scenario, if I used a timezone
| then I would show up at the wrong time for my
| appointment: each locale that observes DST has two
| timezones: one for DST, one for non-DST (e.g. BST and GMT
| for the UK). If I record a 10am appointment as "10am BST"
| and my country changes the rules on daylight savings
| transition date between now and the appointment, then I
| will show up at the wrong time for my appointment.
| Whereas if my appointment is recorded as "10am
| Europe/London" then it's encoding the human reality of my
| appointment, and can be correctly converted to an Instant
| in time if the rules change.
|
| It sounds to me from your reply that you are mentally
| modelling all datetimes as Instants. These are one key
| aspect of dates+times (and often all a lot of software
| needs - since it's usually referring to some point in
| time that has already passed, or a future point in time
| that is x seconds from some other Instant), but Instants
| don't cover everything required when working with dates
| and times.
|
| >I've never ever needed timezone-less dates. Even using
| UTC or timestamps, it's still UTC.
|
| Try sketching out the design for a calendar application
| and I bet you'll very quickly run into a whole raft of
| datetime related logic you might never otherwise
| encounter. Think particularly about future events: some
| are fixed instants in time (e.g. a meeting with people
| across timezones), others aren't (e.g. a dentist
| appointment in your city - my second example above is an
| instance where the local time of the appointment is
| relevant, not the Instant in time that local time
| referred to when the appointment was made). How do you
| represent recurring events?
| wayfinder wrote:
| For the classes of problems that you mention, I consider
| them as separate data types entirely and they shouldn't
| ever touch your timezone-aware date-times objects. They
| should be stored as a composite types of your date, maybe
| time, and target timezone.
|
| If you can mix timezone-aware objects with non-timezone
| aware objects like you do in Python, it's get pretty
| dangerous because people will just mix them willy nilly
| and add and subtract the timezone-aware parts and then
| you get some really subtle date/time bugs.
|
| That's why I believe either a date-time MUST have a
| timezone and for other cases, you need a specialty data
| type for your domain, possibly provided by your date/time
| library.
| magnio wrote:
| > 1. I've set my alarm for 8am local time every day. I
| don't want my alarm clock to go off at 3am just because I'm
| in a different country
|
| Without timezone, your clock would actually go off in the
| middle of the night when you are in a different country.
| Your clock does not know you change location (no timezone,
| no location-dependent time), so it will alarm you after
| exactly 24 hours since the last alarm, which, in another
| country, can be midnight.
|
| > 2. If I have an appointment at 10am next November, that's
| actually a datetime with a locale (given that my
| appointment is at 10am local time, no matter whether the
| DST rules change between now and then).
|
| If everyone is staying in your city, then that works great
| (sans catastrophic continental riff or meteorite strike).
| When at any point you involve more than one geographic
| location, then the appointment is meaningless without
| timezones.
|
| Now, maybe it is actually the case that you and your
| software only care about one geographic location in
| perpetuity, but just like assuming 32-bit IP addresses,
| 8-bit ASCII, and length-oblivious arrays are all you need,
| the teeth marks from its consequential bite tend to be
| quite deep and sanguine.
| thaumasiotes wrote:
| > Without timezone, your clock would actually go off in
| the middle of the night when you are in a different
| country. Your clock does not know you change location
|
| This does not describe any modern person's experience.
| Your clock is connected to the internet; it always knows
| the local time.
| ndriscoll wrote:
| You're missing the point. Evaluating the rule requires a
| timezone, but the rule itself is not defined with
| reference to a specific timezone (well, the second one is
| assuming you can use something like PT that changes
| between PST and PDT throughout the year). To define the
| first rule requires a zoneless time.
| remram wrote:
| > Without timezone, your clock would actually go off in
| the middle of the night when you are in a different
| country
|
| Your clock would do what your clock is programmed to do.
| What a weird statement to make about a _completely
| hypothetical_ tool.
| magicalhippo wrote:
| I think ISO 8601 made a big mistake by allowing timezone-
| less representation[1]. They should have used L for local
| time so it's explicit, and not allowed any timezone-less
| representation.
|
| Sure it's technically well-defined as it is, but I think
| it's too important not to be written out.
|
| In that case you can represent your alarm either as 08:00L
| if you want to wake up in the morning regardless of where
| you travel, or 08:00-02 for those cases where you need to
| stay in sync with home say.
|
| [1]: https://en.wikipedia.org/wiki/ISO_8601#Local_time_(unq
| ualifi...
| crote wrote:
| I completely disagree, the local time is the _only_
| useful part of ISO 8601.
|
| The big problem here is that it does not use timezones,
| but _UTC offsets_. Timezones can and do change their UTC
| offsets, completely breaking all future timestamps saved
| in ISO 8601-with- "timezones". "08:00 UTC-02" is
| ambiguous, "08:00 America/Nuuk" is not.
| asddubs wrote:
| 1 could be better served by an integer representing the
| minute it should go off anyway, since there is no specific
| date attached
|
| 2 time zones account for DST so that point is moot, but in
| the context of traveling and still wanting to maintain the
| same times this is actually something calendar apps often
| get wrong
| jes5199 wrote:
| OK, you've convinced me that having a naive datetime object
| available makes sense
|
| but are there any cases where "now" being naive is useful
| garblegarble wrote:
| No, I can't think of any case where that would be useful
| (although I do take umbrage with a local datetime being
| referred to as a 'naive' type - it serves a very specific
| purpose as a primitive... if it's naive then so is an
| int, since it does not specify a unit).
|
| I don't know anything about Python's datetime handling
| (other then to be alarmed by it given what I've seen in
| this thread). I live in the Java world where the
| java.time library is one of the best around (after a
| decade or more of Java having one of the worst date time
| libraries)
| notatoad wrote:
| datetime with locale is how timezones are represented in
| python. What you're asking for there is a datetime with a
| timezone, not a datetime without a timezone.
| eieio wrote:
| At my last job we had types for a `Time.t` (time + date +
| timezone), a `Date.t` (just a day of the year), and a
| `Time.Ofday.t` (a time of the day with no timezone or date
| attached - like 8:00 AM).
|
| This worked really well! You represent (1) with a
| `Time.Ofday.t`. I suppose if you wanted you could represent
| (2) with a `Time.Ofday.t` + a `Date.t`, although it kinda
| seems to me like you want to keep timezone information
| around if you're dealing with DST changes.
| ndriscoll wrote:
| When is Christmas?
| happytoexplain wrote:
| "8am" is a time that inherently has no timezone, and yet we
| need it. It's not that we don't need timezoneless time - we
| just need to stop using timezoneless time to represent times
| with a time zone and vice versa. Most time APIs were simply
| designed wrong on purpose for "simplicity".
| frou_dh wrote:
| Reminds me of trying Scala and a library where not only were
| paths a type rather than primitive strings (good, like pathlib
| in Python), but absolute and relative paths were actually
| different types.
|
| I think this was it: https://github.com/com-lihaoyi/os-lib
| usrusr wrote:
| The way you put it makes it appear very surprising that time is
| not the extended hello world of type systems. Maybe it's
| because no environment has ever arrived at an implementation
| they are actually happy with, before fizzing out at "good
| enough"? It's clearly a topic where we tend to prefer something
| rough but shared over something better but custom, so the "good
| enough" is powerful.
| jepler wrote:
| It's funny you should say this.
|
| Reading this article prompted me to future-proof a program I
| maintain for fun that deals with time; it had one use of
| utcnow, which I fixed.
|
| And then I tripped over a runtime type problem in an unrelated
| area of the code, despite the code being green under "mypy
| --strict". (and "100% coverage" from tests, except this
| particular exception only occured in a "# pragma: no-cover"
| codepath so it wasn't actually covered)
|
| It turns out that because of some core decisions about how
| datetime objects work, `datetime.date.today() <
| datetime.datetime.now()` type-checks but gives a TypeError at
| runtime. Oops. (cause discussed at length in
| https://github.com/python/mypy/issues/9015 but without action
| for 3 years)
|
| One solution is apparently to use `datetype` for type
| annotations (while continuing to use `datetime` objects at
| runtime): https://github.com/glyph/DateType
| MaulingMonkey wrote:
| Rust's `time` crate does have separate types for these:
| https://docs.rs/time/latest/time/struct.OffsetDateTime.html
| https://docs.rs/time/latest/time/struct.PrimitiveDateTime.html
|
| It's not as helpful as you'd think IME - timezoneless date
| times are suprisingly niche (at least as a useful tool to
| intentionally choose, rather than an accidental side effect of
| API choice.)
| amelius wrote:
| The whole concept is broken anyway, if you look at relativistic
| scales. Good luck running Python code inside a GPS receiver.
| vegabook wrote:
| I suspect a lot of financial data code is going to break. I've
| worked on a number of codebases where the explicit instructions
| were "everything is UTC, all the time", and enforced at the entry
| edges of the code. Bringing in timezones was a definite NO for
| reasons of the unholy mess this would inevitably create:
|
| * India has half-hour timezones
|
| * Countries change their DST rules all the time.
|
| * Conversion between timezones is an utter mess.
|
| As Wes McKinney once said about python datetime: "Welcome to
| Hell"[0]
|
| [0] https://stackoverflow.com/a/13753918
| Spivak wrote:
| You still keep everything in UTC in this new world, it's just
| the object you use internally now knows that it's UTC and makes
| it so you can't accidentally do calculations on two naive
| datetimes which happen to be in different timezones.
|
| You get to have the typing help you enforce that everything is
| in UTC.
| konschubert wrote:
| And you have to treat the timezone offset as information-
| free.
|
| As in, 02:00+00:00 and 04:00+02:00 are absolutely equivalent
| representations of the same data.
|
| If you need to know the timezone in which to display a time,
| you save that timezone separately
| plibither8 wrote:
| > India has half-hour timezones
|
| If that's messy, consider Nepal's timezone that's on the
| 45-minute mark (UTC+5:45).
| hprotagonist wrote:
| or one island of new zealand (chatham), which is +12:45
| angrygoat wrote:
| or along the highway near the Western Australia/South
| Australia border, which informally uses +8:45
| https://en.wikipedia.org/wiki/UTC%2B08:45
| qwertox wrote:
| Same for Nepal, UTC+05:45
|
| https://en.wikipedia.org/wiki/List_of_UTC_offsets
| Izkata wrote:
| RealLifeLore just had a video about time zones in that area
| of the world, there's an area between New Zealand and
| Hawaii where you can go north/south and jump an entire day.
| slyall wrote:
| The Chatham Islands are an Island group, two of which are
| inhabited (Chatham Island and Pitt Island).
|
| https://en.wikipedia.org/wiki/Chatham_Islands
|
| Right now is it on +13:45 due to Daylight Saving
|
| https://en.wikipedia.org/wiki/Chatham_Standard_Time_Zone
| PartiallyTyped wrote:
| Why is humanity like this?
| hn72774 wrote:
| It's mostly political.
|
| There isn't a perfect geographical width for time zones. So
| humans pick something to define the boundaries between time
| zones. And making boundaries on a map is political.
| JJMcJ wrote:
| To some extent a compromise between solar time and
| political and economic realities. For example, the
| Eastern Time Zone in the USA stretches almost to 90
| degrees West, reflecting the East Coast's powerful pull
| on that part of the country.
| WorldMaker wrote:
| A lot of it was GE's fault at the time, specifically. GE
| wanted facilities in New York, Cincinnati (OH), and
| Louisville (KY), among others, to all be in the same time
| zone and had the economic power at the time to lobby the
| railroads and the cities to make that happen.
| bandrami wrote:
| In this case it was so the Sun would be roughly due south
| at noon in Delhi
| djbusby wrote:
| Doesn't that depend on the day of year too?
| bandrami wrote:
| That far south it only varies by a couple of degrees. It
| does wreak astronomical havoc in Mumbai, though, where
| the Sun will sometimes be way in the northeast at noon.
| svilen_dobrev wrote:
| because humanity never understood time properly.. so all
| these facades making it look "simpler" while actualy a lot
| more complicated.
|
| long time ago there was a special `$ man date` -like page
| in linux which went into long explaining many "amazing"
| things about calendar stuff, like whoever feudal in 1553
| deciding that certain week was bad and striked it out of
| his _and his country 's_ calendar, or another one that
| liked certain month and decided to repeat it...
|
| but cannot find it anymore.
| inglor_cz wrote:
| In Europe, a huge driver for standardization of timezones
| into "reasonable" slots was railway traffic, including
| cross-border traffic.
|
| Railways are extremely sensitive to exact time and, indeed,
| the very concept of unified time across the entire region
| or country only started developing when railways expanded
| across Europe. Prior to that, individual towns were happy
| with their own local solar time, but once railway
| connections were introduced, time irregularities would
| cause chaos at best and carnage at worst. That led to
| introduction of unified railway time which developed to
| timezones as we know them.
|
| Railways aren't as prominent nowadays as they were 100-150
| years ago, and countries like Nepal and India don't have
| extensive, frequently used cross-border railways anyway;
| any cross-border traffic is sporadic and mostly freight. So
| there is one fewer reason to cooperate with your neighbors
| when it comes to time-related issues. Trucks can take weird
| timezone changes just fine.
| BurningFrog wrote:
| Train scheduling was sorry the reason for timezones in
| the US.
|
| Now that the original cause is gone, maybe we can get
| some new concept going. Timezones seen more terrible than
| they're worth to me.
| poink wrote:
| Last startup I worked for hired a Nepal-based QA person.
| There was a bunch of calendaring and daily/weekly charts in
| the apps, and she found bugs in _everything_.
|
| I make sure to test with Nepal time whenever I'm testing
| date/time stuff now.
| iso8859-1 wrote:
| Even better, use Monrovia in the 70s. They had an offset of
| 44m30s.[0] >>> datetime(1972,1,1,tzinfo=Z
| oneInfo('Africa/Monrovia')).isoformat()
| '1972-01-01T00:00:00-00:44:30'
|
| [0]: https://en.wikipedia.org/wiki/Time_in_Liberia#History
| lb1lf wrote:
| And, of course, there's the (hopefully apocryphal) story of
| the French initially referring to GMT as 'Paris time minus
| nine minutes and twenty-one seconds'.
| LegionMammal978 wrote:
| As it happens, this story isn't apocryphal at all! One
| can readily find the original law, which was enacted on
| March 9, 1911, and published in the _Journal officiel_ of
| March 10, 1911 [0]:
|
| > _Article unique._ -- L 'heure legale en France et en
| Algerie est l'heure, temps moyen de Paris, retardee de
| neuf minutes vingt et une secondes.
|
| The decree which finally replaced it was made on August
| 9, 1978, and published on August 19, 1978 [1]:
|
| > Art. 2. -- Sur l'ensemble du territoire de la
| Republique francaise, le temps legal (ou heure legale)
| est defini a partir du temps universel coordonne (UTC)
| etabli par le bureau international de l'heure.
|
| [0]
| https://gallica.bnf.fr/ark:/12148/bpt6k2022333z/f2.item
|
| [1] https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000000
| 880128
| midasuni wrote:
| When I built a live clock for some new CasparCG based
| graphics for a major TV program out of singapore some years
| back, a colleague reviewing it in London tried to trick it
| with a Nepal offset -- apparently they'd run into an issue
| with the Viz system they used in 2015 when there were a lot
| of lives from Nepal.
|
| Obviously it worked fine, as did Chatham Island.
| foolswisdom wrote:
| And don't forget about
| https://www.zainrizvi.io/blog/falsehoods-programmers-
| believe...
| Hamuko wrote:
| I'd say that wouldn't enforcement be rather simple going
| forwards since you could just enforce that dt.tzinfo ==
| datetime.timezone.utc, but as far as I know, timezone
| information checking in Python can be a bit of a pain.
| >>> utc1 = datetime.timezone.utc >>> utc2 =
| zoneinfo.ZoneInfo("UTC") >>> utc1 == utc2 False
| >>> dt1 = datetime.datetime.now(utc1) >>> dt2 =
| datetime.datetime.now(utc2) >>> dt1.tzinfo == dt2.tzinfo
| False
| Buttons840 wrote:
| How do you express "our stores, across 6 different timezones,
| all open at 9:30 AM local time" in UTC?
| pelorat wrote:
| you don't, since they are different times?
| sillysaurusx wrote:
| That code runs in the context of humans. Therefore it needs
| to take humans into account when running.
|
| This is a bit like asking "how do you represent a string
| length in utf-8?" The answer is, you don't. It's almost never
| a problem in practice.
|
| Just like there is almost never a reason to care about the
| number of characters in a string, it's very difficult to
| imagine that this code comes up in practice. But if it did,
| the code is simple: for a given timezone, is the current time
| in utc past 9:30am? If so, the store is open.
| Buttons840 wrote:
| Let's say you host a store front for many businesses and
| it's decided that your customers, who are businesses, some
| with many stores, want to store a default opening time.
| Something along the lines of "All Home Depot's open a 6 AM,
| all Lowes open at 7 AM."
| wayfinder wrote:
| That's not date data though. That's just storing local
| time - 6 AM or 7 AM.
| sillysaurusx wrote:
| The store property would be "6 AM". Anywhere it's used,
| it's running in the context of humans. When displaying on
| a website, you don't need to do any conversions: the
| human viewing the store knows where it's located, and
| they know the current time, so computers don't need to
| answer the question of whether it's open.
|
| If computers do need to know, then they'll need to know a
| specific store with a physical location. That gives you
| the time zone.
| macintux wrote:
| > If computers do need to know, then they'll need to know
| a specific store with a physical location. That gives you
| the time zone.
|
| Mapping a location to a time zone seems fraught with
| peril. I'd store the local time zone explicitly.
| amluto wrote:
| Indeed. And anyone near a time zone boundary looking at
| an online map of store locations doesn't want to see
| "opens at 6AM" or whatever -- they want to know whether
| the store is open.
| JJMcJ wrote:
| Indeed. It's not as bad as mapping address => sales tax
| (no ZIP Code isn't good enough), but only because it
| doesn't change as often and tends to follow county
| boundaries when it doesn't follow state boundaries.
|
| Another good example. Arizona doesn't follow Daylight
| Savings, but the Navajo Nation, which includes the Four
| Corners area and is in three states, does observe the
| change.
|
| However the Hopi reservation, completely surrounded by
| Navajo territory, is entirely in Arizona, and does not
| observe DST. So it can get quite complicated and it's not
| enough to say "Arizona doesn't have Daylight Savings
| Time".
| efdee wrote:
| There's no time zones involved in that at all. Nobody is
| going to be checking the opening hours of a Home Depot in
| another timezone and expect to get the date in their
| local timezone.
| blincoln wrote:
| > Nobody is going to be checking the opening hours of a
| Home Depot in another timezone and expect to get the date
| in their local timezone.
|
| You've never wanted to call a business in another
| timezone before making the trip out there?
| Wowfunhappy wrote:
| ...I can see this use case.
|
| However, if I look up the opening time of a Home Depot in
| another time zone, I _expect_ the result to be in that
| store 's local time! I'll do the conversion myself. If I
| get my local time instead, I'll still perform the
| conversion, and get the wrong result.
|
| You could just decide that any time listed anywhere on
| the internet should include a timezone... but that would
| be nuts.
| joshspankit wrote:
| If someone expresses it that way it will be a huge hassle the
| moment they decide one store opens at a different time.
| Buttons840 wrote:
| So maybe individual stores can customize their opening
| time, but corporate still wishes to store a default. How do
| you represent the default? How do you handle the DST time
| changes for individual stores?
|
| I'm trying to poke holes in the "always use UTC and you're
| good" advice. I have actually encountered this scenario,
| and I didn't know how to apply that advice.
| bpfrh wrote:
| I don't get your problem, couldn't you store it like
| this: table timetable:
|
| open | close | store 6am | 6am | default 7am | 12pm |
| store1
|
| table stores: name | address store1 | xyx NYC
|
| If you can't find the store in the timetable:
|
| 1. Get the timezone of the target store by looking up the
| address from the table stores
|
| 2. Set Hours from the default row in the timetable table
| on the object with the timezone
| Izkata wrote:
| > I'm trying to poke holes in the "always use UTC and
| you're good" advice.
|
| There's a much simpler one - recurring meetings/events
| (in-person or local-ish like within one country) that
| cross a DST boundary. You always want these to be
| attached to a local time zone, so it doesn't suddenly
| happen an hour earlier/later than you intended.
| fragmede wrote:
| Where that gets even more fun is with international
| meetings, where the host of the meeting and the attendees
| are in different zones.
| bofaGuy wrote:
| Not sure if this is a serious question.
|
| Each store will have an opening time, each will store the
| local time that the store opens.. just as utc.
| d0mine wrote:
| utc is for a specific moment in time (deterministic with
| great precision for everyday use).
|
| "9:30am local time" may be ambiguous/unknown (the rules may
| not exist yet)
|
| Using the same programming type for both may cause confusion.
|
| How do you express geographic coordinates? Noon in London and
| in NY are different moments in time (it may be important if
| you want to have a remote meeting).
| samus wrote:
| No need for something as brittle as geographic coordinates
| or addresses. Time Zone _names_ are the right abstraction.
| A given location very rarely [edit: adopts another] time
| zone (unless in case of annexations, handovers of
| territory, etc.), but time zone _rules_ (zone offset from
| UTC, DST, etc.) change all the time. A consequence of this
| is that the time zone database of applications should be
| updated every few months!
| d0mine wrote:
| "brittle" ?
|
| Your suggestion to define places by their timezone name
| is ok (it may work in many cases).
| Footkerchief wrote:
| Postgres stores this as TIMESTAMP WITHOUT TIME ZONE,
| sometimes called wall-clock time. IMO this is a good
| convention -- treating "ideal times" and specific epoch
| moments as two different types -- and more languages should
| support this (ideally with a less confusing label).
| dumah wrote:
| Tuples of the local time zone (not utc offset) and a time,
| along with a utc localization conditional on date.
| JJMcJ wrote:
| Reference opening time to local time on each day of the year,
| and then refer that back to UTC.
|
| Like California is -8 in Standard, -7 in Daylight, so a 9:30
| AM opening in the Winter is at 17:30 UTC, in the Summer,
| 16:30 UTC.
|
| It's a hassle but programmers are supposed to model reality.
|
| As an example of the problems that can arise, I remember when
| the new Japanese Emperor was to take office upon his father's
| abdication, there was a big fuss because the Era Name was
| customarily only revealed after the new Emperor's reign
| started but all the computer people wanted to be ready in
| advance. Not sure what finally happened, if it was revealed
| in advance or not.
| konschubert wrote:
| store_opening_hour_and_minute_of_day=(9,0)
|
| It's not a date time.
| remram wrote:
| "9:30 AM every day" is not a datetime. It's a time.
| maxerickson wrote:
| They aren't being removed, they will just toss up a warning.
| tripflag wrote:
| The warning is also opt-in; you'll have to run python with
| PYTHONWARNINGS=always or similar to see it.
|
| Which is scary, because you will be taking the performance
| hit from generating the warning regardless, which can easily
| amount to 30% of your total CPU time if you use
| utcnow/utcfromtimestamp a lot.
| tumult wrote:
| They will be removed: datetime.datetime's
| utcnow() and utcfromtimestamp() are deprecated and will be
| removed in a future version.
| jagged-chisel wrote:
| Aren't now, "will be" in a future version. So the can will
| be kicked down the road as many generations of devs as
| needed until no one cares any longer.
| tumult wrote:
| So, they remove it in 12 months and your code wasn't
| ready for the change, and people mock you for having not
| been prepared by updating your code. The Python people
| have told you to remove it, so nobody will have any
| sympathy for you if you don't do it. As you demonstrated,
| people are sticklers for quoting exact wording when it
| comes to criticizing others.
| jagged-chisel wrote:
| I'm not criticizing. This wording is chosen for this
| exact reason. Otherwise they would say precisely when
| they intend to remove it.
| thaumasiotes wrote:
| Stupid decisions don't always get put into practice after
| they're announced.
|
| I seem to remember reading that remove-if-not is deprecated
| in Common Lisp, and that this is almost universally viewed
| as a mistake, but it remains deprecated (and the
| deprecation is ignored by everyone) just because the
| standard doesn't change anymore.
| maxerickson wrote:
| Sure, but nothing is going to break from the deprecation.
|
| (It's going to break from the eventual removal)
| jagged-chisel wrote:
| For sharing between systems and representing dates to humans
| debugging a system, the following has worked well ...
|
| Planned local events: future date and time string including
| local time zone
|
| Planned global events: future date and time string in UTC, with
| UTC timezone
|
| Past events: date and time string in UTC with UTC time zone,
| unless there is a strong case to be made that these should be
| localized (see "planned local events" above)
|
| Strings in the format specified by ISO-8601.
|
| Of course, internal representation can be whatever it needs to
| be for efficiency. For example, maybe your database stores as
| integer microseconds since an epoch. Fine, but as soon as that
| leaves the database, ISO-8601 that date.
| theK wrote:
| I like your premise but disagree with your guidance.
|
| You should not convert the integer early, you should actually
| wait until the very last moment.
|
| Nowadays a timestamp will be marshalled and demashalled by
| (at the very least) two runtimes until it reaches human
| eyeballs opening up a wide spectrum of bug potential,
| difficult to understand code and development slowdowns.
| Keeping it simple and unambiguous is very important. Time
| libraries have a habit of coming and going, ints are always
| there and 99% of the date arithmetic is trivial any way.
|
| Don't use a lib, just pretty print numbers and you'll be
| fine.
| fluoridation wrote:
| An int is not unambiguous, though.
| "2023-11-19T14:22:34-03:00" is clearly a timestamp and
| represents an unambiguous point in time, while a number by
| itself doesn't mean anything. You have to know that it's a
| timestamp (probably from context) and you have to know what
| timezone it's in.
| Izkata wrote:
| That datetime is unambiguously represented by 1700414554
| as a unix timestamp, and you'd convert to the user's
| local time zone on display.
| pletnes wrote:
| It's a nightmare for the backend developers, compared to
| iso-strings, in my experience.
| rusk wrote:
| Not in the future it's not. There's no way to know the
| exact epoch time until it has happened. Timestamps
| "float" and can accommodate local fluctuations or even
| changes.
| jagged-chisel wrote:
| But 1700414554 is not unambiguously a date. Could be a
| count. Or an identifier. It needs metadata to tell you
| how to interpret it. For this to represent a datetime,
| the human needs to know that it's a datetime, and what
| epoch and timezone to use. The ISO date string removes
| the ambiguity because the context for interpreting it is
| within the string.
| yen223 wrote:
| Crucially, that number could represent the number of
| seconds, or the number of _milliseconds_ since Unix epoch
| (e.g. Date.getTime() in Java)
|
| You kinda have to guess from context that if it's a
| 10-digit number, it's probably seconds.
| bornfreddy wrote:
| I never understood this argument. The ISO8601 date string
| is as much a convention as a unix timestamp is - without
| context neither are decipherable. If anything, unix
| timestamp is _easier_ to explain to an alien than a date
| string. It has a starting point (1970 /01/01 00:00 UTC)
| and it counts seconds from then. Care to explain how an
| ISO8601 date string is constructed?
|
| Also calculating amount of time between two ISO8601
| strings without libraries is nor trivial, or any other
| operation actually. When dealing with dates, there is
| only one simple way to work with non-localized times, and
| it's not ISO-something.
|
| EDIT:
|
| > ...and what epoch and timezone to use.
|
| This is also not correct. Unix timestamp has a well
| defined epoch and it doesn't deal with timezones (though
| the epoch itself is, of course, usually defined as
| 1970/01/01 00:00:00 UTC). You are free to define other
| timestamps, but _unix_ timestamp is well defined.
| mulmen wrote:
| Seconds since epoch requires careful and precise handling
| of datatypes and assumptions. This works great inside a
| system where that can be managed but for the purpose of
| exchange between systems the ISO formats contain all
| relevant information. Either side can use a library to
| parse the string into their local representation.
|
| Comprehension by extraterrestrial life is a localization
| problem.
| mulmen wrote:
| What library did you use? What is your epoch? Are those
| seconds or milliseconds? Is it UTC or TAI?
|
| ISO8601 and friends are literally for formatting dates
| for the purpose of _exchange_.
| Izkata wrote:
| > Past events: date and time string in UTC with UTC time
| zone, unless there is a strong case to be made that these
| should be localized (see "planned local events" above)
|
| I don't think there's any case for storing local time with
| past events. They happened at a specific date and time, store
| them in UTC and if needed convert to local on display. Plus,
| though it's a rare circumstance, for one hour each year DST
| switches cause a duplicate hour - so local time is ambiguous
| during that hour.
| Ndymium wrote:
| There is, when you aggregate your data to create graphs
| such as "My most active hours", you will have a problem if
| your user moves between timezones, if you did not store the
| actual local wall time. [0] For those cases, you can store
| the offset or the denormalized local time along with the
| UTC version.
|
| [0] https://blog.nytsoi.net/2022/03/13/utc
| albert_e wrote:
| > India has half-hour timezones
|
| Not plural though;
|
| The whole of India -- even though it is pretty vast in area --
| has a single time-zone country-wide. I am very thankful for
| this. We already have a lot of other challenges -- including
| dozens of different languages -- that a single time zone is a
| relief.
|
| But yes -- the +5:30 offset usually makes for a less-than-ideal
| factor to plan meetings or follow non local event schedules.
|
| Did I mention we also hate the Summertime / Daylight Saving
| time adjustments we have to accommodate twice a year when
| working with western teams -- more adjustment even after most
| people have already sacrificed on a sane 9-5 schedule to ensure
| they overlap with EU/US teams for daily work meetings. We cant
| imagine why US that has multiple time-zones already in a single
| country, and EU whose countries are often smaller than states
| in India ... need so much adjustment. Why can't they, for
| instance, simply declare that school/offices open at 10am
| instead of 9am for six designated months every year instead of
| imposing this adjustment on the entire world.
| pixl97 wrote:
| If you live closer to the equator it may not make much sense.
| For the longest time the population of the US was heavily
| biased to it's more northern populations than it's more
| southern. In relation to someone that lives in Delhi someone
| in Maine will see a 4 hour larger swing in day length. If
| you're talking farther south in India, like Madurai the size
| of the swing will be even larger.
| phantom784 wrote:
| > Why can't they, for instance, simply declare that
| school/offices open at 10am instead of 9am for six designated
| months every year instead of imposing this adjustment on the
| entire world.
|
| If they did that, you'd still be stuck shifting your schedule
| when they change their working hours.
| gaganyaan wrote:
| That's a good thing, and way better than the current state
| of things. Let the federal government pick summer/winter
| hours, and everyone can adjust or not as they see fit.
| albert_e wrote:
| Not necessarily.
|
| In the most simplest scenario -- once a recurring meeting
| is fixed at 10:30 AM eastern STANDARD time, say, -- no
| schedule change is needed all-year-long if we dont tamper
| with the clock.
|
| It is just that US worker -- due to their own convenience
| -- decides to show up in their office at 9AM for six months
| and 10am for other other six months of the year. Recurring
| meeting does not need to change at all.
|
| The adjustment , if any, is all on US side. And for local
| season / climate reasons which has nothing to do with the
| remote team members, and so the remote team members
| elsewhere in the world dont need to change anything at all.
|
| Just dont tamper with the clock and things will be much
| more simple.
|
| >> If they did that, you'd still be stuck shifting your
| schedule when they change their working hours.
|
| No -- we do not want to link our meetings to the changing
| office hours. We just want a fixed time on a clock fixed
| clock. Pick a time that works throughout the year for both
| teams. Like 10.30 AM EST in my example above.
|
| Current the meetings are "fixed time" but on a moving clock
| -- in reality the meetings shift around but US folks move
| their clocks to "simulate" for themselves that they are
| always having their daily meeting "at 10AM" -- they achieve
| this illusion by inflicting pain on themselves as well as
| rest of the world. We would love if they can leave us out
| of this forced dance :)
| Wowfunhappy wrote:
| Most of my life does not involve coordinating across
| timezones.
|
| You're suggesting that twice every year, we change the
| times that retailers, offices, government agencies,
| broadway theaters, restaurants, roads, schools, and so on
| open and close. Schools alter class schedules and trains
| modify departure times. Also, we all reset our alarms,
| because we'll need to wake up at different times anyway.
|
| It makes so much more sense to just change the clocks!
|
| And yes, _all_ of these things would need to change,
| because they _all_ revolve around the typical work
| schedule! Parents bring children to school before heading
| to work. Public transit runs more frequently during rush
| hour.
|
| There is a discussion to be had about whether we should
| be shifting our schedules in the first place. But as long
| as we're shifting schedules, it makes _so_ much more
| sense to just change the damn clocks!
|
| P.S. Most people don't have white collar jobs!
| Construction workers, janitors, mechanics and so on don't
| _ever_ work across timezones.
|
| P.P.S. I'm okay with nixing the time change _as long as_
| we don 't end up on permanent daylights savings! However,
| permanent daylights savings is my nightmare.
| grogenaut wrote:
| I hate the summer time daytime thing as well and I live in
| the west. Just keep summer time all the time.
| postmodest wrote:
| "We cant imagine why US that has multiple time-zones already
| in a single country"
|
| Because "The USA" spans from GMT+10 to GMT-10. Your Solar
| Noon only varies by an hour between Kolkata and Mumbai.
| Without time zones, the continental U.S. would see a solar
| noon difference of three and a half hours. And that's not
| including Alaska, Hawaii, and Guam, which gives us a 20 hour
| span. You want all those places to be in the same time zone?
| crote wrote:
| Greenland has a single timezone for a 4-hour span. China
| has a single timezone for a 5-hour span. Having a single
| timezone for the contiguous US would definitely not be
| unheard of.
|
| Guam is a bit of an odd duck because it is on the other
| side of the date line. The US currently spans from UTC-4 in
| Puerto Rico to UTC+10 in Guam - which is essentially the
| same as UTC-14. That's a 10-hour span, not a 20-hour one.
| Still, excluding the minor overseas colonial possessions
| would probably make the most sense.
| kingofpandora wrote:
| Have you been to China? It's time zone make sense for
| Beijing and the coast but forces the "Chinese" of
| Xinjiang to do things at unnatural hours for the
| convenience of the ruling elite.
|
| It's bizarre to suggest that someone in western Alaska
| should wake up at the same time as someone in Florida
| because that's what India does.
| Longhanks wrote:
| No, it's bizarre to suggest "7:00 am" should mean sunrise
| for everyone, regardless of their location - it's
| impossible to achieve.
| Muehe wrote:
| You know what? Good on them! We should all just use UTC
| everywhere and adjust business hours accordingly. Get rid
| of timezones altogether.
|
| If you want to know when the sun rises, sets, or is at
| its apex just look it up in a table. The former two vary
| unless you are very close to the equator anyway, and the
| latter is off by an hour for every country using
| "daylight saving time" for half the year. Never mind
| countries that span more than 1/24th of the globe but use
| a single timezone, and that isn't just China.
|
| Also I don't really see how this is "for the convenience
| of the ruling elite". I'd be willing to bet money most
| people in Xinjiang wouldn't have this "problem" in their
| top ten. Probably not even top hundred. This seems like
| something you get used to once and then never think about
| again unless you travel or have a remote meeting.
| chpatrick wrote:
| Greenland only has 50K people and China's timezone
| situation is kind of crazy. I don't think those really
| support your argument.
| pdonis wrote:
| _> The US currently spans from UTC-4 in Puerto Rico to
| UTC+10 in Guam_
|
| No, it spans from UTC-10 in Hawaii to UTC+10 in Guam. And
| if we include other US territories in the Pacific, like
| American Samoa, we have to include UTC-11. That's 21
| hours.
| tzs wrote:
| > Greenland has a single timezone for a 4-hour span
|
| 95+% of Greenland's population lives on its west coast.
| The most common map projection one is likely to come
| across makes it look like that spans a pretty large
| longitude range but it actually only covers about 15deg,
| a 1-hour span.
|
| Take a look at a projection that does a better job of
| representing latitude, such as this [1] azimuthal
| equidistant projection and you can see that west coast
| Greenland is a lot more north/south than you might have
| expected based on the more usual projections.
|
| Here's a map of the towns in Greenland with >300
| population [2] showing how much more populated the west
| coast is than the rest of the country. If you add their
| populations and the populations of the towns listed in
| the table but too small to make the map it comes to about
| 3100 people.
|
| [1] https://en.wikipedia.org/wiki/Azimuthal_equidistant_p
| rojecti...
|
| [2] https://en.wikipedia.org/wiki/List_of_cities_and_town
| s_in_Gr...
| steveBK123 wrote:
| Brazil's stock market does/used to do something along these
| lines when US & Brazil changed their clocks in opposite
| direction, to keep the NY time hours of the Brazilian
| exchange from drifting as far. Given that we all also
| observed DST at the time, this made things even more
| complicated for systems.
| screye wrote:
| Having lived in both India and far North in the USA, I'd take
| half-hour time zones over daylight savings every time.
|
| Shifting time-zones increases car accidents by about 6-16%
| for the entire week (studies vary). Just that is a massive
| enough impact on safety and productivity to discourage the
| switch. At a personal level, leaving work at 5.30-ish with it
| being pitch black outside, is among the most depressing
| things in the world. Even more wasteful is that the average
| American wakes up at 7.20am. So, they don't gain any daylight
| but lose an entire hour.
|
| I'm not usually the type to make such accusations, so I
| apologize in advance for sounding culture-warry. But,
| switching-time zones is "white person thing". Large percent
| of the Chinese, Indian & the Middle Eastern population live
| above the 25th parallel (Florida) and large populations of
| Korea & Japan live north of the Bay Area without daylight-
| switching.
|
| Permanent daylight time with later sunrise would be a huge
| win.
| mulmen wrote:
| > We cant imagine why US that has multiple time-zones already
| in a single country
|
| Are you aware the contiguous United States is three times
| larger than India? Alaska alone is half the size of India and
| not at the same longitude as the lower 48. Hawaii is even
| farther west than most of Alaska. The easternmost point in
| the US is 66 degrees west. The westernmost is 179 degrees
| west. That's nearly a third of the globe.
|
| > Why can't they, for instance, simply declare that
| school/offices open at 10am instead of 9am for six designated
| months every year instead of imposing this adjustment on the
| entire world.
|
| Is this a serious comment? Europe doesn't have a central
| government. The most recent attempt to establish one was
| extremely unpopular and famously stopped in 1945.
|
| Why should foreign schools and businesses change their hours
| to accommodate you? A more obvious solution would be to just
| stop observing DST but that's not something that will happen
| unilaterally and will be an especially hard sell at extreme
| latitudes.
|
| If you want to do business internationally you have to deal
| with timezones. India isn't unique in that inconvenience.
| Asooka wrote:
| > but that's not something that will happen unilaterally
| and will be an especially hard sell at extreme latitudes.
|
| Not unilaterally per se, but EU parliament did vote to end
| it in ... 2021
| https://www.europarl.europa.eu/news/en/press-
| room/20190321IP... . COVID kind of put those plans on the
| backburner.
|
| People at extreme latitudes should not care much, since for
| them DST does close to nothing.
|
| The parent's proposal is actually quite sound. It would be
| a lot more useful to have institutions switch their
| starting times for part of the year when it makes sense for
| them, rather than forcing a one-size-fits-all solution on
| everyone. Countries at different latitudes would be free to
| switch e.g. school start times at different dates depending
| on when sunlight shifts too far in one direction, while
| keeping their clocks synchronised with astronomical time.
| Heck, Spain basically does that already, since they're on
| the wrong timezone (geography dictates they should be on
| British time, but because of events in the '40s, they're on
| Central European time) - so they do everything one hour
| "later".
| mulmen wrote:
| [delayed]
| master_crab wrote:
| It definitely will break financial firms. I just did a code
| search in our repos for utcnow and other relevant functions,
| and the indexer was definitely wheezing pulling in the hits.
| andrewprock wrote:
| Deprecation should not break anything. At some point the code
| will be removed and the org will have to pin the version
| until the deprecations are resolved.
| StableAlkyne wrote:
| > I suspect a lot of financial data code is going to break.
|
| Reminds me of when Numpy removed a lot of types like np.bool a
| few releases ago, because they were aliases of the standard
| library types.
|
| Which broke a _ton_ of libraries having Numpy versions pinned
| to ">=1.0" or even worse, "~=1.0" expecting them to follow the
| standard practice of incrementing the major version when they
| break compatibility. It's not _terrible_ because you just pin
| your project to 1.23 or whatever, but it was very annoying when
| everything I was using just started breaking.
|
| I wonder if Python plans to do the same with this - the 2 to 3
| transition was painful and dragged on for a decade, nobody
| wants to do that again for 3 to 4. When they remove this
| function and break back compatibility with old code, is that
| going to happen in a future 3.x release?
| hexane360 wrote:
| It's worth noting that numpy and scipy have a consistent
| policy now, although it's not semver. Deprecations will
| always happen at least 2 minor versions before removal:
|
| https://numpy.org/neps/nep-0023-backwards-compatibility.html
|
| https://numpy.org/doc/stable/dev/depending_on_numpy.html#run.
| ..
|
| So, when using numpy in a package, and you've tested e.g.
| versions 1.12 to 1.22, you should require
| 'numpy>=1.12,<1.25', because something deprecated in version
| 1.23 could be removed in 1.25.
| jkrejcha wrote:
| Yes, they're almost certainly going to do it a 3.x release.
|
| I think in some senses these backward compatibility breaks
| have already happened. I remember that Google got bit by
| async becoming a keyword in I think Tensorflow.
|
| Generally a lot of old Python 3 code still works today if it
| doesn't do anything really weird like that, but I do
| definitely think that the pain of Python 2 to 3 was painful
| so they don't really want to repeat it.
|
| I think it is probably prudent to treat point releases as
| major releases at least with regards to Python.
| notatoad wrote:
| Removing utcnow() doesn't force you to use tz-aware dates
| though. That's just a leap that the author of this article has
| made.
|
| If you're working in a system where all dates are utc, then
| datetime.now() gets you a date in utc and you don't need
| datetime.utcnow(). The only reason to call utcnow is if you're
| working on a system where the local timezone isn't utc, so you
| inherently have to deal with timezones at some level. Which
| means that using naive timestamps is a bad idea.
| nerdponx wrote:
| datetime.now(tz=timezone.utc) is what you probably want most
| of the time anyway. You can always manually strip off the
| time zone component if you really want to use datetimes
| without associated time zones.
| ahoka wrote:
| Then accept that UTC is a timezone and just use that
| everywhere. There are also a lot of things that can't be easily
| stored in UTC, like opening hours.
| icholy wrote:
| Why can't opening hours be stored in UTC?
| pjot wrote:
| Seems like the ideal way to store them to me!
| mulmen wrote:
| Have you thought about this? How do you store shop hours
| in UTC for shops in timezones with DST?
| midasuni wrote:
| Then you would be wrong, because they open at 9am local
| time - if the government changes local time with 2 days
| notice then opening time changes.
| jomoho wrote:
| Every heard of daylight savings time (DST)?
| capableweb wrote:
| Can be adjust client-side, or wherever you need to
| present it, rather than adjusting stored data.
| mulmen wrote:
| This is only sometimes true. Cases like opening hours and
| daily batch processing rely on local time. Persisting the
| values in UTC mean best case you are wrong half of the
| year and worst case all of it.
| capableweb wrote:
| Just because you're storing the time in UTC doesnt mean
| you can't also store the timezone, and lots of other
| related data too.
| mulmen wrote:
| [delayed]
| RichieAHB wrote:
| A store's opening hours will probably remain 9am-5pm
| regardless of any time zone changes around it. If you run a
| bunch of stores across time zones you need to know where
| each store is and whether it's summer or winter to work
| backwards to find out 9-5 in UTC.
| mulmen wrote:
| The coffee shop in my neighborhood is open from 6am to 2pm
| Pacific. We observe daylight saving time. The shop hours do
| not change. So, what UTC value do you store?
| bilsbie wrote:
| I guess it would change based on local time changes.
| narrator wrote:
| Yeah, the stock market opens at what time EST? Including
| daylight saving time, etc. I agree that any time time goes to
| a serialized format over a socket or to a database or file it
| should always be UTC.
| rtpg wrote:
| Something like "9AM-5PM EST" can't be stored in a datetime
| object even with a timezone slot! Datetimes with a timezone
| represent specific points in time, not vague "5PM" like
| concepts.
| divbzero wrote:
| If "everything is UTC, all the time" is enforced at the entry
| edges of the code, couldn't the entry edges be refactored to
| always specify the UTC timezone?
| lern_too_spel wrote:
| That doesn't work for recurring events in local time.
| smooc wrote:
| Financial data deals with cutoff times and those happen in a
| timezone. Thus particularly in finance timezones are important.
| You are right though that internally everything should be UTC
| internally and only when required it gets transposed to the
| timezone. However many legacy financial systems assume a local
| time zone and not UTC and they do not expose that information
| in their data. Happy reconciliation :-).
| steveBK123 wrote:
| One edge case to this is I've worked on financial systems
| where we kept the Asian market systems in JST, while
| EU/MENA/Americas ran on UTC. As long as you aren't dealing
| with FX/Futures, markets are generally open no earlier than
| 7am and no later than 6pm. This worked nicely since it meant
| that the DATE in each regions system&local clocks agreed.
| midasuni wrote:
| If the market opens at 9am New York time then that's not the
| same as storing 1400 utc. An law could be passed to change
| the offset on a given day
|
| You have to store time in the relevant geographic time zone.
| Something occurring at 1200UTC on dec 1st is not the same as
| something occurring at 1200Europe/London on dec 1st. The two
| times may coincide today, but if the U.K. government decides
| to implement daylight saving next week as a fuel rationing
| measure, then your 1200London event will have to be displayed
| at 1300UTC, but your 1200UTC event would be at 1200UTC.
| hanniabu wrote:
| This is just dumb...
|
| > I would have made it more clear that these functions work with
| naive time, maybe by calling them naive_utcnow() and
| naive_utcfromtimestamp().
|
| > But their names are not the problem here. The specific issue is
| that some Python date and time functions accept naive timestamps
| and assume that they represent local time, according to the
| timezone that is configured on the computer running the code.
|
| Uhhh, no I would not expect local time because as the name
| entails we're dealing in UTC. Sigh.....
| vore wrote:
| You might not, but the standard library sure does. And that's
| the exactly the problem! How can functions in the standard
| library know if the time is local or UTC without any indication
| on the value itself? (spoiler: they can't!)
| BugsJustFindMe wrote:
| The less stupid solution is to just make those functions
| produce zone aware datetimes because you have literally asked
| for a specific time zone.
| seanp2k2 wrote:
| As the article author correctly points out, Python should
| have just thrown when a method is called that requires a TZ
| with a datetime that doesn't include one.
|
| Between this, the Unicode circus, and the rejection of
| PEP582, Python seems more and more like the HOA that isn't
| earning their monthly fees IMO.
| BugsJustFindMe wrote:
| I don't understand why the functions weren't just made to return
| non-naive results. You've literally asked for UTC. There's no
| excuse for allowing the result of that to be interpreted as
| something that isn't UTC.
|
| Set a separate flag that governs conversion to string to avoid
| different ISO output for shitty string parsers if you want, but
| there's no great reason to not just fix the functions so that
| they continue to work better than before and do the thing that
| people actually expect them to do, which is produce UTC.
|
| Intentionally naive storage or transfer is irrelevant. That's
| just serialization. And when you explicitly tell the computer to
| "deserialize this as UTC" it should fucking do what you told it
| to and give a zone aware result.
| drkevorkian wrote:
| This would be a backwards incompatible change that would cause
| a lot of issues. For instance, you are not allowed to compare
| naive and non-naive datetimes, so for instance, `utcnow() >
| datetime(2023, 11, 19)` would work before, but break following
| your change.
| akersten wrote:
| Removing the functions wholesale _isn 't_ a backwards
| incompatible change?
| ollien wrote:
| It is one that can be found via static analysis. That may
| not be true if behavior is changed. In some cases, this may
| be "ok" (see: Go's recent loop changes), but in others, it
| may not.
| IshKebab wrote:
| Most Python users don't do any form of static analysis
| though, so both changes would only be found at runtime.
|
| But I think changing the behaviour and not the name is
| still a very bad idea.
| BugsJustFindMe wrote:
| That's going to break following this change anyway.
| sanderjd wrote:
| But in a much more obvious way. Noisy errors are better
| than quiet inaccuracy.
|
| They screwed up these methods from the start, and removing
| them is the only way to get rid of the confusion, without
| introducing subtle breakage.
| InitialBP wrote:
| If this was something used only by your company or a specific
| project, then I'm absolutely on board. However, this is in a
| library used in thousands (millions?) of projects. Since it's
| potentially a breaking change you can't just change it and
| expect everyone to know.
|
| Many people won't know it's deprecated until the code fails to
| run, and having new functions rather than changing the
| functionality of existing functions makes it much easier to
| identify what is actually happening.
| thrdbndndn wrote:
| > I don't understand why the functions weren't just made to
| return non-naive results. You've literally asked for UTC.
|
| I totally agree with you that it makes no sense this `utcnow()`
| does not return tz-aware object.
|
| But I think their fix is great in this regard: now you just use
| `datetime.now(timezone.utc)`. It's more explicit, it returns
| aware DT object now, and more importantly, it gets rid of a
| function that I always feel too specific to have anyway (like
| how we don't have `plus(a, 2)` and `plustwo(a)`).
| sanderjd wrote:
| Except isn't datetime.now() still going to return a tz-naive
| datetime? I would much rather have a method that requires an
| explicit tz, or explicitly uses UTC (like utcnow, but with
| the right return type).
|
| Looking for this mistake in code reviews gets really old.
| abh123 wrote:
| I got bit by this once. Timezones aware date calculations can
| be an order of magnitude slower than non tz aware. Consider
| every time a legislative body changes dst, it creates an
| entry in the timezone database that needs to be checked when
| adding or subtracting time from that timezone.
| ryandrake wrote:
| I'm not a Python guy so am not familiar with the culture, but I'd
| assume many, many programs use the deprecated function, given
| that it made "the news." It seems not right for backward
| compatibility to deprecate something many developers are using,
| simply because the old one wasn't thought out very well, and
| "developers should switch" to the explicit functions. Especially
| since, as the author demonstrates, the deprecated one can be
| easily re-implemented. It seems like a developer inconvenience
| was added without changing the state of the world. Things like
| this--I don't know--make me take a development environment less
| seriously.
|
| In C, we all know we shouldn't use things like strcpy() and
| gets(), and you'd be a total fool to add them to new code. But
| for the sake of backward compatibility with programs that aren't
| going to change, they should be kept in and documentation should
| nudge people to do it the right way. Maybe that's the Python way
| of nudging: "This function is deprecated!"
| int_19h wrote:
| Different language ecosystems have different standards for
| backwards compatibility, with C (and e.g. Java) being
| incredibly conservative by modern standards. This is not a good
| or a bad thing per se, it's just something to consider when
| picking a tool for the task at hand.
| jkrejcha wrote:
| Fwiw, gets() was actually removed in C11 because of it's
| inherit security problems. :)
|
| But aside from that, I think it's just a different style.
| Waiting 10 years from deprecation to remove a deprecated thing
| might be required with C just because of how prevalent C is and
| how much the developers in that _have_ to think about basically
| every platform, but removing something on a major release isn
| 't inherently bad, it's just a different tradeoff (being able
| to move a bit faster and fix some design issues vs. being very
| very good at backwards compat)
|
| The deprecated function can obviously be reimplemented pretty
| easily, but so can gets(). With utcnow(), it had some
| unfortunate effects in that it didn't really do what people
| thought it did, and because of that, most of the uses were
| basically bugs to begin with.
|
| (Having experience with .NET for example, you'd think that
| DateTimeOffset.UtcNow and datetime.utcnow() are semantically
| similar, but the problem is that utcnow() doesn't actually have
| a timezone attached to it. Adding one would also be a breaking
| change, and one that is more subtle.)
| sillysaurusx wrote:
| One advantage of getting older is that you see a lot of change.
| In the long run, simple ideas tend to win. And there have been
| lots of cases where the programming world collectively agreed
| that some more complex idea was the right way, then a decade
| later everyone has reverted to the simple idea.
|
| UTC is simple and unambiguous. Time is a number representing a
| fixed point in time. When displaying it for humans, convert it
| into human form. When this principle is applied everywhere, it's
| hard to make mistakes.
|
| My gut says that deprecating utc as the native time
| representation will be one of those ideas fervently embraced by a
| few, ignored by most, and then quietly forgotten about in a
| decade.
| ryandrake wrote:
| It doesn't seem like they're deprecating "utc as the native
| time representation." They're just making it harder to get a
| datetime object that "has no time zone." The message with this
| change is: Go ahead and keep using UTC, but explicitly specify
| it, and the object itself will know it's own UTC-ness.
| p5a0u9l wrote:
| They're not deprecating UTC. Did you read the link? They're
| deprecating functions that read as authoritative, but are
| actually naive about timezones, which can less to non-UTC
| results.
| sillysaurusx wrote:
| If that were true, the recommended fix would be to continue
| using utc (as numbers). Instead, the recommendation is to use
| datetime objects.
|
| This, I think, is the idea that will be quietly ignored in
| the long run.
| im3w1l wrote:
| It's hard not to draw the parallel to encodings. Implicit
| whatever -> Explicit whatever -> Explicit utf8 -> Implicit
| utf8
| remram wrote:
| What is "utc as numbers"?
| worik wrote:
| > What is "utc as numbers"?
|
| Seconds since start of epoch
| remram wrote:
| You're free to use numbers instead of the datetime
| module. In fact you don't have to use any part of the
| standard library if you don't want to. I don't understand
| your remarks at all.
|
| If you think UTC means that "time is a number" you are
| very confused though. UTC has no relation with the UNIX
| timestamps (and the epoch), though they are both ways to
| represent a specific point in time.
| worik wrote:
| The question was: 'What is "utc as numbers"?'
|
| You are reading to much into a simple question.
|
| > UTC has no relation with the UNIX timestamps (and the
| epoch),
|
| I said nothing about Unix
|
| The epoch in Swift IIRC is in 2000.
|
| The idea of counting time in seconds since an epoch is
| ubiquitous. I am unsure if it is universal
| remram wrote:
| I'm reading too much into my own question? This
| conversation is getting too inscrutable for me.
|
| It was my mistake for trying to engage. Generally people
| get downvoted for good reason.
|
| Still I'm confused why you're in this thread at all,
| which is about a change to an API you don't seem to want
| to use at all.
| sanderjd wrote:
| I think the recommendation is to use a datetime with the
| timezone explicitly set to utc? I think the numbers vs.
| objects thing seems like a distraction...
| worik wrote:
| > "naive about timezones"
|
| That is what they said, but it is inaccurate
|
| All time should be UTC until it is displayed
|
| So a number without a timezone is seconds since epoch in UTC
|
| That is "default" not naive
|
| Some Python applications programmers made stupid mistakes so
| they change the library
|
| Golly. On the face of it Python is a mess. And it is
| everywhere. Golly
| int_19h wrote:
| You're focusing on representation where you should be
| thinking about semantics.
|
| A "naive" datetime is the one for which it is not known
| what the timezone is. The opposite is the one for which it
| is known. You can absolutely encode UTC timezones as
| seconds since epoch without any additional information
| (except that one bit that is needed to distinguish them
| from "naive" ones, which doesn't have to be a literal bit -
| it can be just a different data type, for example).
|
| And, yes, it would sure be nice if we didn't have "naive"
| datetimes at all, and everything was always UTC. But there
| are too many datetimes recorded in the real world without
| enough information to recover the timezone and thus the
| precise UTC time, and they still need to be processed. The
| mistake was to make this the default behavior - but that is
| a very old one, dating back to earliest days of computing.
| worik wrote:
| > You're focusing on representation where you should be
| thinking about semantics.
|
| True. Fair
|
| > A "naive" datetime is the one for which it is not known
| what the timezone is.
|
| Then it is UTC
|
| That is what UTC is for.
| skitter wrote:
| > Then it is UTC
|
| You're absolutely right that it should be, but the
| problem is that it isn't - Python treats these as
| belonging to the local time zone.
| nemothekid wrote:
| > _Then it is UTC_
|
| Says you. The python documentation has never said that
| naive datetimes are UTC. If the language suddenly makes
| this assumption, then _you break existing code_. If you
| don 't want to break existing code, your only option is
| to 1.) deprecate the existing function and 2.) provide an
| alternative (which is provide an explicit datetime).
| int_19h wrote:
| No, it is not. It is a datetime for which it is not known
| whether it is UTC or not. Assuming that it is is only
| marginally less bad than assuming local time.
| worik wrote:
| > But there are too many datetimes recorded in the real
| world without enough information to recover the timezone
| and thus the precise UTC time
|
| Software sux
|
| Changing the Python libraries to try to fix buggy
| software strikes me, on the face of it, as a bad idea.
|
| I am sensitive to this having recently worked with ode
| that stored time as a string, wall clock local, with no
| timezone.
|
| And made time series data from it
|
| Software sux, because programmers do silly things
|
| Stop it!
| Spivak wrote:
| This misses what the change actually is. Python has two
| datetimes, one which includes the timezone info and one which
| doesn't (naive).
|
| There is no assumed timezone for naive datetimes and different
| software treats it differently. What's being deprecated is
| methods to create naive datetimes that are implicitly UTC
| without just attaching that information to the object itself.
| In the new world everything is still in UTC and you convert to
| local time at the last minute but now you can be sure that the
| datetime object you got handed is actually UTC instead of it
| being a convention that isn't always honored.
| gizmo wrote:
| Good point. Also, as long as javascript will happily convert an
| integer into a new Date() people will want obvious
| compatibility in Python.
| happytoexplain wrote:
| Time is two different things. Just making everything UTC until
| display time is incompatible with that. Sometimes you need to
| operate on calendar units or clock units as part of business
| logic.
| worik wrote:
| > Sometimes you need to operate on calendar units or clock
| units as part of business logic.
|
| And you _must_ do it in UTC
| erik_seaberg wrote:
| To make something happen at 9 AM every day in the user's
| time zone, choosing UTC will make it harder.
| worik wrote:
| Needs must.
|
| But otherwise use UTC
|
| A local time aware process has to be available for users.
| Of course
|
| But in the backend it is UTC
|
| Storing time any other way is a world of pain
| 38 wrote:
| Go seems to work as expected here: package main
| import ( "fmt" "time" )
| func main() { dt := time.Unix(0, 0).UTC()
| fmt.Println(dt) // 1970-01-01 00:00:00 +0000 UTC
| fmt.Println(dt.Unix()) // 0 }
| forgotpwd16 wrote:
| Does Go also has a distinction between naive/timezone-aware
| times? If not don't see why would expect something else. This
| is an issue because the distinction exists. Note it isn't bad
| that it does. There're actually arguments in favor of it. It's
| bad that can freely mix them.
| 38 wrote:
| > Does Go also has a distinction between naive/timezone-aware
| times?
|
| Why would you ever want or need that?
| forgotpwd16 wrote:
| Suppose you want to run a routine after 12h. That is now is
| 7 PM and want it to run tomorrow at 7 AM. Like if simply
| print times you get: t1 = datetime.now()
| t2 = t1 + datetime.timedelta(days=0.5) print(str(t1))
| # '2023-11-19 19:00:00.000000' print(str(t2)) #
| '2023-11-20 07:00:00.000000'
| 38 wrote:
| > That is now is 7 PM and want it to run tomorrow at 7
| AM. Like if simply print times you get
|
| is this English? also I am still not seeing a problem:
| package main import ( "fmt"
| "time" ) func main() {
| t1 := time.Now() t2 := t1.Add(12 * time.Hour)
| fmt.Println(t1) // 2023-11-19 15:14:16
| fmt.Println(t2) // 2023-11-20 03:14:16 }
| forgotpwd16 wrote:
| >is this English?
|
| Ah, a grammar pedant. Haven't met one in a while.
|
| >also I am still not seeing a problem
|
| Try again setting your timezone to let's say NY and date
| at 2023-11-04. Oops.
| slotrans wrote:
| This was an aside and not the point of the article but I can't
| let it go:
|
| > It is also a best practice to store naive datetimes
| representing UTC in databases.
|
| It is most definitely NOT a best practice and you SHOULD NOT DO
| THIS.
|
| If your database supports TIMESTAMP WITH TIME ZONE -- which the
| "aware" type per the article's terminology -- you should be using
| it. If your database doesn't, you should get a better one.
| klysm wrote:
| This is a good idea for Postgres but only because of its
| specific semantics
| spsesk117 wrote:
| Would you care to elaborate? I'm not an expert in this area so
| I'm probably missing something, but my thought has always been
| the 'portability' of storing everything in the backend as UTC
| is more flexible/less complex in the long run, dealing with
| conversation at the 'last mile' so to speak.
|
| Happy to be corrected here but it's not intuitive to me that
| dealing with timezones as the 'base unit' makes anything
| easier.
| toyg wrote:
| It's the usual divide between people who actually know how
| databases work, and hence want to do more stuff there
| (because it will likely be faster and more robust); and
| people who don't know (and don't want to know) anything about
| databases, and hence would rather use them as dumb stores of
| basic data.
|
| I've been in each camp at one time or another, since being
| db-agnostic makes sense in some cases (libraries, products)
| and not in others (websites, services).
| int_19h wrote:
| It's not an either-or. You can store everything in UTC while
| also using TIMESTAMP WITH TIME ZONE. The timezone will always
| be UTC, but that way at least anyone who will be dealing with
| this data later knows that to be the case, instead of
| assuming.
| Denvercoder9 wrote:
| Converting from a local date/time with an associated timezone
| to an UTC time is not a lossless nor unchanging operation. By
| converting everything to UTC, you're throwing away
| information that you might need to do the conversion at the
| 'last mile' later on.
|
| For example, imagine I schedule a dentist appointment for 9AM
| in my local timezone sometime next summer, and put it in my
| calendar. Now, if the government decides that we won't do
| daylight saving times next year, my dentist and I still
| expect that appointment to happen at 9AM local time. However,
| if my calendar application had converted it to UTC using the
| timezone definitions at the moment I created the appointment,
| it would show in my calendar at 8AM, and I'd be an hour
| early!
|
| This is not an as hypothetical situation as it seems. To give
| just two recent examples: the Chilean government decided to
| postpone the start of DST with less than a month's notice
| last year, and Morocco shifts the clock an hour during
| Ramadan, the date of which only becomes certain on the day
| itself.
| ntonozzi wrote:
| Can you explain why? I write web apps, and I typically want to
| know an instant in time when something occurred and then
| localize the time for display. Why would I need to store a time
| zone for that?
| crote wrote:
| Storing UTC for past events is totally fine because it is
| unambiguous.
|
| However, if you are writing something like a calendar app and
| storing timestamps for future events, you run into the issue
| that time zones have the annoying habit of changing.
|
| Let's say you have a user in Berlin, and they want to
| schedule an event for 2025-06-01 08:00 local time. According
| to the _current_ timezone definition Berlin will be on CEST
| at that moment, which is UTC+2, so you store it as 06:00 UTC.
| Then Europe abandons summer time, and on 2025-06-01 Berlin
| will now be on CET, or UTC+1. Your app server obviously gets
| this new definition via its regular OS upgrades.
|
| Your user opens the app, 06:00 UTC gets converted back to
| local time, and is displayed as 07:00 local time. This is
| obviously wrong, as they entered it as 08:00 local time!
|
| Storing it as TIMESTAMP WITH TIME ZONE miiiight save you, but
| if and only if the database stores the timezone as
| "Europe/Berlin". In practice there's a decent chance it is
| going to save it as a UTC offset anyways...
| seanp2k2 wrote:
| If you're storing time zone info for a transaction in the
| database instead of storing it as epoch time, you're probably
| doing it wrong. Time zone is a user-level presentation layer
| issue. Keep that junk out of the backend. Imagine writing code
| to reconcile financial transactions that also had to deal with
| time zone offsets to figure out if one transaction happened
| before another. So much extra complexity for no reason. I don't
| know where you've been doing this or where you got this idea,
| but it's most definitely not common or advisable to store TZ
| info on transactions anywhere I've worked in my couple of
| decades at some very large software companies. TZ info is
| usually stored with a user account as a preference that they
| can update, or it's detected from their browser during
| presentation time, because that's when it matters -- when
| you're showing it to a human. Having machines calculate TZ
| offsets between database records is asinine, inefficient, and a
| great way to introduce an entire domain of bugs for absolutely
| no reason.
| Figs wrote:
| > If your database supports TIMESTAMP WITH TIME ZONE -- which
| the "aware" type per the article's terminology -- you should be
| using it.
|
| NO!!! IT IS NOT THE SAME AT ALL!
|
| I've been burned by that _exact_ misconception. TIMESTAMP WITH
| TIME ZONE does NOT store a timezone in the database!
|
| It _implicitly converts_ a timestamp you supply into UTC and
| DISCARDS the associated timezone information you provided. When
| you read it back, it converts it to LOCAL time unless you
| explicitly specify a different conversion. This is a recurring
| source of confusion and bugs. The timezone a timestamp was
| _actually written in_ is sometimes VERY important -- and I 've
| personally had to deal with _data loss_ on a project caused by
| this misconception.
|
| Let me repeat: There is NO WAY to read back what timezone a
| "TIMESTAMP WITH TIME ZONE" was written with later -- unlike an
| "aware" datetime in Python -- BECAUSE IT DOES NOT ACTUALLY
| STORE THE TIME ZONE YOU SUPPLIED! This is a data type that
| _DESTROYS INFORMATION_ YOU PROVIDED TO THE DATABASE assuming it
| can be clever later.
|
| I fucking _hate_ that data type SO much.
|
| An "aware" datetime in Python actually tracks a timestamp with
| _a specific timezone explicitly attached to it_. It is VERY
| different!
|
| Documentation for Postgres:
|
| > For timestamp with time zone, the internally stored value is
| always in UTC (Universal Coordinated Time, traditionally known
| as Greenwich Mean Time, GMT). An input value that has an
| explicit time zone specified is converted to UTC using the
| appropriate offset for that time zone. If no time zone is
| stated in the input string, then it is assumed to be in the
| time zone indicated by the system's TimeZone parameter, and is
| converted to UTC using the offset for the timezone zone.
|
| > When a timestamp with time zone value is output, it is always
| converted from UTC to the current timezone zone, and displayed
| as local time in that zone. To see the time in another time
| zone, either change timezone or use the AT TIME ZONE construct
| (see Section 9.9.4).
|
| https://www.postgresql.org/docs/current/datatype-datetime.ht...
|
| Python:
|
| > Date and time objects may be categorized as "aware" or
| "naive" depending on whether or not they include timezone
| information.
|
| > With sufficient knowledge of applicable algorithmic and
| political time adjustments, such as time zone and daylight
| saving time information, an aware object can locate itself
| relative to other aware objects. An aware object represents a
| specific moment in time that is not open to interpretation.
|
| [...]
|
| > For applications requiring aware objects, datetime and time
| objects have an optional time zone information attribute,
| tzinfo, that can be set to an instance of a subclass of the
| abstract tzinfo class. These tzinfo objects capture information
| about the offset from UTC time, the time zone name, and whether
| daylight saving time is in effect.
|
| https://docs.python.org/3/library/datetime.html
| zzzeek wrote:
| I agree (though less indignantly). TIMESTAMP WITH TIME ZONE
| basically makes me confused as it is trying to run around
| guessing how to actively solve a problem I dont actually
| have, which is, "I don't know how to correctly represent
| datetimes in my application".
| Figs wrote:
| I may have been a bit over the top there. :p
|
| TIMESTAMP WITH TIME ZONE just sets off my lingering issues
| from an old project.
|
| All the other posts in this thread misunderstanding it
| really demonstrate the point about it being a source of
| recurring confusion though!
| zzzeek wrote:
| what people usually want, when they are confused about
| that datatype, is a datatype that stores the timestamp
| *and* a _specific_ timezone to go along with it, so you
| get back a timestamp with that same timezone if you did
| not ask to convert it to another. that would be a bit
| less efficient from a storage perspective but would
| likely be more intuitive.
| zzzeek wrote:
| TIMESTAMP WITH TIME ZONE stores the timestamp naively. The type
| defines a convention for how data is transmitted to and from
| the datatype.
|
| which is basically exactly how one is supposed to use timezone-
| naive datetimes. the datetimes are individually "naive" however
| are meant to always be used within a context that is implicitly
| non-naive across the full set of datetime objects.
| FObersteiner wrote:
| I think naive datetime would be fine, even if it resembles UTC -
| as long as you don't mix in a serial representation. The module
| documentation says, "Whether a naive object represents
| Coordinated Universal Time (UTC), local time, or time in some
| other timezone is purely up to the program, [...]". That
| definition goes down the drain imho once you call `.timestamp()`,
| which gives you Unix time as a serial representation (epoch
| time), which _must_ be referenced against aware datetime, namely
| 1970-01-01 00:00 UTC. Same trouble vice versa
| (`.fromtimestamp()`).
| BiteCode_dev wrote:
| The snippets the article give are good to get an UTC datetime or
| timestamp now.
|
| I'd like to add that if you have any fancy datetime manipulation
| to do in Python, pendulum (https://pendulum.eustace.io/) is
| probably your best bet.
| nooorofe wrote:
| >pendulum is probably your best bet
|
| It is best until you work with Pandas DataFrame
| (https://stackoverflow.com/questions/47849342/making-
| pandas-w...)
| BiteCode_dev wrote:
| Numpy and pandas are their own little island. It's not just
| dates and time, it's everything.
|
| If you use numpy and pandas, you should also not use Python
| datetime, generators, most stdlib mathematical functions, the
| itertools module, random, etc.
|
| It's the first thing you learn if you read any good pandas
| book, and the first thing I teach in my numpy/pandas
| trainings.
|
| It has pretty much nothing to do with pendulum.
|
| Basically, half the Python ecosystem is "well, except with
| numpy/pandas of course".
| contravariant wrote:
| You know what would help people adopt timezone aware timestamps?
| Just make now and utcnow return timezone aware timestamps! What's
| the point creating a naive timestamp when you _know_ the time?
| oblvious-earth wrote:
| Discussion on Python discuss:
| https://discuss.python.org/t/deprecating-utcnow-and-utcfromt...
|
| I'm the one arguing against this move, I've already made my
| thoughts clear that it's a lot of churn, e.g. the PR to remove it
| from Pip literally caused Pip to have to do a bug release, and
| has valid use cases, e.g. modelling datetime data types from
| spreadsheets and databases that do not have timezones.
|
| But I also accept I'm not the one maintaining Python, so I've
| updated my codebase appropriately
| (`datetime.datetime.now(datetime.UTC).replace(tzinfo=None)`).
| Python is not a backwards compatability language, and it's
| clearly not a strong motivation for most users as I don't see
| anyone attempting to write a backwards compatibility shim over
| the standard library, so no point complaining too much.
| tomp wrote:
| Bad idea.
|
| datatime.utcnow() should be the default way of recording &
| storing time, e.g. in logs or in the database.
|
| All other options are strictly inferior. >>>
| str(datetime.datetime.utcnow()) '2023-11-19
| 16:46:04.049705' >>>
| str(datetime.datetime.now(datetime.UTC)) '2023-11-19
| 16:46:35.924671+00:00'
|
| There's no reason for `+00:00` visual noise in the UTC-aware
| datetime.
| forgotpwd16 wrote:
| >datetime.datetime.now(datetime.UTC)
|
| There're many things to complain but this is certainly not one.
| datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
| Though this should be `datetime.timezone.utc` rather
| `datetime.UTC` if not mistaken.
| tomp wrote:
| not sure, I tried this in Python 3.11.6 and `datetime.UTC`
| works whereas `datetime.timezone.utc` doesn't exist
|
| in any case, just compare
| datetime.datetime.utcnow()
|
| and
| datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
|
| verbosity is _not_ a virtue in this case
| remram wrote:
| This is verbose because it is dissuaded. The whole point of
| this change is to _not_ have users get naive datetime
| objects, of course it gets more verbose.
| int_19h wrote:
| `datetime.timezone.utc` is the original way of doing it and
| should work just fine on a stock Python 3.11 install.
| `datetime.UTC` is a relatively recent addition, and if you
| look at the actual type of the object it returns, it's
| still `datetime.timezone.utc`
| forgotpwd16 wrote:
| So my installation was outdated. Still not fan of having
| two different ways to refer to the same thing.
| remram wrote:
| There is definitely a reason...
| amluto wrote:
| It would be nice if there were separate types for naive and aware
| datetimes. Then mypy and similar tools could actually check code
| for correctness.
| karmakaze wrote:
| Isn't Python adding gradual typing? This is the sort of confusion
| that becomes apparent when we know and write the types (TZ aware
| or not) coming out of into functions.
| neillyons wrote:
| Python should use different types to represent datetimes with a
| timezone and those without. class Datetime:
| pass class NaiveDatetime: pass
|
| That way you can annotate functions properly.
| def timezone(datetime: Datetime) -> ...:
|
| This is how Elixir does it. So much easier to understand as a
| newcomer.
|
| https://hexdocs.pm/elixir/DateTime.html
| https://hexdocs.pm/elixir/NaiveDateTime.html
| jes5199 wrote:
| I've definitely been burned by assuming that "no time zone" means
| UTC when my python environment assumed I wanted it to mean
| Pacific time - it's like the APIs all prefer naive datetimes, and
| I had to learn a new trick for each one to convince it to do the
| right thing
| usrbinbash wrote:
| > To me it is clear that the Python maintainers behind this
| deprecation have a problem with naive datetimes and are using
| this supposed problem as an excuse to cripple them.
|
| I am not a python maintainer, and I also use naive datetimes a
| lot, and I can _absolutely understand the maintainers rationale
| behind this_.
|
| Let me explain.
|
| What's a "naive datetime" suposed to be conceptually? There is no
| such thing. Datetimes only make sense in the context of a
| timezone. UTC is just another timezone, with an UTC-Offset of +0
|
| So why do we have this strange thing that may be a UTC timestamp,
| or a local timestamp, or god knows what in the first place? It
| makes sense as an implementation detail of the datetime library
| to have timezones as separate objects, but for consumers of that
| library? It can cause confusion, and hard to track bugs, when
| suddenly one of the functions that accept aware or naive is used
| and spits out something completely unexpected.
|
| I have spent many an hour tracking bugs, where systems spat out
| complete nonsense timestamps, only to discover that the reason
| they do that, is a mixed usage of aware and naive dateteime
| objects.
|
| In my opinion, making explicit use of aware datetime the norm as
| much as possible, is a good thing. And removing prominently named
| functions that spit out naive ones, is a good first step.
|
| Let's look at the listed usecases:
|
| > An application may be designed in such a way that all dates and
| times are in a single timezone that is known in advance.
|
| Okay...so put that TZ info somewhere it's easy to find, like a
| configuration Singleton, and use it.
|
| > It is also a best practice to store naive datetimes
| representing UTC in databases.
|
| Okay...read them from, and into datetime objects using UTC as
| their timezone information.
|
| The bottom line is: There shouldn't be "naive" datetime objects,
| or at least they shouldn't be a common thing. Conceptually,
| datetimes _always_ have a timezone attached, they are worthless
| without one.
| vegabook wrote:
| all true but you miss that naive UTC has become a _de facto_
| standard in many (particularly finance) codebases.
|
| Sometimes conceptual beauty must unfortunately reckon with
| long-established reality. It's basically very late to be doing
| this.
| fishywang wrote:
| The naive time thing in python really is (was) a nightmare. I
| once noticed that a db library we use when storing a timestamp in
| the db would calculate that timestamp from 1970-01-01 00:00:00 at
| _local time_ instead of utc and had to patch that to make sure we
| never store a wrong timestamp in our db (luckily all our
| production servers run on UTC as the local timezone).
|
| Glad that it's finally being addressed at the language level.
| orf wrote:
| I've been using Python for going on 14 years now, and I had no
| idea utcnow() returned a naive date time. I happen to live and
| deploy to a (mostly) UTC time zone, so i expect a bunch of my
| code is subtly wrong.
|
| One of my projects added all of the code in PyPI to GitHub, it
| would be interesting to see how prevalent the use of "utcnow()"
| is.
| arp242 wrote:
| > An application may be designed in such a way that all dates and
| times are in a single timezone that is known in advance. In this
| case there is no need for individual datetime instances to carry
| their own timezones, since this uses more memory and processing
| power for no benefit, since all these timezones would be the same
| and it would never be necessary to perform timezone math or
| conversions.
|
| The memory and processing differences between the two seem
| marginal, at best. Especially when it's at UTC ("plus zero"
| doesn't take too much processing).
|
| So I'm gonna have to ask for benchmarks on this one.
|
| And even _if_ it was slower one must ask if having a confusing
| concept like a naive datetime is worth it. Obviously Python is
| all about the "programmer productivity at the expense of some
| performance" trade-off.
| remram wrote:
| Yeah, both None and UTC are singletons so there should be
| exactly 0 difference in memory usage between a datetime with
| tzinfo=None or tzinfo=UTC.
| blincoln wrote:
| Am I correct that the
| datetime.datetime.now(datetime.timezone.utc) syntax is backwards-
| compatible all the way to Python 3.2?[1] If so, this seems like a
| good move. The edge cases like compatibility with data sources
| that don't indicate the time zone seem like less of an issue than
| data corruption due to developers not realizing that they were
| working with "UTC" timestamps that weren't actually UTC.
|
| I'd be more concerned if this was one of those changes where
| there isn't a good way to write reasonably straightforward code
| that will run in relatively old versions of Python as well as
| newer ones.
|
| [1] https://peps.python.org/pep-0615/
| lowbloodsugar wrote:
| Hahaha. Fucking python. This kind of shit is why you'd be mental
| to use it for anything that can't be rewritten in a day.
| drexlspivey wrote:
| Haha yes you'd have to be crazy to use the most popular
| language in the world.
| qwertox wrote:
| I was recently working with stock data from a Django shop, half
| of their Unix timestamps were correct timestamps, the other half
| had a local timezone offset baked right into the integer.
|
| At least this time finding problematic code will be a grep away,
| so I'm ok with this change, even though I've used it a lot.
|
| Edit: Wow. So Paul Ganssle writes in April "Previously, we have
| documented that utcnow and utcfromtimestamp should not be used ,
| but we didn't go so far as to actually deprecate them [...]"
|
| The linked to issue where this was decided is from Jul-Sep 2019.
| And I've never heard about this. Obviously this is my fault, but:
| where do I need to inform myself to know about these decisions?
| I've been "happily" using them all the time (quoted because we're
| all aware of the challenges these conversions pose each and every
| time).
|
| [0] https://github.com/python/cpython/issues/81669
| pierotofy wrote:
| Python breaking stuff with another minor version update?
| Shocker...
| phendrenad2 wrote:
| The problem with powerful languages is you can misuse them. The
| maintainers are deprecating a perfectly-good API, which is likely
| used by many people, simply because someone, somewhere, might not
| have read the (very clear) documentation and misused it. Maybe
| they should deprecate strftime() and strptime() because someone
| might serialize a datetime and drop the timezone.
| kerkeslager wrote:
| I've noted before and will note again that the amount of hate
| Python got for the 2-to-3 deprecations has led to a much worse
| problem: piecemeal low-visibility updates which are much harder
| to plan for.
|
| As a contractor, I singlehandedly migrated 4 different codebases
| from 2 to 3; a total of just under a million lines of code, and
| none of these codebases took more than 40 hours. This was not
| some horrific burden for most companies using Python. The people
| who flamed Python for these breaking changes were either extreme
| outliers or the sort of people who would be happy with the
| language never making breaking changes, ever, no matter how bad
| of mistakes in design were discovered.
|
| I would strongly prefer that datetime.utcnow were not deprecated
| in a 3.x release, but instead deprecated along with the GIL and
| any other breaking changes, in Python 4.0. Yes, it would get them
| flamed. And the flamers are wrong. At least that way people can
| plan for the transition at their leisure instead of constantly
| worrying that a 3.x release will unexpectedly break their
| codebase if they don't read the release notes before every
| update.
| dheera wrote:
| Deprecation shouldn't break peoples' code all of a sudden. Code
| should still work, and just get more annoying over time.
| Initially, spit out warnings that deprecation is going to
| happen. Then, start changing the user's desktop background.
| Then, start playing nice cat meowing sounds out of the speaker.
| Then, start playing ghastly wailing sounds out of the speaker.
| Then, start sending e-mails. Then, scan for IoT light bulbs and
| mess with the colors. Then, scan for bluetooth headsets within
| a 50 meter radius and play wailing noises out of those. Then,
| impose a 0.001 second delay. Then a 0.01 second delay. Then a
| 0.1 second delay. Then a 1.0 second delay. Then start scraping
| LinkedIn for engineer resumes and e-mail them to any sysadmin
| e-mails you can find in the various config files in /etc/ and
| /home/.
|
| Don't suddenly deprecate stuff and break people's code on a
| moment's notice. Most likely the person who wrote the code
| using the deprecated function was laid off 2 years ago and the
| company still depends on it.
| panarky wrote:
| _> Don 't suddenly deprecate stuff and break people's code on
| a moment's notice._
|
| "Deprecated" doesn't mean "break people's code on a moment's
| notice".
|
| FTA: "datetime.datetime's utcnow() and utcfromtimestamp() are
| deprecated and will be removed in a future version"
|
| "likely a few years out"
|
| "once you switch to Python 3.12 or newer you will start
| seeing deprecation messages on your console and your logs,
| and these can get annoying"
| dheera wrote:
| > will be removed in a future version
|
| It should not be "removed" as a step function. It should
| get more annoying over time but still function for the next
| 30 years, at which point it's incredibly, incredibly
| annoying to call the function (but still works).
|
| This helps products continue running but simultaneously
| incentivizes the people on top to hire engineers to make
| the code less annoying without completely wrecking the
| business or downstream software that depends on it.
|
| Basically, the servers will still run and the customers
| will be happy but if the VP sitting 50m from the servers
| doesn't want cat noises coming out of their headphones they
| need to hire an engineer ASAP or it will turn into wailing
| noises pretty soon.
|
| > you will start seeing deprecation messages on your
| console and your logs, and these can get annoying
|
| Not annoying enough. This only sends messages to someone
| who was probably got laid during the recession and isn't
| around anymore, or some open source repo creator who is now
| being forced to work 18 hours a day by their new job and
| doesn't have the energy to update any code. It needs to
| slowly creep out and annoy _other_ people nearby before
| someone will actually care. When the neighbors constantly
| have wailing noises coming out of their living room TV they
| will be incentivized to contribute to the repo.
| personjerry wrote:
| Who is updating to every 3.x?
| d1l wrote:
| If you maintain a library you'll hear about this kind of shit
| early and often.
| ddxv wrote:
| I don't manage anything too crucial, but I like to keep every
| project I work on updated to the latest Python. I've noticed
| I'm often quite early with this, and help open issues with
| any libraries that are lagging. For example for Py3.12 I'd
| say about half of what I work on is on Python3.12 now. Slower
| projects are 3.11 and those I'm just a user of (like stable
| diffusion) are still on 3.10. I don't know of any projects I
| use that are less than 3.10.
|
| This also is in line with how I am around most tech. I like
| to keep all databases and libraries up to date for security
| reasons.
| Clamchop wrote:
| A typical pattern is to deprecate in minor versions and remove
| in the next major version, encouraging gentle readiness for
| that major update. I don't know enough about Python to say this
| is what they're doing, but it fits in this case.
| OJFord wrote:
| That's not what they do, in semver terms you get breaking
| changes in minor version bumps.
|
| To be fair, as a result there's maybe more resistance to
| making any such change than there otherwise would be, but in
| nicher standard lib modules there are API/semantic changes
| from one version to another.
|
| I'd prefer semver, like it sounds GP would, but failing that
| I'd prefer totally owning that the version is fairly
| meaningless, and doing something like 2023.x as pip does for
| example. At least then everyone _knows_ they should check for
| anything like that. (Not to mention it carries the additional
| age /potentially out of date information.)
| nemothekid wrote:
| > _I may be missing something here, but I don 't really follow
| this logic._
|
| Isn't the logic that throwing an error on naive timestamps would
| break existing code?
| rtpg wrote:
| It's pretty disappointing to see this article make claims like
| "web developers just use naive datetimes".
|
| I think anyone who does anything nontrivial with datetimes should
| always use non-naive datetimes (unless you have a really really
| really good reason to)
|
| Even when I started doing Python web dev 10 years ago this
| knowledge was bestowed upon me and has saved me many headaches
| (and helped me find bugs in third party code). The fact this
| article claims otherwise makes me doubtful of other advice given.
|
| Unfortunately, Pythons date/datetime APIs make it way too easy to
| do the wrong thing on this topic.
| ape4 wrote:
| Stackoverflow on this
| https://stackoverflow.com/questions/15940280/how-to-get-utc-...
| tzs wrote:
| The timezone thing in Python that bit me was when I needed to
| parse a time string. Googling told me Python had strptime and it
| would do what I wanted. So I found it in the Python docs and used
| it.
|
| What I failed to notice was that Python has two strptime
| functions, one in time and one in datetime, and they are not the
| same. I was losing timezone information that was in my time
| strings, and when I wrote a test program to just test timezone
| parsing I happened to pick the other strptime and everything
| worked fine, which left me quite confused.
| NelsonMinar wrote:
| Python could be better but really, does any language handle date
| and time types well? After 30+ years of this I mostly just use
| seconds since epoch everywhere like some sort of caveman banging
| rocks together. But at least it works clearly.
|
| Last I looked Pendulum was the best choice for a fancy but humane
| Python library for dates and times. Install size is over 4MB :-(
| https://pendulum.eustace.io/
___________________________________________________________________
(page generated 2023-11-19 23:00 UTC)