9 ms·
2020 Leap Day Bugs
- hmate9 7y agoThis is why no one should ever ever write their own Time or Date library. The number of edge cases is simply enormous
- velox_io 7y agoAsk Jon Skeet: https://blog.nodatime.org/2011/08/what-wrong-with-datetime-anyway.html https://blog.nodatime.org/2011/08/what-wrong-with-datetime-a...
- hyperpape 7y agoWhen you encounter someone saying "no one should ever", you can substitute "fewer than a half dozen groups of people should tackle this problem (in systems they want to use in production). It will take each such group a tremendous number of hours, involving a multi-year process of slowly finding edge cases and missing functionality." If that's not true, then there's room to complain, but dates and times fit the bill. In some ways they're worse than other "harder" problems, because people are more likely to think those harder problems are too hard for them. And while the vast majority of companies don't need a proprietary database, it's more likely to be a competitive advantage than your own datetime library. I think I could eventually write a good datetime library. But I certainly should not, unless I decide that's going to be one of my major efforts to help a language that doesn't already have one.
- maxerickson 7y agoWhat if people tried to speak precisely for effect instead of hyperbolically for emphasis?
- jrandm 7y agoI believe accurately conveying identical information in a manner everyone can understand is an impossible, or at least unreasonable, burden to place on individuals. Instead, what if people tried to hear graciously and "assume good faith"? The quote is ripped from HN's guidelines.
- maxerickson 7y agoCan you please explain more about how your response relates to my comment? For instance, I've not placed the burden of "conveying identical information in a manner everyone can understand" on anyone, nor have I assumed bad faith. So it seems like a weird comment to tack onto mine, but I am assuming I just don't correctly understand.
- IggleSniggle 7y agoHyperbole and precision can get tricky in human language because different cultural groups have different language encodings for the same sets of words. For example, if you live in London then "9 in the morning" means when the world synchronized clocks agree that, locally for you, the time is 9am. But if you say "9 in the morning" to someone in Belize, it means "first thing after you are finished with your morning and ready to start your day," which can mean 1pm in some cases. Here's a lovely article on these kind of time-keeping differences, around something that you might expect to have a precise meaning: https://www.businessinsider.com/how-different-cultures-understand-time-2014-5?op=1 https://www.businessinsider.com/how-different-cultures-under... More to the point at hand, however, you suggested that people not speak in hyperbole but instead speak accurately. Although you can request that others adjust their use of language while in your presence to better meet your needs for a certain kind of precision, policing other people's language isn't possible. However, re-interpreting what people say into what they mean is somewhat possible for an astute listener who understands the context.
- maxerickson 7y agoYou are making my simple statement really complicated. I'm not walking around demanding people change their communication to accommodate me, I'm suggesting that trying to speak precisely can be a useful exercise.
- wwweston 7y agoPrecision of understanding would go up and emotional investment in a topic would likely be more proportional to true stakes? Sounds boring but functional.
- 76543210 7y agoHow about C rtos? How should that be handled?
- Misdicorl 7y agoAlmost all the edge cases with time have to do with localization. Build your time library on (un)signed 64 bit integers representing the number of nanoseconds since the utc epoch. Adjust above sentence to reflect the level of precision and range your use case needs. You are now done for 80% of use cases (perf timing, logging, timeouts, event storage, event ordering within jitter). If you need to parse/display for humans or have something happen at a particular time in a particular timezone, things get gross. But that's no different than any other situation where you eventually have to interface machine data with humans. Either it's your particular expertise or it's a distraction and you should use someone else's solution.
- burfog 7y agoYou can still have problems. It may be determined that the computer's clock got too far ahead. For example, it booted and you cared about time, but NTP hadn't yet made corrections. Suddenly the time runs backwards. Leap seconds may get interesting too, especially if you have to predict ahead or if the OS isn't updated often enough. (there is a 6-month warning) If you want to call leap seconds an issue for humans, then you aren't using UTC at all. You're using TAI. Software interfaces often ignore the distinction between UTC and TAI, and even between UTC and UT1, preferring to pretend these issues don't exist. POSIX is in conflict with international timekeeping, effectively requiring that there are zero leap seconds.
- Misdicorl 7y agoLeap seconds are only a problem for wall clocks (localization) and deciding whether to call something utc or tai. The ntp case is contrived. Either you care and wait until ntp has connected to do your stuff. Or you care and don't let ntp rewind and instead smear. Or you don't care and deal with the consequences.
- mortehu 7y agoLeap seconds affect Unix time too, because leap seconds are excluded from "number of seconds since Unix epoch". You can't measure the length of time intervals spanning leap seconds with simple subtraction.
- ehsankia 7y agoIt's not only about writing your own library though. For example, it's often not reading the documentation properly. In Python, if you take a datetime, and call .replace(year=X) on a datetime for Feb29, it'll throw a ValueError.
- Aeolun 7y agoEven if you replace it with another leap year?
- cgriswald 7y agoIt returns a new datetime object which includes its own validity check and raises an exception for a bad leap day the same way it would for March 32nd or Blurnsuary 12th. (However, year must be an integer in [1, 9999].) Edit: So, another leap year would be fine.
- ehsankia 7y agoNo another leap year would be fine. But yeah a very common (wrong) pattern is, if you want to find the same day a year in advance, is to do `d.replace(year=d.year + 1)`, and that would break on Feb 29 only, so one day every 4 years. It's a very common pattern unfortunately.
- perl4ever 7y agoWhat if you take March 31st and add one month to it? (I assume you can do that somehow)
- deathanatos 7y agoNot with the standard library. (The "timedelta" class only expresses in units up to days, as it is ambiguous how long a month is. There's a nice package called "python-dateutil" that includes a "relativedelta" class; adding a month to March 31 results in April 30: In [7]: datetime.datetime(2020, 3, 31) + dateutil.relativedelta.relativedelta(months=1) Out[7]: datetime.datetime(2020, 4, 30, 0, 0) Adding a year to a leap day: In [8]: datetime.datetime(2020, 2, 29) + dateutil.relativedelta.relativedelta(years=1) Out[8]: datetime.datetime(2021, 2, 28, 0, 0) The exact duration that relativedelta adds depends on what you add it to. (Hence the name.) But the results tend to match up with human expectations.
- PopeDotNinja 7y agoImmediately thought of Tom Scott's Computerphile video on time & timezones: https://youtu.be/-5wpm-gesOY https://youtu.be/-5wpm-gesOY 10m12s watch. Informative and entertaining.
- user982 7y agoA line in one of my Python daemons has been crashing it repeatedly all day: isotime = datetime.strptime(time.get('title'), '%a %d %b %I:%M:%S %p').replace(year=YEAR, tzinfo=TZ).isoformat() ValueError: day is out of range for month It's not mission-critical, so I'm just going to wait it out until tomorrow. EDIT: Hacked it out. isotime = datetime.strptime(f"{time.get('title')} {YEAR} {tzoffset:+03d}00", '%a %d %b %I:%M:%S %p %Y %z').isoformat()
- 1wd 7y agohttps://bugs.python.org/issue26460 https://bugs.python.org/issue26460
- phoobahr 7y agoThat strap time parsing doesn't fail under python 2.7.17 or 3.8.1
- user982 7y agoPython 2.7.17 (default, Dec 31 2019, 23:59:25) Type "help", "copyright", "credits" or "license" for more information. >>> from datetime import datetime >>> datetime.strptime('Sat 29 Feb 12:00:00 PM', '%a %d %b %I:%M:%S %p') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: day is out of range for month
- park_94110 7y agoThis is because 1900 is the default year in datetime. 1900 was not a leap year.
- user982 7y agoI know, I'm just providing a counterexample to phoobahr.
- detaro 7y agoInteresting. Given the documentation of strptime, I would have expected that to not be possible at all (since constructing a datetime without a year isn't possible directly)
- ddevault 7y agoHere's mine: https://git.sr.ht/~sircmpwn/meta.sr.ht/commit/e0be9dcd8e96f952547c243e078c47571f54fca2 https://git.sr.ht/~sircmpwn/meta.sr.ht/commit/e0be9dcd8e96f9...
- progval 7y agoI was about to ask why you didn't use a timedelta, and then found out that datetime.timedelta doesn't support anything greater than week. It also has this incorrect example: https://docs.python.org/3/library/datetime.html#examples-of-usage-timedelta https://docs.python.org/3/library/datetime.html#examples-of-...
- kgabbott 7y agoI respect wanting or needing to do this with just the builtin datetime module. For everyone else, I recommend relativedelta from the dateutil package: https://dateutil.readthedocs.io/en/stable/relativedelta.html https://dateutil.readthedocs.io/en/stable/relativedelta.html e.g.: >>> from dateutil.relativedelta import relativedelta >>> date = datetime.utcnow().date() >>> date datetime.date(2020, 2, 29) >>> date + relativedelta(years=1) datetime.date(2021, 2, 28)
- mj1586 7y agoI added to here: https://stackoverflow.com/a/60468711/634824 https://stackoverflow.com/a/60468711/634824 Thanks.
- est31 7y agoJust solve it the Google way: https://xkcd.com/2266/ https://xkcd.com/2266/
- anonsivalley652 7y agoStupid Q: Why doesn't the syslog protocol (RFC5424) deal with leap seconds (the seconds field goes to 00-59, not 00-60)? Are they using UTC (they would have to ignore LS and have crappier logs) or TAI (doesn't have LS)? https://mailarchive.ietf.org/arch/msg/syslog/DDLgKsRPITFXYSBzicpbqTwtbk8/ https://mailarchive.ietf.org/arch/msg/syslog/DDLgKsRPITFXYSB... http://www.madore.org/~david/computers/unix-leap-seconds.html http://www.madore.org/~david/computers/unix-leap-seconds.htm... https://tools.ietf.org/html/rfc5424 https://tools.ietf.org/html/rfc5424 https://cr.yp.to/libtai/tai64.html https://cr.yp.to/libtai/tai64.html https://cr.yp.to/libtai.html https://cr.yp.to/libtai.html
- wtallis 7y agoIs there a real need for syslog to handle leap seconds? As that email you linked to points out, most implementations are likely to screw it up to some extent; requiring everyone to ignore leap seconds seems to narrow the range of possible behaviors. It also strikes me that syslog timestamps aren't something you should be depending on too heavily in the first place, especially not for things like calculating precise time durations between separate messages.
- anonsivalley652 7y agoTwo wrongs don't make a right, but three lefts do. Throwing shade without evidence doesn't demonstrate professionalism, it demonstrates laziness. Correlation on high-volume production systems requires precise timestamps all the time.
- wtallis 7y ago> Throwing shade without evidence doesn't demonstrate professionalism, it demonstrates laziness. Who's throwing shade?
- burpsnard 7y agoit's bad enough guessing dmy or mdy, without wondering if we earned interest on that 10 billion euros that appears to have spent an entire second in a transit account earning 2.7% per annum (legal think 'annum' implicitly includes the leapsecond, an assurance resting on dozens of assumptions and misunderstandings of many ibscure treaties and standards and policies, modulo the case law in jurisdictions where precedents can redefine)
- dictum 7y agoRandom thought: we're now closer to 2038 than to Y2K.
- martin-adams 7y agoand only heading in that direction
- gumby 7y agoSpeak for yourself.
- ge96 7y agowhat does this mean? you're okay if you're using 64bits? just briefly skimmed the 2038 wikipedia page, mentioned 32bit
- onei 7y agoIf you store time as seconds since the Unix epoch (1st Jan 1970), you'll overflow a 32 bit unsigned integer in 2038 (around March iirc) and time will suddenly be back in 1970 again. I believe the Linux kernel did some work to circumvent this on 32 bit systems in a recent release, but if you're running an old 32 bit system you're probably out of luck.
- FreeFull 7y agoActually, it's signed 32-bit integers that overflow in 2038. Signed integers have been used because people wanted to store dates earlier than 1970 too.
- adrianmonk 7y agoAnd probably because signed integers are a default choice in certain languages and/or maybe on certain architectures. Java, for example, famously doesn't even have an unsigned 32-bit integer primitive type. (But it has library functions you can use to treat signed integers as unsigned.) Ultimately not a good design choice, but the fact that it actually wasn't that limiting and relatively few people care or notice tells you that many people have a mindset where they use signed integers unless there's a great reason to do something different. Aside from just mindset and inertia, if your language doesn't support it well, it can be error-prone to use unsigned integers. In C, you can freely assign from an int to an unsigned int variable, with no warnings. And you can do a printf() with "%d" instead of "%u" by mistake. And I'm fairly sure that converting an out of range unsigned int to an int results in random-ish (implementation-defined) behavior, so if you accidentally declare a function parameter as int instead of unsigned int, thereby accidentally doing an unsigned to signed and back to unsigned conversion, you could corrupt certain values without any compiler warning.
- xxpor 7y agoI haven't been able to figure out if this is a Google issue or King County Metro issue yet, but google maps transit directions are completely broken today. Every suggestion is "take Lyft" or wait until 4 am tomorrow.
- indecisive_user 7y agoInteresting observation. I played around with it a little on google maps. It says it pulls route information directly from the King County transit website[1] which lists routes by the day of the week, not by the date, and seems to be displaying the routes for today just fine. My guess is that it's a Google issue, but maybe the King County transit website was broken earlier today and gmaps is just serving the cached routes now. For anyone curious, this is what it currently looks like to get from Bellevue to Redmond in google maps. https://i.imgur.com/wMTIzBL.png https://i.imgur.com/wMTIzBL.png [1]https://kingcounty.gov/depts/transportation/metro/schedules-maps/route/b-line.aspx https://kingcounty.gov/depts/transportation/metro/schedules-...
- rachelbythebay 7y agoLet's not forget the stuff that'll break December 31, 2020... because it'll be day 366 (or 365, if 0-indexed). Anyone still using a Zune out there?
- kclay 7y agoI have an old Zune. Going give this a try this year
- swypych 7y agoFor the lazy https://www.theguardian.com/technology/blog/2009/jan/01/zune-firmware-mistake https://www.theguardian.com/technology/blog/2009/jan/01/zune...
- henriquemaia 7y agoWell... thanks. But not because I'm lazy, for I had no idea about this bug there. I just thought OP had an off topic moment based on random connection. But now, after reading your link and giving it a bit of thought, what s/he wrote makes perfect sense even without your link. So... thanks.
- Kipters 7y agoZune HD user here (albeit it's been sitting on my desk lately...) I'm definitely going to try it
- imperialdrive 7y agoThe bulk of our deployed Yealink T56 phones displayed February calendar events for the wrong day. I never did find out why.
- pm215 7y agoI hear this is a firmware bug, and should automatically sort itself out once we hit March (but there is a bugfixed f/w due too). My pet theory/guess was that there was a misimplementation of some algorithm like Zeller's congruence (https://en.m.wikipedia.org/wiki/Zeller%27s_congruence https://en.m.wikipedia.org/wiki/Zeller%27s_congruence) for calculating the day of the week, which works on an adjusted year starting in March, because I couldn't come up with any other reason why a leap year bug would manifest for all days before feb 29 and then not thereafter. But there is probably a duller explanation :-)
- geforce 7y agoMy car clock went back from 2:00AM to 12:00. I was really wondering what happened.
- tech234a 7y agoMy Timex Expedition watch also skipped to March 1.
- makomk 7y agoThat's fairly normal for older or more basic digital watches - they don't know anything about the year, so every four years you have to manually set them back the 29th of February. I think that people see this as a bug says something about changing expectations. Pre-digital watches generally didn't know about months either, so required manual date adjustment every other month. The framing of this manual adjustment as a bug feels like it comes from our experience of dealing with computer software all the time.
- schoen 7y agoOr from dealing with more recent digital watches that do know about the year.
- a3n 7y agoTimex Ironman bought within the last two years, almost certainly less than $20, says 3/1 Sat today. The numbers on the back might say "029 36". Or maybe "029 56". I'm sure its innards are the same as most of the other sub-$20 Ironmans.
- gerikson 7y agoIn mechanical watches, that's the difference between an annual calendar, and a perpetual calendar. Annual calenders don't take leap years into account, perpetual calenders do.
- sproketboy 7y agoM$ loser shill.
- btmiller 7y agoLinkedIn has one! Yesterday it listed my time with my current employer as 2 years and 9 months. Today, it’s 2 years and 8 months! Can anyone venture a guess on how I time traveled?
- jobigoud 7y agoHappy -1st of February.
- andreygrehov 7y agoSo happy to see Timehop in this list. I was a little worried about releasing not-a-bug-but-a-feature, but it played out great :)
- mj1586 7y agoI love the image, BTW! :)
- JensenDied 7y agoI ran into this already on January first. Someone in the last 4 years changed/created a function in a MUD that I now maintain, to convert Unix timestamps into iso8601 strings for MySQL. They did the math for which year is a leap year incorrectly, which wasn't the bug that bit us, they helpfully added the leap day regardless of where in the year it was. The tests they wrote targeted the middle of the year and missed it. I just pulled in date2j and related match from postgres, added more test cases.
- Yessing 7y agois there something special about 2020 (regarding leap years)? the rule I know is divisible by 4 && ( not divisible by 100 || divisible by 400) so 2020 is not even an edge case.
- marcosdumay 7y agoLeap days are an edge case by themselves, it doesn't need any extra thing special about it.
- stOneskull 7y agoOver 4 years there are a lot more apps and a lot more reliance on apps. There's lots more spaghetti out there since 2016 so more likelihood of bugs. I assume 2024 will have more.
- HocusLocus 7y agoI think the answer you were looking for was, apparently NO there is nothing special about 2020 in relation to this problem. Despite the misleading use of year 2020 in the title and the title of the linked page, what is being experienced is a simple mis-coding of year+1 calculations. The title could have been, "Leap day bugs, again! People, must we go through this every 4 years?" So this is a crop of bugs that are either code written in the last 4 years or untested/unnoticed/unreported 4 years ago. One of the Sprint examples (someone roaming between two cell towers and their date changing back and forth) is especially disturbing.
- blowski 7y agoOr there's an unfinished ticket in the backlog that says "Oh gosh, let's just bodge all these values in the database and make sure we fix it by the next leap year".
- macintux 7y agoI do wonder whether the fact that some systems aren’t really 4-digit-year compliant is making this uglier this year. I know Splunk got hit with a 2020 bug.
- tzs 7y agoSears appears to have have taken this to a new level. I got two emails from them today. The first arrived at 6:36 AM, with subject > Confirmed! Your mystery Leap Year offer awaits inside. How much will you save? The second arrived at 9:54 AM, with subject > Oops! Your code is fixed. (We shoulda looked before we leap-yeared...) The messages themselves appear to be identical except for some query parameters on some URLs, so I'm guessing that whatever they botched for leap year was on the server when one tried to respond to the offer. Botching Feb 29 in general date handling code is embarrassing, but there is it least a somewhat plausible excuse that you just forgot about that special case. But botching Feb 29 in code that is meant to only work on Feb 29? Wow.
- scarmig 7y agoBotching is pretty ungenerous. All of the above can easily happen in the context of a complicated software system. Experienced people who avoid these issues are mostly experienced with smashing headfirst into one of these tricky areas and approaching them with an attitude of "here be dragons" afterwards. One bitten, twice shy.
- mercora 7y agohuh! i just noticed few hours ago a pi i use has had the wrong date which was set to a day earlier. I quickly determined a faulty ntp server i had hard configured was giving the bogus time. In case it is of interest its address was "144.76.60.190" and was chosen by random chance because i cant resolve names without working time on that machine (don't ask). It appears to be taken offline by now though but i checked its giving the wrong time before changing to another server. Also, but probably unrelated, my WiFi stopped working exactly 00:00AM CET but that might be unrelated as it does that all the time :)
- susam 7y agoI learnt the following test for leap year early in my software engineering career from the book "The C Programming Language" by Kernighan & Ritchie (see section 2.5 Arithmetic Operators): (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 The following test also works: year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
- thaumasiotes 7y agoFor those who were curious why these could both work: (A & B) | C differs from A & (B | C) in two cases: when A is false, C is true, and B is any value. But in this case in particular, those differences would create a bug when A is false (the year is not divisible by 4) at the same time that C is true (the year _is_ divisible by 400). Since that can't happen, the bug cannot occur.
- davedunkin 7y agoMy bank, IberiaBank, deposited interest and sent out statements today, with them being dated March 1.
- jeromebaek 7y agorelevant: falsehoods programmers believe about time https://news.ycombinator.com/item?id=4128208 https://news.ycombinator.com/item?id=4128208
- imroot 7y agoLogRocket is reporting every date as Feb 28, 2020.
- smallstepforman 7y agoSo frustrating that my embedded code works without a hitch and our company is nearly bankrupt, while our bank with billions of dollars in annual profit goes offline since it cant handle leap years.
- system2 7y agoConsidering billions of devices and services not being affected, these bugs are very insignificant. At least we figured out leap day bugs and not having y2k crisis' every four years.
- xmdx 7y agoI think I found one. My Amex bill is due on the 29th and I have a direct debit to pay it automatically. However it never got taken. First time this has ever happened. Let's see if it happens today since it's now the 1st.
- ginko 7y agoI'm kinda surprized that date libraries break with a simple leap year like 2020. I'd have more understanding if it happened with the year 2000(leap year) or 2100(not a leap year), but the basic "is year divisible by 4" check should be good enough until 2100.
- lamby 7y agoDoes anyone remember the fail2ban issue where it used 100% CPU for the entire day?
- hipjiveguy 7y agoI deposited a cheque using the ScotiaBank mobile app on March 1, and when I looked at it on my online banking page, it said that it was deposited on March 2! Seems hard to believe that a mobile app would be allowed to tell the server what time the cheque was deposited!