[HN Gopher] Ask HN: Did you encounter any leap year bugs today?
       ___________________________________________________________________
        
       Ask HN: Did you encounter any leap year bugs today?
        
       After a frantic scramble this morning, our billing team has
       finished patching a bug which erroneously was charging our monthly
       subscribers for an extra day.  All test suites are passing now, and
       SRE has scheduled a postmortem after the QA confirms the fix in
       2028.
        
       Author : sjr1
       Score  : 109 points
       Date   : 2024-02-29 20:22 UTC (2 hours ago)
        
       | stop50 wrote:
       | Can't you just backdate some servers to confirm the fix?
        
         | murderfs wrote:
         | That's generally risky to do nowadays because of things like
         | TLS certificate expiration.
        
           | Retr0id wrote:
           | In a few hours you'll be able to backdate to "yesterday",
           | with very low chances of hitting cert expiry issues (but I
           | wouldn't be surprised if OP's issue involves components
           | outside of their control or ability to test end-to-end)
        
             | murderfs wrote:
             | I should have written something along the lines of
             | "validity date ranges" instead of expiration: you're much
             | more likely to run into problems where you run into a
             | certificate that was issued in the future relative to when
             | you think is now.
        
         | abathur wrote:
         | Not directly related to leap year, but a couple weeks ago I set
         | up a script for testing notification behavior that used
         | libfaketime to simulate runs at different times.
         | 
         | I guess this might be less-trivial if you've got a distributed
         | multi-service architecture and perhaps also depend on APIs that
         | aren't under your control in the first place.
        
           | stop50 wrote:
           | Set up a backdated timeserver and use that to sync time
        
       | mirekrusin wrote:
       | We had test failing that had to be skipped and worked out in the
       | background.
        
       | rlaager wrote:
       | One cleanup script broke because Python doesn't have a clean way
       | to subtract a year, and if you do now.replace(year=now.year-1),
       | you get a ValueError when now is 2/29.
       | 
       | It's easy enough to address. There are various StackOverflow
       | posts on such things. Here is one:
       | https://stackoverflow.com/questions/54394327/using-datetime-...
        
         | aiiane wrote:
         | What is your definition of "subtracting a year"? Seems like
         | that's a relatively ambiguous operation without more
         | specification.
        
           | kccqzy wrote:
           | Since they mentioned a clean up script, I assume they could
           | easily just use 365 days for that use case.
        
             | hinkley wrote:
             | But then it'll be off by one day for the rest of this year.
             | And someone will notice that they no longer have March 1
             | 2023-March 1 2024 in their chart, but March 2 2023
        
               | kccqzy wrote:
               | It's a cleanup script. I bet nobody cares it's off by one
               | day. Also I doubt a cleanup script has a charting
               | function.
        
           | Ensorceled wrote:
           | Can you think of any situation where subtracting a year from
           | today's date is ambiguous when today isn't, well, today?
        
             | aiiane wrote:
             | Yes - on any day, subtracting a year might mean subtracting
             | the average length of a year (which is a bit more than 365
             | days), or wanting the same day and month number in the
             | previous calendar year, or wanting the same semantic
             | difference ("last Monday of the month in January"), to name
             | a few possible meanings.
        
             | JohnFen wrote:
             | Worth a mention... Falsehoods Programmers Believe About
             | Time: https://news.ycombinator.com/item?id=4128208
        
             | OJFord wrote:
             | Moving bank/festive holidays, first Monday of the year(,
             | first work day of the year not Monday if that's NYD and
             | bank holiday), lunar occasions.
             | 
             | 'subtract a year' is imprecise and has many meanings, if
             | what you want is 'same day, same month, previous year' then
             | say that and do that, that's conceptually `date.year -= 1`
             | not `date -= 1 year`, and will have this bug.
        
         | natrius wrote:
         | It's not that python doesn't have a clean way to subtract a
         | year, it's that "subtract a year" is imprecise. There's a clean
         | way to subtract 365 days, and there's a clean way to set the
         | year one year earlier. But if you're doing the second thing, is
         | python supposed to silently change to March 1 when you change
         | the year from a leap day? There's no way around handling edge
         | cases.
        
           | Swenrekcah wrote:
           | APy should just figure out what I would have wanted to happen
        
         | VirusModulePtr wrote:
         | Okay I am having really odd undefined behavior in Python in
         | UART communications that were working just fine yesterday... My
         | boss joked it could be a leap year thing but at this point it
         | wouldn't surprise me. Switch over to using Rust and no issues
         | at all
        
         | LeoPanthera wrote:
         | > now.replace(year=now.year-1)
         | 
         | Yeah but this is bad code. Python certainly does have a "clean"
         | way to subtract a year, you subtract a datetime.timedelta
         | object.
        
         | iooi wrote:
         | which is why you should use arrow
        
         | cmgriffing wrote:
         | I get it if you don't want to bring in another dependency, but
         | Arrow has a lot of nice utility methods:
         | https://arrow.readthedocs.io/en/latest/guide.html#replace-sh...
        
       | ThrowawayTestr wrote:
       | A fiber cable was cut so we had no internet for the morning,
       | probably not leap year related.
        
       | williamstein wrote:
       | I have some unit tests for billing and subscription code for my
       | company that started breaking in CI today due to the leap day:
       | https://github.com/sagemathinc/cocalc/commit/8575029c2b76787...
        
       | Frummy wrote:
       | The mcdonalds order waiting thing malfunctioned, displayed
       | de52hg04 instead of 088 and I had to wait a lot longer for my
       | order since it flew under the radar for a while until I spoke to
       | them :)
        
       | acheron wrote:
       | Just hope the King of Sweden doesn't make another February 30.
       | https://www.timeanddate.com/date/february-30.html
        
         | ulkis wrote:
         | Let's just be happy that it isn't still the day after February
         | 24 that becomes the inserted leap day. https://www.isof.se/lar-
         | dig-mer/kunskapsbanker/lar-dig-mer-o...
        
           | bombcar wrote:
           | We should just do what we do for time changes and do feb 28
           | over again.
        
         | dasil003 wrote:
         | Every time I go to timeanddate.com I feel like I see a link to
         | the Leap Day page (https://www.timeanddate.com/date/leap-
         | day.html) that shows the meme-infamous boyfriend-checking-out-
         | another-girl couple, except she's proposing to him! Obviously
         | this happened earlier that day since they're wearing the same
         | outfits, and I can't help but feel bad for her knowing what's
         | coming but unable to warn of the impending train wreck.
        
         | TheRealPomax wrote:
         | I'll take a February 30 if it means every other month is 30
         | days too, and we just get the extra days as universal, extended
         | winter holiday where no one can legally be required to work
         | because there is no December 31st or January minus-fourth.
        
       | tdhopper wrote:
       | My sister is staying in a hotel and all the keycards stopped
       | working.
        
         | ant6n wrote:
         | What happens in a situation like this? Does the staff issue
         | physical keys? Do the doors even have manual locks? Do the
         | staff walk every body to their room?
        
       | nortlov wrote:
       | The Casio F-91W doesn't account for the year, it showed today's
       | date as Thursday, March 1st.
        
         | bakoo wrote:
         | Same with my colleagues most recent top model Samsung Galaxy
         | Watch :]
        
           | dotnet00 wrote:
           | Odd, mine is showing the right date.
        
             | davchana wrote:
             | Are you sure? My F91W doesn't even ask for year in
             | settings. How would have it known it is a leap year or not.
             | 
             | Some other models (not F91W) does track year.
        
               | dotnet00 wrote:
               | I was responding to the claim about the Samsung Watch not
               | showing the right date, I unfortunately have never owned
               | the older kinds of "smartwatches" :)
        
           | linker3000 wrote:
           | OK on my Watch4 Classic FWIW.
        
           | frankgrimesjr wrote:
           | Are they using a third party watch face? My Galaxy Watch 4
           | has no issues.
        
         | spicybright wrote:
         | Thank you so much for the reminder, that would have screwed me
         | up today :)
        
         | LeoPanthera wrote:
         | That's more of a design decision than a bug. It's intentional
         | to make the product cheaper. The manual does mention it.
        
         | tjvc wrote:
         | I noticed this too and clicked this thread wondering if it
         | would show up! Still an awesome watch.
        
       | bdangubic wrote:
       | https://twitter.com/EAHelp/status/1763192739322085598
        
       | napoleongl wrote:
       | One of the largest food store chains in Sweden had their entire
       | card payment go down because someone forgot to handle leap years!
        
         | livrem wrote:
         | Wikipedia says they are "the second largest retail company in
         | the Nordic countries[citation needed]". Pretty big company
         | anyway and embarrassing for them. Would love to learn more
         | about what the bug was, but I guess they will never say.
         | 
         | https://en.wikipedia.org/wiki/ICA_AB
        
           | vinay427 wrote:
           | Is that intended as a correction? It's a different claim, as
           | far as I can tell, and the data I could find points to ICA in
           | fact being the largest supermarket chain in Sweden by
           | turnover.
           | 
           | https://www.esmmagazine.com/retail/top-5-supermarket-
           | retail-...
        
             | livrem wrote:
             | No disagreement, just additional information.
        
         | hinkley wrote:
         | This isn't even one of the weird years!
         | 
         | Is this why we can't have nice things?
        
       | amatix wrote:
       | > A number of New Zealand petrol pumps stopped working on
       | Thursday due to a "leap year glitch" in payment software, fuel
       | stations and the payment service provider said.
       | 
       | https://www.reuters.com/world/asia-pacific/leap-year-glitch-...
        
         | PlunderBunny wrote:
         | I'm sure it's more complicated than "we didn't think about leap
         | years", but it certainly sounds pretty amateurish.
         | 
         | Old programmer rant: In my day, we fixed the Y2K bug - we went
         | to the future and back several times a day!
        
       | jung_j wrote:
       | There was one in the Phoenix Framework (Elixir) about issuing
       | certificates with an invalid end date:
       | https://github.com/phoenixframework/phoenix/issues/5737
       | 
       | Interestingly, Azure had this bug some years ago too leading to
       | an outage. https://azure.microsoft.com/en-us/blog/summary-of-
       | windows-az...
        
       | evanb wrote:
       | Payroll software at work had a one-off planned maintenance day
       | today, presumably to avoid worrying about any bugs.
        
         | dasil003 wrote:
         | lucky it didn't fall on a payday eh?
        
         | zie wrote:
         | Today is a payday for us, worked great!
        
       | internetter wrote:
       | I'd suggest not waiting 4 years to publish a postmortem, if
       | you're serious
        
       | 1-more wrote:
       | EA Sports WRC has a bug that can be fixed by setting the date to
       | March 1st. https://twitter.com/EAHelp/status/1763192739322085598
        
       | KomoD wrote:
       | Yes.
       | 
       | > During the morning on Thursday, no ICA store in Sweden could
       | accept card payments. Instead, you had to use cash, Swish or pay
       | via their app.
       | 
       | > The reason behind the problem was an internal problem in the
       | payment systems at ICA as a result of an extra day in February,
       | leap day.
       | 
       | ICA being the biggest grocery store chain in Sweden
        
       | kccqzy wrote:
       | Heard from a friend in China: the age calculation portion of the
       | app to schedule a marriage certificate had a bug where they
       | subtracted 22 (legal minimum age) from the year, which resulted
       | in 2002-02-29 which doesn't exist. The app intends to compare
       | this against the user's birth date. The error handling code
       | assumes all errors are from the comparison. The app then rejected
       | all marriage certificate appointments by complaining that the
       | users are too young to marry legally.
        
         | chaorace wrote:
         | Haha, that would be quite the appropriate place to put one of
         | those "Please wait and try again" error messages.
        
       | jonsagara wrote:
       | Here's a blog post that is tracking issues:
       | 
       | https://codeofmatt.com/list-of-2024-leap-day-bugs/
        
       | webel0 wrote:
       | Yes, Hesai LiDAR [1] bug is grounding cars.
       | 
       | [1] https://pandaily.com/hesai-technology-addresses-lidar-
       | produc...
        
       | pavon wrote:
       | No, but some of our software writes data to rotating directories
       | named after the date, and while doing some manual debugging on a
       | test system, it started failing to create these directories the
       | first time it rotated on Feb 29 UTC. Turns out it just happened
       | to run out of disk space at that time, but I had myself convinced
       | that it was a leap year bug for over an hour. :)
        
       | bregma wrote:
       | Python.                   cls = <class 'datetime.datetime'>,
       | data_string = 'Feb 29 04:55:03.687' format = '%b %d %H:%M:%S.%f'
       | E       ValueError: day is out of range for month
        
         | herpderperator wrote:
         | Interesting... I suppose that is because there is no year? What
         | year does it default to? Can you show your exact line of code?
        
         | derefr wrote:
         | That doesn't seem incorrect; given that no year is specified,
         | it seems like it's evaluating the constraint in the context of
         | an implicit default year. (1970? 0CE?)
         | 
         | The confusing part, to me, is that Python would consider the
         | above string to be parsed into a date in the first place, given
         | that it has no year.
        
         | nicholasjarnold wrote:
         | confirmed. and interesting/unexpected! this breaks:
         | 
         | datetime.strptime('Feb 29 13:37:06.942', '%b %d %H:%M:%S.%f')
         | 
         | edit: added code example. import datetime from datetime first
         | obvi
        
         | LeoPanthera wrote:
         | That's because you didn't specify a year.
        
         | ptx wrote:
         | As mentioned by sibling comments, it's because you're not
         | specifying a year. If you change the day to the 28th you'll see
         | that it defaults to the year 1900:                 >>>
         | datetime.strptime('Feb 28 04:55:03.687', '%b %d %H:%M:%S.%f')
         | datetime.datetime(1900, 2, 28, 4, 55, 3, 687000)            >>>
         | datetime.strptime('Feb 28 13:37:06.942', '%b %d %H:%M:%S.%f')
         | datetime.datetime(1900, 2, 28, 13, 37, 6, 942000)
        
           | OJFord wrote:
           | That makes it weird though, because 1900 _was_ a leap year? I
           | sort of get it, but it 's a slightly odd and inconsistent
           | decision.
        
             | pxx wrote:
             | 1900 was not a leap year... It's 0 mod 4, yes, but it's 0
             | mod 100 and not 0 mod 400
        
             | jesprenj wrote:
             | It wasn't. https://learn.microsoft.com/sl-
             | SI/office/troubleshoot/excel/...
        
       | davchana wrote:
       | My Casio F91W I assumed would know that year YYYY is leap, and
       | would show 29th as Date. No, it showed 1 as in March (it doesn't
       | show months). I had to manually set it back to 28th so that
       | tomorrow it shows correct date.
       | 
       | To be fair, it doesn't ask for year anywhere in settings. It
       | simply doesn't know what year it is.
        
       | FumblingBear wrote:
       | This one is rather specific, but a game rhythm based Final
       | Fantasy game called Theatrhythm Final Bar Line is simply not
       | allowing people to play today because it has an internal system
       | that awards prizes for specific days and they didn't handle the
       | case of what to do when it's on a leap day. You can boot it up
       | but can't actually play the game as a result.
       | 
       | Not working on the game or anything but found it moderately
       | amusing as someone who owns the game!
        
       | vidanay wrote:
       | Maybe? My paycheck direct deposit didn't show up until almost
       | 7am. Normally it hits right at midnight.
        
       | xyst wrote:
       | One of the most common QA test cases when it comes to testing
       | date and time sensitive applications.
        
       | bun_terminator wrote:
       | Yes, a few mildly bad things go wrong on a feb 29th. Everything
       | that handles stuff a year from now for example. Pretty bad for a
       | planning program. But our customers noticed and avoided that.
       | Codebase is too ancient and brittle to even attempt to fix. Or at
       | least boss doesn't want to invest time in it.
        
       | bxparks wrote:
       | I can understand getting the years 2000 (leap), 2100 (not leap),
       | 2200 (not leap), and 2300 (not leap) wrong. But getting the year
       | 2024 wrong is, disappointing, to put it diplomatically.
        
         | JohnFen wrote:
         | That's putting it very diplomatically indeed.
        
       | nameoda wrote:
       | My monthly bus passes for both February and March did not work in
       | Dallas today. The driver was aware of the issue and just waved me
       | in.
        
       | inciampati wrote:
       | Yes, in T-Mobile billing, I tried to set up automatic payments on
       | the 26th, but the system both told me that this was impossible
       | (because it was "less than 2 days from the end of the month") and
       | then accepted it, because why wouldn't it.
        
       | qwerty456127 wrote:
       | Yes - I triple-checked the calendar to verify my suspicion this
       | February might have 29 days. The result was always negative - it
       | seemed 28. Then February the 29th actually came. A bug apparently
       | occurred in my mind.
        
       | edgarvaldes wrote:
       | Just AFTER reading about Casio watches in this thread I looked at
       | mine. Sure it displays the date as March 1.
        
       | fdgjgbdfhgb wrote:
       | All street lamps in Paris turned off at midnight :)
       | 
       | https://www.leparisien.fr/paris-75/paris-pourquoi-les-rues-d...
        
       | 2muchcoffeeman wrote:
       | Why are there so many stories about leap year bugs?
        
         | ImaCake wrote:
         | Because programmers take shortcuts. Its easier to type x - 365
         | than to import Calendar and then date(x) - timedelta(1 year).
        
         | bombcar wrote:
         | It's strange to me, it hasn't been than long since a leap year
         | and I don't remember as many last time.
        
       | o11c wrote:
       | We got a bunch of close-dated yogurt the other day.
       | 
       | Several were best by 2-27, 2-28, 3-01, and 3-02, but none by
       | 2-29.
        
         | jareklupinski wrote:
         | > none by 2-29
         | 
         | traditionally known as the "Angel's Share" :P
        
       | davidbanham wrote:
       | My suite failed this morning on an obscure test of a function
       | that converts between ages and dates of birth. Took me ten
       | minutes of head scratching before I realised it was Feb 29th.
       | 
       | ''' + if time.Now().Month() == time.February && time.Now().Day()
       | == 29 { + t.SkipNow() + } '''
       | 
       | Fixed.
        
       | JohnFen wrote:
       | Not a single one, either in the code at work or anywhere else.
        
       | pastureofplenty wrote:
       | Yes, I have a bot that posts daily San Francisco weather records
       | to Mastodon. It did not post as scheduled today. This is because
       | I am looking at all the high temperatures, low temperatures, and
       | precipitation on today's date from 1875 (about as far back as
       | there are digitized weather records I can work with) to the
       | present. Since there was no such date as February 29, 1875 it is
       | throwing an error.
        
       | Smoosh wrote:
       | I certainly did. There is a batch process to cull old records. It
       | checks for customers who do not have a date of death recorded but
       | are > 130 years old, as it assumes that we weren't informed of
       | their death.
       | 
       | It takes 130 years from the current date and uses that in an SQL
       | statement to compares it to the date of birth. DB2 doesn't like
       | 1894-02-29.
       | 
       | Apparently it happens every 4 years, but no-one can be bothered
       | to fix it.
        
       | yanateras wrote:
       | The other way around! Today a few services that don't
       | congratulate me on my birthday (on non-leap years) did. I was
       | born on February 29th.
        
         | bombcar wrote:
         | Were you born on the day after Feb 28 or the day before Mar 1?
         | ;)
        
       | acutesoftware wrote:
       | Our ETL process is heavily monitored so we never miss a days
       | data, but we got a surprising error "cant build aggregates -
       | missing data, aborting MV refresh, data will be a day old". It
       | was the year to date (YTD) calculation - no data for 29/2/2023 to
       | compare to today.
        
         | bombcar wrote:
         | This is why -365 days can be better than -1y.
        
           | OJFord wrote:
           | Frankly unless you've considered it ahead of time and thought
           | you'd handled it, IMO you want the error. What's the correct
           | thing to do here? I don't think it's necessarily -365d, it
           | might be, but if I was GP I'd be glad for the chance to
           | consider it and decide what's correct - instead of it just
           | blowing up or even worse silently going whichever way's wrong
           | and undetected for a while.
        
       | lucas_membrane wrote:
       | My desktop machine did not time out overnight last night and
       | require me to enter my password to resume wasting time this
       | morning.
        
       | davchana wrote:
       | I am gald that in excel, deleting a day from March 1st
       | automatically gives Feb 29 or 28 depending on the year in
       | formula. Before that, I struggled a lot to find last day of month
       | by tracking if its a leap year or not, and keeping an array of
       | months & number of days. Now I simply add 1 to month, and from
       | resulting daye I subtract 1 day. The Date value of that gives me
       | 31 or 30 or 29 or 28.
        
       | jcarrano wrote:
       | My Citizen ana-digi-temp from 1985 works perfectly fine and shows
       | Feb 29.... though it thinks it is 1996!
        
       | dgan wrote:
       | Yup, all our rolling-year calculations failed because you can't
       | have 29 Feb 2023!
        
         | conductr wrote:
         | These ones are the worst because you'd think they'd be so
         | obvious at time of implementation. Maybe it's just me, I do a
         | lot of comparisons and things like this always are top of mind
         | for me.
        
       | zzzbra wrote:
       | Gusto paycheck didn't come in until a lot later than usual...
       | thought this might have been my last day on the job for a little
       | bit, didn't help that my manager and I's one on one was my first
       | meeting of the day heh.
        
       | asynchronous wrote:
       | The national law enforcement background check portal was down
       | today, I wonder if the leap day had anything to do with it.
        
       | obiefernandez wrote:
       | Uber is down in Mexico City
        
       | jewel wrote:
       | We have a product that uses ChatGPT via the API, using the 3.5
       | turbo version. Our query involves some dates. Instead of giving
       | back text like it usually does, today it has been giving errors
       | because it does not think 2024-02-29 is a valid date.
       | 
       | This is easy to reproduce with the web interface, at least
       | sometimes [0]. It start out by saying it's not a valid date and
       | then as it's explaining why it isn't it realizes its mistake and
       | sometimes corrects itself.
       | 
       | [0]
       | https://chat.openai.com/share/37490c9f-81d6-499f-b491-116536...
        
       | Waterluvian wrote:
       | Yes. Be mindful about if your industrial firmware really needs to
       | know the datetime..
        
       | tr33house wrote:
       | I had a few [datetime].replace(year=[current year]+n) in python
       | where n is not divisble by 4 e.g. 2,10
       | 
       | This is in code we use for scheduling
        
       | pgeorgi wrote:
       | https://review.coreboot.org/c/coreboot/+/80790
        
       | moralestapia wrote:
       | I did, actually!
       | 
       | A couple date form fields on AWS had their date incorrectly set
       | to 2024/02/28 instead of 2024/02/29. Not mission critical, but it
       | is something :D.
        
       | francisduvivier wrote:
       | Now that you mention it, the payment system was not working in a
       | ski resort restaurant in Switzerland this noon.
       | 
       | They had to switch to cash.
        
       ___________________________________________________________________
       (page generated 2024-02-29 23:00 UTC)