[HN Gopher] Microsoft Exchange stops passing mail due to bug on ...
       ___________________________________________________________________
        
       Microsoft Exchange stops passing mail due to bug on 1/1/22
        
       Author : technion
       Score  : 605 points
       Date   : 2022-01-01 08:45 UTC (14 hours ago)
        
 (HTM) web link (old.reddit.com)
 (TXT) w3m dump (old.reddit.com)
        
       | [deleted]
        
       | tdiff wrote:
       | So they are not checking security definition updates on some test
       | systems before releasing? This is ridiculous.
        
       | thanatos519 wrote:
       | ... so if they test things, they don't do it in an environment
       | that resembles the world of their victims^Wcustomers?
        
         | Krasnol wrote:
         | I assumed it's normal now to outsource beta testing to the
         | customer.
        
         | fragmede wrote:
         | For all the hate the cloud gets because of cost/whatever, I'm
         | really glad to have a SaaS provider for email right about now.
        
           | [deleted]
        
         | hughrr wrote:
         | Being a victim is exactly what I felt like when I was an MSFT
         | customer. I shall remember that one :)
        
       | littlecranky67 wrote:
       | kind of offtopic: I recently learned google uses a "Leap Smear"
       | instead of using leap seconds. To avoid errors and outages by
       | having a minute with 61 seconds, they just speed up their time on
       | a single day to match that extra second eventually.
        
         | PascLeRasc wrote:
         | That's really interesting, where did you hear that? I'd like to
         | read more if you have anything
        
           | mikehollinger wrote:
           | https://developers.google.com/time/smear :-)
        
           | ed25519FUUU wrote:
           | I'd you're using Google's public timeservers you're also
           | using leap second smearing.
           | 
           | https://developers.google.com/time/smear
        
       | belter wrote:
       | Many eons ago...Around 10 to 15 years ago...Seen a similar
       | serialization and date processing bug with a Java based
       | Enterprise Integration Platform used by some of the largest
       | companies in the world.
       | 
       | Several European Central Banks were unable to process
       | transactions ;-). Can't provide more details, to protect the
       | innocent. Since then, it has been a standard within the Testing
       | group of that vendor to always have a running platform setup with
       | a date 6 months ahead ( clock sync from a different source ).
       | Something I added to my own Software Engineering and Testing
       | standard practices.
        
         | unbanned wrote:
         | Is it someone's responsibility to periodically use the
         | environment as real users?
         | 
         | Without this, there's no value in running a duplicate
         | environment like this. Automated tests won't capture human
         | interaction perfectly...
        
           | rbanffy wrote:
           | You can automate at the UI level and run that set of
           | interactions (as well as screen captures and image matching
           | if needed)
        
         | karmakaze wrote:
         | I came to ask if anyone was aware of systems that automate
         | tests of dates in the future to find it already answered.
         | 
         | > Something I added to my own Software Engineering and Testing
         | standard practices.
         | 
         | Noted.
        
           | trembonator wrote:
           | Cmon, it's Microsoft! You shouldn't need to do that!
        
             | jrootabega wrote:
             | Agreed. Microsoft should be doing that already.
        
           | hughrr wrote:
           | Isn't this basically fuzzing?
           | 
           | Making sure it works at the business domain level is another
           | thing entirely.
        
             | matsemann wrote:
             | Not exactly fuzzing, no.
             | 
             | Most tests are written with a fixed date, or now().
             | Instead, using now()+delta can help discover future bugs
             | and give you some time to remedy the issue. Often annoying
             | to write tests like that, though, without them breaking for
             | unrelated/timing issues compared to a fixed value.
        
             | fragmede wrote:
             | not especially. Fuzzing would be running the software with
             | an API to test all of the possible dates.
        
               | jacquesm wrote:
               | No, that's exhaustive testing.
               | 
               | This is fuzzing: https://en.wikipedia.org/wiki/Fuzzing
        
               | azernik wrote:
               | A date 6 months in the future is not invalid or off; it
               | is a normal input that the program is expected to receive
               | in the future.
               | 
               | Fuzzing would be testing the date parser by passing it
               | '25-44-2021' to see what breaks.
        
               | jacquesm wrote:
               | Indeed. But you probably meant to address the parent,
               | rather than my comment.
        
               | azernik wrote:
               | Blerp
        
               | pimlottc wrote:
               | Fuzzing inputs don't necessarily have to be invalid, just
               | dynamically generated in order to probe program states
               | not normally exercised by manually generated test data.
               | Per Wikipedia: "providing invalid, unexpected or random
               | data as inputs"
        
               | hughrr wrote:
               | Exactly my original point.
               | 
               | Invalid input is invalid input
        
               | 0x0000000 wrote:
               | Valid, random inputs is still fuzzing, which is what the
               | person you are replying to was sharing with the quote
               | from Wikipedia.
               | 
               | Inputs don't have to be invalid for it to be fuzzing.
        
             | chmod600 wrote:
             | If you expect your software to exist in 6 months, then the
             | input is entirely expected, and therefore not fuzzing.
             | 
             | It's a nice early-warning system for Y2K or Y2038-like
             | problems.
        
         | game_the0ry wrote:
         | A couple of years ago, I did work for a major airline where the
         | test suites that would test date processing would fail on every
         | leap year (Feb 29). So they decided not to run tests or deploy
         | on Feb 29th.
        
           | mdavidn wrote:
           | One project had tests fail every Saturday and Sunday, near
           | the organization's fiscal week boundary. Ever since then, I
           | have strived to hard-code all dates in test suites, choosing
           | dates several decades in the future.
        
             | alisonkisk wrote:
             | Doesn't that just hide the bugs? Your tests should pass on
             | any and all date.
        
             | rbanffy wrote:
             | The outcome of tests shouldn't depend on the time of day.
             | Are these integration tests and you are having to deal with
             | external bugs you can't fix?
        
           | treeman79 wrote:
           | We doing a midnight deploy with 40 people. After boss
           | explained process. I asked him, so are we deploying on the
           | first midnight or the second?
           | 
           | Long quiet pause, then a series of curses. So we deployed at
           | 2am instead.
        
             | mlyle wrote:
             | Hmmm. Where are you? Here in the US DST changes happen at
             | 2AM to avoid ambiguities/weirdness with midnight.
        
             | rbanffy wrote:
             | Midnight UTC solves most of these problems.
        
           | jlkuester7 wrote:
           | Lol, reminds me of of the large EMR platform I used to work
           | on that (until very recently) could not handle the "fall
           | back" DST event (thanks to local date encoding in very parts
           | of the system).... So the recommended 'fix' for hospitals was
           | to just turn it off (their entire electronic health record)
           | for the duration of the DST changeover... I personally
           | believe that a non-trivial amount of people die due to DST
           | and similar time related bugs...
        
             | tharkun__ wrote:
             | Same for SAP. Seems like it's still 'best practice' to do
             | so:
             | 
             | http://www.sapbasis1solution.com/how-to-prepare-sap-
             | system-f...                   During this time of one hour
             | "Fall Back" on the clock, as is our Basis team best
             | practice (SAP Note #7417, #102088 and others) we intend to
             | gracefully shut down all Production applications prior to
             | 2:00 AM, at which time the "fall back" happens that will
             | revert back clock time by one hour.  We would then wait for
             | clock time to advance past the "new" 2:00 AM Local time.
             | And start from 2:05 AM EST will bring up applications.
        
             | riahi wrote:
             | From personal experience, this is Epic.
        
               | tuukkah wrote:
               | Yes. Epic was deployed in Helsinki in 2021, and you bet
               | it miscalculates the administration of recurring
               | medications during DST changes, which nurses then need to
               | correct manually.
        
               | belter wrote:
               | For anybody who missed this very insightful comment :-)
               | see the "Criticisms and controversies" section: https://e
               | n.wikipedia.org/wiki/Epic_Systems#Product_and_marke...
        
             | curiousllama wrote:
             | Oh, EMR systems kill patients all the time.
             | 
             | Like, I'm not convinced "turn it off" isn't an improvement.
        
               | game_the0ry wrote:
               | I hesitate to find it amusing that healthcare software is
               | so busted that we laugh off the negative, fatal
               | consequences.
        
               | alisonkisk wrote:
        
               | tata71 wrote:
               | No, the commenter isn't laughing or joking.
               | 
               | They're that bad.
        
               | thfuran wrote:
               | Not having one at all is also bad.
        
               | throwawayboise wrote:
               | How so? "First, do no harm" is the foundation of
               | medicine.
        
               | dragonwriter wrote:
               | > How so?
               | 
               | Empirically, it's associated with a higher rate of
               | medical errors, which is a big part of the drive for
               | electronic records.
        
               | wereHamster wrote:
               | Not of software engineering though.
        
           | Hamuko wrote:
           | Our unit tests break twice a year, starting a couple of days
           | before DST change. I'm sure it could be solved, but since the
           | DST change happens on Sunday and the CI builds fail on
           | Friday, no one has really bothered.
        
             | denton-scratch wrote:
             | > the CI builds fail on Friday
             | 
             | That seems different from what I understand by "continuous
             | integration".
        
             | Dunedan wrote:
             | So I guess your units tests run with the current date and
             | don't test behavior with different dates. That's something
             | which has the potential to hide quite a few date related
             | bugs until it's too late.
             | 
             | What I like to do to avoid this situation is to use
             | property-based testing to test that the code works for all
             | dates in the desired time span. For Python I use hypothesis
             | [1] in combination with freezegun [2] for that. Here is an
             | example of how that could look like:                 from
             | datetime import datetime, timezone as tz              from
             | freezegun import freeze_time       from hypothesis import
             | given, strategies as st                     def
             | business_logic():           # TODO: Refactor before 2038!
             | if datetime.now(tz=tz.utc) > datetime(2038, 1, 19, 3, 14,
             | 7, tzinfo=tz.utc):               raise Exception("This code
             | is not working after UNIX time overflow")
             | ...
             | @given(dt=st.datetimes(max_value=datetime(9999, 12, 31, 23,
             | 59, 59), timezones=st.just(tz.utc)))       def
             | test_business_logic(dt):           with freeze_time(dt):
             | business_logic()                     test_business_logic()
             | 
             | [1]: https://hypothesis.readthedocs.io/en/latest/
             | 
             | [2]: https://github.com/spulec/freezegun
        
               | Hamuko wrote:
               | It's just that the unit tests are built on the assumption
               | that if you go forwards 24/48/72 hours, the time will be
               | the same but N day(s) ahead. And that breaks down when
               | you shift time zones.
               | 
               | > _don 't test behavior with different dates_
               | 
               | It basically tests with different dates every time it's
               | run.
        
       | benttoothpaste wrote:
       | Long should be a 64 bit type on 64 bit machines, no?
        
         | stkdump wrote:
         | No, Win64 is an LLP64 platform.
        
           | bithavoc wrote:
           | Expanding on the topic, https://devblogs.microsoft.com/oldnew
           | thing/20050131-00/?p=36...
        
         | [deleted]
        
       | userbinator wrote:
       | Did anyone notice this anomaly?                   220101001
       | 2147483647
       | 
       | Those don't line up. It seems like it's converting a larger
       | number (10x?), but the error message mentions the above string.
        
       | breakingcups wrote:
       | See also: https://news.ycombinator.com/item?id=29757377
        
       | zbentley wrote:
       | Time to trot this out again:
       | https://infiniteundo.com/post/25326999628/falsehoods-program...
        
       | kizer wrote:
       | Seems like many bugs occur when programmers try to be clever
       | unnecessarily. In this day and age, we don't really have to do
       | tricks to save memory or time in application programs; it's just
       | not worth it with modern silicon and compilers/runtimes. So many
       | bugs could be avoided if people valued robust functionality with
       | maybe a "boring" implementation over trivial applications of
       | cleverness etc.
        
       | mitchs wrote:
       | I'm curious, what everyone considers far enough in the future for
       | your code. Eg. are you willing to write code that puts
       | nanoseconds in a 64 but number? That is "only" 584 years after
       | epoch. Would you consider that ok?
        
       | YXNjaGVyZWdlbgo wrote:
       | That is what happens without QA, people saving timestamps as int.
        
         | Forge36 wrote:
         | How often does QA adjust time on their machines? Could be an
         | easy test case/setup step for an automated suite
        
           | YXNjaGVyZWdlbgo wrote:
           | Since the year 2k craze it's actually a rather standard
           | practice in QA, at least on our team, to increment in decade
           | steps up to 2038.
        
             | k8sToGo wrote:
             | How do you get to 2038 by increasing by decades only?
        
               | YXNjaGVyZWdlbgo wrote:
               | You are absolutely right the last step is most of the
               | time not a decade and in a few year it's even under a
               | decade I hope the QA guys can adept their workflow...
        
       | technion wrote:
       | As far as I can tell, there's currently no official
       | acknowledgement of this issue.
       | 
       | It has affected 100% of the Exchange servers I'm overseeing. In
       | every case, a complete halt to mail was corrected by a fix only
       | escribed on Reddit and Twitter.
        
         | bazzargh wrote:
         | There is one here
         | https://techcommunity.microsoft.com/t5/exchange-team-blog/em...
         | though you'd be hard pressed to recognize it as being this bug,
         | since it doesn't mention the error message that everyone has
         | seen, and the instructions for workaround are not as explicit
         | and detailed as I'd want if I was paged for this.
        
         | drsnow wrote:
        
           | hprotagonist wrote:
           | me, too!
           | 
           | https://techcommunity.microsoft.com/t5/exchange-team-
           | blog/me...
        
       | alblue wrote:
       | TL;DR Microsoft released a virus definition file with a
       | timestamp/serial 220101001, and is unable to parse it into a
       | (signed) long value since the largest value is 2,147,483,647 and
       | it's possible that there's a factor of 10 in the deserialisation
       | logic.
        
         | AshamedCaptain wrote:
        
         | Flocular wrote:
         | The error message " Can't Convert "2201010001" to long." makes
         | it seem like that was the timestamp/serial used (Would be
         | yymmddHHMM format). No factor 10 in deserialisation needed for
         | an overflow.
        
         | ginko wrote:
         | But 220,101,001 isn't larger than 2,147,483,647.. Did they get
         | the number slightly wrong?
        
           | cnorthwood wrote:
           | It also included a serial number following the date part of
           | 001 (also 002, etc)
        
             | jonny_eh wrote:
             | Clearly this should stay a string. But I suspect they're
             | converting to an int to compare which definition is newer.
        
               | genocidicbunny wrote:
               | Comparing with strings ain't no panacea either. There's
               | some suspicion that Windows 9 was skipped because a lot
               | of old software checked for Windows 95 or 98 by just
               | doing a string compare against "Windows 9". (For the
               | record, I kind of doubt this was much of a concern by the
               | time Windows '9' was being worked on, but there's a
               | certain logic to it.)
        
               | turminal wrote:
               | That would work just fine with a string comparison.
        
               | priansh wrote:
               | Yeah my first thought was, well you could lay out the
               | timestamp in a way that supports lexicographical sorting,
               | and then realized they had already done so. No reason
               | this shouldn't be a string!
        
               | petee wrote:
               | It can be both. DNS serial numbers are YYYYMMDDnn, and it
               | works just fine for humans, it is easy to convert, more
               | compact, and you can compare in a single operation.
               | Internally, there is no reason for it to be a string.
        
           | [deleted]
        
           | Cycl0ps wrote:
           | There's three 0s before the last 1. That pushes it over the
           | edge of what a long int can handle
        
           | [deleted]
        
       | puyoxyz wrote:
       | don't link old reddit please, anyone who wants to use old reddit
       | already has it set as the default, and for apollo users old
       | reddit links don't automatically open in apollo like normal
       | reddit.com links
        
         | netsec_burn wrote:
         | If I remember correctly, HN automatically converts Reddit links
         | to old.reddit.com (less user hostile).
        
           | tuwtuwtuwtuw wrote:
           | Sounds like it should convert it to i.reddit.com then since
           | it's even less user hostile, at least in my view
        
         | butwhywhyoh wrote:
         | Wrong, I don't use reddit at all and I prefer old reddit. It's
         | not default for me since I don't have an account.
        
           | belltaco wrote:
           | https://chrome.google.com/webstore/detail/old-reddit-
           | redirec...
        
           | tuwtuwtuwtuw wrote:
           | Same here, but I would prefer if it linked i.reddit.com
           | instead. Like this:
           | 
           | https://i.reddit.com/r/sysadmin/comments/rt91z6/exchange_201.
           | ..
        
         | iso1210 wrote:
         | So people should go out of their way to change their links to a
         | system they don't like to appease people of some software
         | nobody's heard of and presumably could trivially be adapted to
         | recognise "old.reddit"?
        
         | SeasonalEnnui wrote:
         | As a counter data point - please do link old reddit. The dark
         | UI patterns on normal reddit are astonishingly hostile for an
         | anonymous user.
        
         | dagmx wrote:
         | The Apollo safari extension doesn't support it, but you can
         | simply go to the share sheet and select Open in Apollo
        
         | tuwtuwtuwtuw wrote:
         | Not sure what Apollo is, but it sounds like whatever it is it
         | should be fixed instead of you asking people to give some
         | alternate links to a worse version of the website.
        
           | ZeroCool2u wrote:
           | Apollo is a 3rd party Reddit client for iOS. It probably
           | should be fixed in Apollo. I know Sync on Android has no
           | issue handling any of the Reddit sub domains.
        
             | BenjiWiebe wrote:
             | And RedReader on Android also supports old.reddit links.
        
       | gtsop wrote:
       | Interested to know if there are other legacy pieces of software
       | in any industry having similar bugs
        
       | raintrees wrote:
       | Set-MalwareFilteringServer -BypassFiltering $True -identity
       | <server name>
       | 
       | Then restart Microsoft Exchange Transport service.
       | 
       | New year: Building a postfix-dovecot server.
        
       | f0e4c2f7 wrote:
       | Maybe we should just leave email off for 2022.
        
         | duxup wrote:
         | I really like this idea, until I consider all the other
         | options.
        
         | influx wrote:
         | Much prefer e-mail, which is async over messaging which isn't.
         | Also, my e-mail has programmable filters...
        
           | k8sToGo wrote:
           | Why is messaging not async? No one is forcing you to reply
           | right away.
        
             | aldebran wrote:
             | Some people treat messaging as having a sync social
             | contract. I've had a few people ask me within a min why I'm
             | not responding. I've had to set expectations and they
             | thought I was weird.
        
         | AnIdiotOnTheNet wrote:
         | Honestly I'm getting to the point where I'm beginning to think
         | computing was a bad idea.
        
           | wedn3sday wrote:
           | I think 90% of society would probably be better without
           | having easy every day access to advanced computers. Let the
           | HPC people keep running their physics and chemistry
           | experiments, but maybe we dont all need to have 10 computers
           | surrounding us 24/7.
        
             | zippystrider wrote:
             | The drawbacks of accessible computing (e.g. shortened
             | attention span, low-quality media consumption) are vastly
             | outweighed by its potential to allow people social mobility
             | and learn new skills they wouldn't have otherwise.
             | 
             | If I were born in an era before computers and the internet,
             | it's unlikely I would have experienced the best works of
             | classical music and hip hop; explored poetry and the great
             | classical books; and taught myself professional skills and
             | improved academically with access to textbooks and online
             | lecture courses.
             | 
             | I suppose it's possible I could have looked for real-life
             | pockets of communities where these are celebrated, went to
             | a physical library, and asked for help at a community
             | college. But more likely, I would've just copied what my
             | family and peers were doing when I was younger and missed
             | out on so much growth, because of a lack of connection to
             | people passionate about these things that the internet
             | provided.
        
               | kizer wrote:
               | The democratization of information and discussion is
               | invaluable really. Comes with downsides, which have to be
               | addressed of course.
        
             | [deleted]
        
           | formerly_proven wrote:
           | Sand was never meant to do this. Every day we stray further
           | from the light.
        
             | hans1729 wrote:
             | Or water invented man to carry itself up the hill.
        
               | imbnwa wrote:
               | Reza Negarestani likes this idea
        
             | cblconfederate wrote:
             | The light belongs to the Sun. Electric lighting is
             | basically cultural appropriation
        
           | vsareto wrote:
           | Delete all business applications but keep video games.
        
           | speedgoose wrote:
           | The average quality of life and life expectancy improved a
           | lot thanks to computing. I'm sorry you don't like emails
           | though.
        
         | skofgar wrote:
         | This would be a great New Years resolution. No emails.
        
         | bpodgursky wrote:
         | You won't like what comes next.
        
           | wrycoder wrote:
           | Purchase orders via Twitter?
        
             | tomjen3 wrote:
             | Fax machines.
        
       | linker3000 wrote:
       | We shouldn't blame Microsoft for this; I once worked in the
       | veterinary industry, and one Practice Management System allowed
       | you to register a pet including their real or approximate birth
       | date, or by entering an approximate age.
       | 
       | If you entered a birth date, the software would calculate the
       | pet's age, and we noticed we had the odd quirk, like a 400 year-
       | old cat etc. I couldn't see an obvious pattern to the anomaly,
       | and it didn't occur often, so I created a support ticket.
       | 
       | After a couple of days, I received a response that 'dates were
       | hard' and we should correct the ages manually as needed.
       | 
       | So there you have it: Dates are hard.
       | 
       | (No, the bug wasn't ever fixed.)
        
         | kingcharles wrote:
         | Did you check with the cat to see if it was actually 400 years
         | old?
        
         | lopatin wrote:
         | Sure, dates are hard. But I think it's too generous to say
         | Microsoft shouldn't be blamed for releasing such a bug.
        
           | rbanffy wrote:
           | Dates are hard but Microsoft is a trillion dollar company
           | that sells products on every locale and timezone on the
           | planet.
           | 
           | Something like this is unacceptable.
        
             | aldebran wrote:
             | I talked to someone who worked in this team. A mere 30 min
             | conversation opened my eyes to the complexity and he wasn't
             | even scratching the surface. It's hard for most people to
             | appreciate the true complexity here. I agree that
             | accountability is needed but even a trillion dollars won't
             | be enough for bug free code - especially with dates.
        
               | lopatin wrote:
               | The nature of this specific bug isn't something related
               | to hard date stuff, like leap years, leap seconds, DST,
               | or time zones. It's just that they formatted version
               | strings as YYMMDDHHMM (e.g. 2201010001) and tried
               | converting that number to an int32, causing an overflow
               | once 2022 struck.
               | 
               | Date bugs are hard, but this one isn't.
        
               | [deleted]
        
               | gromitss wrote:
        
         | BrandoElFollito wrote:
         | > So there you have it: Dates are hard.
         | 
         | Being an amateur developper, I never tried to touch a date in
         | another way than though a specialized module (arrow in Python,
         | moment or luxon in JS, ...).
         | 
         | I know only a few such modules so everything that remotely
         | looks as time/date computation is a nail for my universal
         | hammer.
        
           | joenathanone wrote:
           | I learned this one the hard way when using jQuery Datatables,
           | dates aren't natively supported for sorting, so had to
           | integrate moment.js and learn the quirks of date formatting
           | between it, Datatables, .net and sql, especially since with
           | moment you uppercase everything MM/DD/YYYY vs MM/dd/yyyy,
           | plus notation for AM/PM and seconds is also different.
           | 
           | Dates are hard.
        
             | BrandoElFollito wrote:
             | > date formatting between it
             | 
             | Oh yes. The nightmare of software that reinvent the wheel.
             | 
             | Instead of using ISO 8601 [1] they feel the need to do
             | something else.
             | 
             | I currently suffer with how time was botched in the
             | otherwise great backup program Borg [2]
             | 
             | [1] https://xkcd.com/1179/ - yes, xkcd has an entry for
             | everything
             | 
             | [2] https://www.borgbackup.org/
        
         | OisinMoran wrote:
         | It's painful to learn of such a bug and have no insight into
         | how it was caused. Would love to get my hands on the codebase
         | to figure this one out!
         | 
         | In another universe The 400 Year Old Cat could have been our
         | 500 Mile Email.
        
           | petee wrote:
           | We know how it was caused, bottom of reddit post is the
           | update. The developers got clever and used a common method to
           | store a version as an integer, but they never checked that
           | they had enough space to store such a large number for the
           | uncommon format they chose.
           | 
           | Its just another form of y2k, or y2038.
        
             | NobodyNada wrote:
             | The comment you replied to is talking about the 400-year-
             | old-cat from the previous comment, not the Exchange bug
             | from the article.
        
               | petee wrote:
               | Oops! Thank you, I lost track of the thread while
               | scrolling back up! Please disregard, as I'd love to know
               | what that bug is too
        
         | throwawayboise wrote:
         | Dates _are_ hard, it 's got to be one of the things on the
         | lists of "things programmers don't understand."
         | 
         | Choices to represent dates as an integers (seconds from an
         | epoch), or as strings, or as arrays, or as other data types all
         | come with a lot of non-obvious consequences and edge cases to
         | deal with. I always use a provided "date" datatype from a
         | library, and never try to roll my own with base data types if I
         | have any choice in the matter. And they are still hard,
         | depending on what range of dates you need to be able to handle.
        
           | SamuelAdams wrote:
           | Semi-related, one of my favorite posts on UTC. Seems simple
           | to use until it's not.
           | 
           | https://zachholman.com/talk/utc-is-enough-for-everyone-right
        
         | goda90 wrote:
         | I feel like after Y2K, we should've learned to never store two
         | digit years again. If the format they used was actually
         | YYYYMMDDhhmm, then it would've crashed as soon as someone tried
         | to convert it to an int and they would've fixed it without
         | another thought. Sure dates are hard, but a few simple rules
         | cover a lot of problems.
        
           | OisinMoran wrote:
           | Do you mean it would crash from that number being too big for
           | a byte-sized int? Just checking I'm not missing anything
           | here.
        
       | db48x wrote:
       | Phone numbers are not numbers. Zip codes are not numbers. Model
       | numbers are not numbers. Characters are not numbers. Which part
       | of this progression escapes you?
       | 
       | Seriously, if you can't add, subtract, multiply, and divide them,
       | then they aren't numbers and you shouldn't use a numeric data
       | type for them. This is CS 101 knowledge. How badly does MS run
       | their engineering?
        
         | hulitu wrote:
         | Just look at Win 10 and at Teams for examples. The only
         | engineering which counts at MS is the one which maximizes
         | profits.
        
           | samstave wrote:
           | Isn't it lovely that Bill Gates' famous words are that
           | vaccines are the best investment he has ever made?
        
           | Demiurge wrote:
           | And how is this different for everyone else in the free
           | market economy?
        
             | reaperducer wrote:
             | A lot of people and companies take pride in their work.
             | Saying that people are only in it for a buck is a tired old
             | cliche that is easily disproven through even casual
             | observation.
        
             | dijit wrote:
             | I had a weird kind of epiphany when I was watching the
             | fireworks over Sydney last night.
             | 
             | The harbour bridge has lights on it.
             | 
             | For what financial benefit?
             | 
             | The fireworks display itself, I can't understand where the
             | financial benefit is and it costs millions of dollars. ($7
             | million as far as I'm aware)
             | 
             | ---
             | 
             | I think that you could make a financial motivation
             | statement for making good software (it makes it less likely
             | for people to switch, for example), but my broader point
             | is: why does everything have to be financially motivated?
             | 
             | Because, a lot of stuff that we enjoy doesn't seem to be
             | primarily financial in nature.
        
               | dylan604 wrote:
               | >The harbour bridge has lights on it.
               | 
               | >For what financial benefit?
               | 
               | Same for the Opera House. Imagine all of those stock
               | photos of Sydney. Now narrow those down to the nighttime
               | shots of Sydney. Imagine those without lights on the
               | bridge or opera house. For that matter, any of the lights
               | on any of the buildings. What do you have left? A really
               | boring photo. Nobody wants to visit a city with really
               | boring photos. What's the financial benefit of that?
        
               | Jon_Lowtek wrote:
               | Does not compute. What's the financial benefit of
               | selecting cities based on how well lit their photos are?
        
               | watt wrote:
               | A lot of things about humans is based on desire, not on
               | logical conclusion or requirement. Humans do things
               | because they want to, not because they need to or it's
               | the logical or rational thing to do.
               | 
               | Evoking desire is key.
        
               | dijit wrote:
               | So taking this whole comment chain into consideration,
               | why are Windows 11 and Teams going out of their way to be
               | awful to use?
               | 
               | We agree that the Free Market(tm) incentives are to
               | maximise desire even at an up-front loss (Fireworks,
               | Lighting the bridge) but the parent said that it's free
               | market economics that prevent Teams and Windows from
               | being desirable to use.
               | 
               | Is someone wrong or am I misunderstanding something?
               | 
               | Is there more profit in awful things? Why does the
               | Harbour bridge have lights then?
        
               | dylan604 wrote:
               | Why are we even trying to equate the 2 things? The harbor
               | bridge has a very pleasant look and people want to
               | accentuate that, so they have decided to put lights on it
               | so that it can be enjoyed at night. There is a very
               | pleasing affect from things being lit at night. Why why
               | why is this hard/difficult to grasp?
               | 
               | That is so so so different from a group of engineers
               | building a product and totally not grasping that while it
               | technically works, it is not pleasant for the end users.
               | It takes a certain level of asshattery to assume that the
               | devs are going out of their way to make it this way.
        
               | selestify wrote:
               | Better lit structures make photos of them look better.
               | Tourists choose destinations to spend money at based on
               | how good the photos of the destinations look.
        
               | Jon_Lowtek wrote:
               | that doesn't answer my question, i was asking why the
               | tourist selects like that. How does selecting based on
               | how well lit photos are create a financial benefit for
               | the tourist? ;-)
        
               | ben-schaaf wrote:
               | It's not for the benefit of the tourists at all, it's an
               | advertisement to increase tourism for the benefit of
               | local businesses.
        
               | Jon_Lowtek wrote:
               | Yet such adverts should not increase tourism because
               | tourists must surely prefer to visit cities that offer
               | benefits for tourists.
        
               | dylan604 wrote:
               | You're such a troll. The benefits of tourists to the
               | tourist for visiting a city can come in many forms, and
               | financial benefit is rarely one of them. In fact, it
               | typically comes at great financial cost.
        
               | SAI_Peregrinus wrote:
               | That's their point. Not everything done in a market
               | economy is done with a goal of gaining a financial
               | benefit.
        
               | Demiurge wrote:
               | city user experience :)
               | 
               | There is the same financial incentive for MS to fix their
               | Y2k22 bug.
        
               | mind-blight wrote:
               | It doesn't have to be, but our economy is structured to
               | name it one of the primary ways to justify something's
               | existence, Ave basically the only way to make something
               | sustainable.
               | 
               | The incentive structures are built to make financial
               | incentives take precedence with most things
        
         | collegeburner wrote:
         | Sometimes a performance reason? Number is usually smaller,
         | faster, also better if stored in a database and more efficient
         | if used as a primry key,
        
           | ClumsyPilot wrote:
           | Gotta free up space for those electron apps
        
         | Pxtl wrote:
         | We need null-terminated binary-coded-decimals as a standard
         | datatype for cases like this. "Numeric String".
        
           | ananonymoususer wrote:
           | Okay, so if it's null-terminated, how does one represent a
           | zero?
        
             | edoceo wrote:
             | "0\x00"?
        
             | Pxtl wrote:
             | F-terminated might work better (given 1-nybble-per-digit
             | BCD), or do a Pascal-style length prefix. I was less
             | fixated on the implementation detail than I am about the
             | basic concept of: arbitrary length numeric strings with
             | numeric semantics and string-like storage and length
             | characteristics.
        
             | tom_ wrote:
             | Decide that the null value is one of the invalid digits -
             | e.g., %1111. 0 can remain %0000.
        
         | frays wrote:
         | The only reason I can think of is YYYYMMDDHHMM represented as
         | an unsigned long is 4 bytes, while the equivalent in characters
         | would require 12 bytes.
         | 
         | Is it possible that at Microsoft's scale this would actually
         | make a significant difference?
        
           | yodelshady wrote:
           | a simple tuple of appropriately-sized integer types would
           | only need 8 bytes, which coincidentally is what MS will need
           | come 2043.
           | 
           | That does mean rolling your own "greater-than-or-equal"
           | operation though.
        
           | petee wrote:
           | Anything you do will take 3x the memory, so yes... I cant see
           | why anyone would store as a string internally, you have to
           | decode into a number anyway so just extra work. Strings are
           | only useful to humans.
           | 
           | Edit: reading all the comments here, I get the feeling high
           | level programmers don't fully understand how things are
           | represented at the low level, there is no purpose in storing
           | a version/serial as a string.
        
             | jeroenhd wrote:
             | Re your edit: these days, most developers are web
             | developers where people don't care about these
             | optimizations.
             | 
             | It's a little silly that a test didn't catch this problem,
             | but using a version number somewhere high up in the long
             | makes total sense to me. After all, version numbers can be
             | anything you define them to be, as long as they're unique.
             | You'd like them to be sortable, but they don't even have to
             | be.
        
               | petee wrote:
               | Sorry, I edited twice (just for confusion hah).
               | 
               | I don't think it's that they don't care, I suspect many
               | simply do not understand what is under the hood in the
               | first place; and they don't need to when doing web
               | development. The fact that some here suggest storing
               | version as a string is some how faster and safer is a big
               | give away.
        
               | jeroenhd wrote:
               | Perhaps saying they don't care is a bit much, they
               | usually just don't need to care. The data is delivered to
               | most websites in the form of JSON which can be parsed to
               | any data format you want, and at that point it might even
               | be faster to do a string compare to skip the double/int
               | conversion.
        
               | petee wrote:
               | I got what you were saying. That certainly may be case,
               | depending on application. It looks in this case like its
               | just definition files being loaded into memory, and if
               | they need to compare that version more than once, doing
               | it as a single operation binary comparison will be
               | significantly faster than continually comparing a UTF-8
               | string (SIMD aside)
        
             | foepys wrote:
             | There are lot of "numbers" not actually being numbers. E.g.
             | phone "numbers" are not numbers. The same as a house
             | "numbers" are not numbers. Version "numbers" are also often
             | not numbers (e.g. 2.1.230-rc.1).
             | 
             | If the OP bug was really triggered by a _string of
             | numerical characters_ not fitting into a 32bit integer, all
             | the trouble of saving a few bytes on the client system were
             | not worth it.
        
               | petee wrote:
               | Yes, that is what the OP of the thread said, I've read
               | it. Version numbers can be numbers if you want, and plan
               | them to be. Which is the case here, its not a string fit
               | into a 32 bit integer, its actually an integer. But they
               | didn't think to check the max size which would only fit
               | in an unsigned. Its an odd choice on their part, but
               | certainly would have worked.
        
               | foepys wrote:
               | This very much depends on the protocol. Microsoft loves
               | XML and and if the update package has an XML manifest
               | with update information attached to it, it's very well a
               | string that gets serialized to a number. The same applies
               | to JSON and other text-based formats.
        
               | petee wrote:
               | And that is fine though because at some lower level
               | everything becomes a number to a computer. I think
               | everyone is getting hung up on this string/number
               | difference; data from humans is going to come as a
               | string, thats no reason to store or process it as such.
               | 
               | Plenty of data is stored in varied types for processing
               | that are efficient for a computer, for example DNS has
               | been using date-based serial numbers successfully for
               | decades, and stored internally as uint32.
        
           | pintxo wrote:
           | It probably did, 25 years ago
        
           | throwuxiytayq wrote:
           | Not likely. Modern software developers laugh this kind of
           | difference away, and will almost always default to taking a
           | memory/storage space hit over other possible trade-offs
           | (performance, correctness, convenience...)
        
             | watermelon0 wrote:
             | Considering storage/memory requirements for modern
             | desktop/mobile apps, I wouldn't mind if developers would
             | occasionally think about optimizing them.
        
               | xigoi wrote:
               | Storing non-numeric data as strings is not what makes
               | modern apps bloated. It's the technologies used
               | (Electron) and a general "I don't care" approach.
        
               | Dork1234 wrote:
               | Nah, we computer scientist are happy embedding electron
               | into every application no matter how small.
        
         | ed25519FUUU wrote:
         | This is so extremely common that it's funny to me you scoff at
         | it.
         | 
         | Under the hood these systems will convert to some numerical
         | format to compare which version is newer. You store it as a
         | (proper) numerical format or you serialize it into one later,
         | but at the end of the day it's a number because that's how you
         | compare it.
        
         | zitterbewegung wrote:
         | The only reason I can think of is that storing a version as a
         | number would allow you to check if your version is incompatible
         | with another server or feature / extension. By using less than
         | or greater than.
        
           | frays wrote:
           | If they were stored as characters you could still do a string
           | comparison using greater than and less than signs and logic.
           | 
           | "202201010001" > "202112122359"
           | 
           | evaluates to True in Python, SQL and many other languages.
        
             | oefnak wrote:
             | But "1000"<"999" in Python.
        
               | thomasfedb wrote:
               | But the format and length for these numerical strings is
               | fixed.
        
               | jpambrun wrote:
               | This is going to be a problem in about 8,000 years tho.
        
               | laumars wrote:
               | String comparison works as long as you order your date
               | time by significance and zero pad all values, which they
               | were doing with their date stamp anyway.
               | 
               | Plus if they weren't then even numerical comparisons
               | would fail eg 1012021 (Oct/1/2021) < 5102020
               | (May/10/2020) so you argument is moot.
        
               | 6c696e7578 wrote:
               | Wouldn't it be done more like this though?
               | "%04d%02d%02d" % (999,1,1)
        
           | ilikehurdles wrote:
           | Not necessarily.
           | 
           | 2.2 is greater than 2.12 but v2.2 is actually an early
           | predecessors to v2.12
        
             | mmis1000 wrote:
             | That would work if padding is always forced (like date).
             | And in this case, it actually is.
             | 
             | 2.02 is smaller than 2.12
        
               | pfooti wrote:
               | Best hope you don't end up releasing 2.100 then
        
               | mmis1000 wrote:
               | It can also ends up as 2.99.01. Jokes aside, there is
               | another bug caused by some poor programmer hard-coded the
               | length of version field recently.
               | https://news.ycombinator.com/item?id=29702128
        
         | tyingq wrote:
         | Not that it excuses the issue, but I suspect the motivation was
         | numeric sorting to identify the newest. So it was sort of a
         | number in that respect.
        
           | LadyCailin wrote:
           | Not criticizing you, but no, it's a string which happens to
           | have a natural ordering. The fact that it happens to look
           | like a number is irrelevant.
        
             | boardwaalk wrote:
             | It's like nothing could have multiple useful forms. Which
             | is of course not true. This is just a dumb bug.
        
             | tyingq wrote:
             | The idea wasn't justifying the choice, but rather trying to
             | imagine what happened. Because they did want a way to sort
             | and pop the highest numeric value, they made a bad choice.
        
         | bob1029 wrote:
         | I have found that any time you would refer to a thing as a
         | "Code" or "Number", you are almost certainly talking about a
         | string. Every property name in our codebase that contains one
         | of these terms is a string type without exception.
        
           | dannyw wrote:
           | If it's not a float or integer, it's a string.
        
             | quesera wrote:
             | And if it's currency, it should be an integer not a float.
        
               | bob1029 wrote:
               | We use decimals for all currency and rate properties.
               | Integer is fine in many cases too.
        
               | quesera wrote:
               | Be careful with floats:                 20.40 == (20.39 +
               | 0.01)       => false
               | 
               | ("decimal" can either be colloqually-equivalent to
               | "float", or it can refer to a distinct data type which is
               | supported by some languages and databases. A proper
               | decimal type is currency-safe to use, if available.)
        
             | [deleted]
        
         | [deleted]
        
         | rbanffy wrote:
         | > Seriously, if you can't add, subtract, multiply, and divide
         | them, then they aren't numbers
         | 
         | Sadly, sometimes you can, regardless of whether you should.
        
         | tomjen3 wrote:
         | But they are. Zips here in Denmark are clustered progressively,
         | so that if you have a package going to (say) 8600 and 8704 then
         | it makes some sense to send those orders to the same
         | distribution node, since they will be close together, but to do
         | that you need to treat them as numbers.
         | 
         | My grandparents first phone number was 13. Not because they got
         | in super early and had the 13th phone number in the country,
         | but because that was the 13th number for their exchange. When a
         | bunch of exchanges were put together everybody got another
         | number in front of theirs. Their phone number is much longer
         | today, but it still ends in 13.
         | 
         | I guess you could treat the phone numbers as strings, but I
         | don't know if you can do that with the Danish zip numbers.
        
           | chiph wrote:
           | Even in North America, you shouldn't treat ZIP/postal codes
           | as numbers. The US added 4 digits 30-ish years ago (ZIP+4)
           | and they're separated with a dash. You _could_ store them as
           | separate numbers [0] and rely on the presentation code to add
           | the dash. But since Canada has alphanumeric postal codes
           | (Mexico uses numbers), you 're better off treating them as a
           | string field.
           | 
           | The US used to prefix phone numbers with letters (like
           | MElrose 1-2345) as an aide-memoire during the transition to 8
           | digits with area codes. And you'll still see businesses
           | advertising with letters in place of digits (like 800-GOT-
           | JUNK which is a junk removal firm) but they never get entered
           | into phone number fields like that. The best reason to have
           | phone numbers as text though, is the digit groupings [1]. In
           | North America, it's 3-3-4 but other countries group their
           | numbers differently to help people remember them. So allowing
           | users to enter numbers in their format you're making it easy
           | for them.
           | 
           | [0] The main reason to do this is if you're in the business
           | of sending out mailings. The US postal service gives
           | discounts if you sort and bundle by ZIP code, and mixed ZIP
           | and ZIP+4 values would make that hard.
           | 
           | [1] https://en.wikipedia.org/wiki/Chunking_(psychology)
        
           | silvestrov wrote:
           | You should never use clustering/subtraction on Danish zip
           | codes as a source of "how hearby". To quote
           | https://www.postnumre.dk                  2400 Copenhagen NV
           | (North West)        2412 Santa Claus, Greenland         2450
           | Copenhagen SV (South West)            ...        3790 Hasle
           | (close to Roskilde)        3900 Nuuk (Geenland)        3992
           | Dog sled patrol "Sirius"        4000 Roskilde
        
             | wombatpm wrote:
             | Unless it is encoded in its design. For US zip codes the
             | first three digits encode a geographic region. But there is
             | no guarantee that 601 is next to 602
        
           | [deleted]
        
           | akersten wrote:
           | A ZIP code is an identifier made of numerals, it is not a
           | _number_ in the mathematical sense. It does not make sense to
           | multiply, add, subtract, or divide them - even though the
           | numerals are assigned in apparently ascending order. There 's
           | nothing preventing a future decree from making one that
           | starts with a Z, or a 0, or putting a dash in the middle of
           | it. It is foolish to store it as an integer type.
           | 
           | You can cluster them for distance without storing them as an
           | integer. Just throw them in a graph data type and compute
           | edges having actual integral weights. The ZIPs themselves are
           | not what you want to be doing your math on.
        
           | pintxo wrote:
           | Lots of phone numbers start with a zero, converting string to
           | numbers will most likely change the phone number by removing
           | the information of the leading zero. Doing this in js will
           | store it as base 8. Neither will make anyone happy.
        
             | bombcar wrote:
             | Excel loves replacing phone numbers with 12031041e8 or
             | whatever when importing CSV. So useful.
        
               | hermitdev wrote:
               | What's even worse is if you inadvertently save the CSV
               | with the auto format, the data will be lost, too. Excel
               | is both a wonderful tool and the bane of my existence
               | when dealing with financials.
        
               | dylan604 wrote:
               | This is one of the most annoying things to me about Excel
               | (of a long list). In pretty much every time MS
               | applications feel they are smarter than me ends in MS
               | application being wrong. It doesn't matter if the data is
               | manually typed or pasted from else where, when Excel
               | tries to auto-guess how to set the formatting of the cell
               | is just horrid. Dates are shite when trying to be in the
               | US and using UK formatted dates.
        
         | NelsonMinar wrote:
         | So.. are database IDs numbers? Because they sure are
         | autoincrement integers in almost every DBMS. I always thought
         | that was a mistake but it's practical.
        
           | masklinn wrote:
           | > So.. are database IDs numbers?
           | 
           | No.
           | 
           | > Because they sure are autoincrement integers in almost
           | every DBMS.
           | 
           | The autoincrement occurs before it's a database ID. The
           | _generator_ for database ids is a _sequence_ , that has no
           | bearing on the semantics of the database ids.
        
           | marcosdumay wrote:
           | They are absolutely not numbers.
           | 
           | As many people already commented, it's reasonable to encode
           | things as numbers as long as you keep in mind there's an
           | encoding operation with it's possible flaws.
        
             | kenjackson wrote:
             | Honestly that seems like a cop out.
        
               | marcosdumay wrote:
               | The usual habit of typing ids as integral numbers is
               | incorrect, they are not numbers. But the problems it
               | causes are well known and dealt with by what is broadly
               | known as good practices.
               | 
               | Is it better this way?
               | 
               | (You can see the problems clashing with each other if you
               | search for discussions about defaulting ids to 32 or 64
               | bits. So they are not completely solved, the practices
               | are just good enough that things don't usually break on
               | practice.)
               | 
               | At the end of the day, all you have on a computer is a
               | bitfield to mess around. You will always have to deal
               | with encoding at some point.
        
               | Spivak wrote:
               | I mean strings are numbers if you want to be that
               | reductive. The "on-disk" representation of the thing is
               | independent of its real type and properties.
               | 
               | So sure, store a date in an "integer" but if you try to
               | treat it like one instead of a bitfield you've made an
               | error and if your storage isn't wide enough to hold all
               | dates that's gonna be a PITA later.
        
           | Quekid5 wrote:
           | Yes, but as soon as they leave the realm of the DB itself,
           | they (should) become opaque identifiers.
        
           | mind-blight wrote:
           | It's becoming pretty standard to use UUIDs over integers now.
           | That provides more architectural flexibility
        
         | dheera wrote:
         | > How badly does MS run their engineering?
         | 
         | I think the real problem is ... how many good engineers and
         | engineering managers nowadays _want_ to work at MS?
        
         | petee wrote:
         | You're right but thats not the issue here, the version is
         | structured as a number but they failed to give it a type large
         | enough to represent it; simply a signed/unsigned screwup.
        
           | masklinn wrote:
           | That's not a fix, barely an improvement, really just a shitty
           | workaround: the _exact same issue_ rear its head again in
           | 2043.
           | 
           | The actual fix is exactly what the original comment states: a
           | version is not a number.
        
             | petee wrote:
             | Oh I agree its a bad long term solution, but assuming they
             | had noticed and used the correct type, 2043 is likely well
             | past the lifetime of the product and would have worked fine
             | till then. Not great, but certainly passable.
        
               | masklinn wrote:
               | > Oh I agree its a bad long term solution, but assuming
               | they had noticed and used the correct type, 2043 is
               | likely well past the lifetime of the product
               | 
               | You expect _Microsoft Exchange_ to _stop being used_ some
               | time in the next 20 years?
        
               | petee wrote:
               | That version yes, absolutely. I expect at some point
               | Microsoft will have made enough updates that they will
               | say X version is no longer supported, and it will stop
               | working on its own. And its not like it's a product
               | installed on some embedded device that will never get
               | updates until then, Exchange will get security fixes for
               | as long as it is exists and nobody will be running this
               | version in 20 years.
               | 
               | Even more likely, we'll have new protocols the current
               | version doesn't support, so the bug will have been long
               | fixed or noticed.
        
               | masklinn wrote:
               | > That version yes, absolutely.
               | 
               | But in your alternate timeline the issue would only have
               | been hit in 2043, and since in our timeline it was not
               | noticed before it was hit, there is no reason to believe
               | it would have been noticed in the alternate.
               | 
               | So the exact same issue would have occurred, a few years
               | later.
               | 
               | I fail to see why that would be an improvement.
               | 
               | > Even more likely, we'll have new protocols the current
               | version doesn't support, so the bug will have been long
               | fixed or noticed.
               | 
               | That is a completely unsubstantiated assertion.
        
               | petee wrote:
               | I'll quote myself again, _" Oh I agree its a bad long
               | term solution, but assuming they had noticed and used the
               | correct type, 2043 is likely well past the lifetime of
               | the product and would have worked fine till then"_
               | 
               | I never suggested it was any improvement except for the
               | advantage of time; although I shouldn't have used the
               | word 'correct'. Signed 32-bit dates have a well known
               | limitation that people will likely hunt and fix over the
               | next 20 years. But yes, its all unsubstantiated, no doubt
               | there.
               | 
               | The real main point of my post you first replied to is
               | that it doesn't matter that the version was stored as an
               | integer. The failure happened when they used their own
               | format and didn't confirm it was properly bounded.
               | Everyone here is having a hard time grasping how their
               | data is stored and processed at the low level - your
               | 'string' is still just an array of 8-bit bytes.
               | 
               | Storing an only-increasing number as any form of integer
               | is a perfectly acceptable, and efficient way for a
               | computer to compare and process. Version numbers are one
               | of those. Phone numbers are obviously not.
        
           | lolinder wrote:
           | The version is not structured as a number, it's structured as
           | a string of digits that incidentally resembles a number.
           | There are no operations that take two version numbers and
           | return a new version number, so they are not numbers.
        
             | petee wrote:
             | That is how they are entered by a human, yes. Then they are
             | converted to binary and processed, like everything else.
             | There is no need to add two version numbers together, but
             | as they only ever increasing, its sane and efficient to
             | store, and compare binary.
             | 
             | Everything in software takes data in one form and processes
             | it into another. There are no 'strings', there are no
             | version numbers. There is only binary. They simply did not
             | give enough space to store it, thats all.
             | 
             | DNS is a perfect example, which stores serial numbers
             | internally as an unsigned 32 and has worked for decades and
             | will continue to. But they chose the format of YYYYMMDDnn
             | which will last far longer than a 2 digit year.
        
         | dehrmann wrote:
         | You should try PHP. You can multiply all sorts of things!
        
         | skrebbel wrote:
         | Captain Hindsight strikes again!
        
         | [deleted]
        
         | yholio wrote:
         | These are version numbers. It's perfectly fine to use _numbers_
         | to express version _numbers_ , a great majority of protocols
         | reserve numeric fields for this.
         | 
         | The problem here was basic overflow, they reached a version
         | number exceeding the capacity of the numeric type.
        
         | djrogers wrote:
         | > Seriously, if you can't add, subtract, multiply, and divide
         | them, then they aren't numbers
         | 
         | You've missed a ton of other scenarios here, the relevant one
         | being a compare operation with a < or > output. These are
         | version numbers. Version numbers the way they're used here
         | increment, they are _not_ random strings, which is what you're
         | effectively suggesting.
         | 
         | If the version numbers here were represented as strings they'd
         | need to be converted to a number at some point to compare them,
         | and you'd probably run into the same problem you have here.
         | 
         | Of course I'm sure you'd have the perfect, completely
         | applicable, and universally accepted solution then as well...
        
           | wolf550e wrote:
           | ISO8601 strings are sortable and are not numbers.
        
             | SAI_Peregrinus wrote:
             | Which comes first, "2021-W52-6T15:10.4" or
             | "20220101T151115.1-05"? Lexicographic sort between those
             | two ISO-8601 date/time strings will get it wrong.
             | 
             | Did you mistake ISO-8601 for RFC-3339? Even there
             | lexicographic sorting isn't guaranteed, since you can have
             | a pure date or a pure time or a date-time combined, and
             | there's a choice between "T" and " " to separate dates from
             | times in a date-time but it's much more likely to work than
             | with ISO-8601.
        
             | 88913527 wrote:
             | Character sorting isn't a natural law. The fact that "A"
             | comes before "Z" is historical; it's 'always been done that
             | way'-- at least since the Phoenicians.
             | 
             | https://en.wikipedia.org/wiki/History_of_the_alphabet#Desce
             | n...
        
             | tuwtuwtuwtuw wrote:
             | No they aren't.
             | 
             | 10000 can be a valid year according to ISO8601, but sorted
             | as a string it would come before year 2000, which would
             | obviously be incorrect.
             | 
             | Here's from the ISO:
             | 
             | > 3.5 Expansion By mutual agreement of the partners in
             | information interchange, it is permitted to expand the
             | component identifying the calendar year, which is otherwise
             | limited to four digits. This enables reference to dates and
             | times in calendar years outside the range supported by
             | complete representations, i.e. before the start of the year
             | [0000] or after the end of the year [9999].
        
               | otterley wrote:
               | Sounds like a problem we don't have to worry about for
               | another 8,000 years or so.
        
           | pigbearpig wrote:
           | These should have been strings, end of story. You can sort a
           | string. Amazing to see storing a non-number as as number
           | being defended. Truly CS101.
        
             | srj wrote:
             | I guess it depends on the language but using a string for
             | this doesn't seem like a great choice except for user
             | display / logging. Given this is a version number you'd
             | want to support comparison operators, and a struct with
             | those operators defined (and a string format method) would
             | make more sense imo.
        
             | DSMan195276 wrote:
             | You can certainly sort a string, but I think there are
             | valid reasons to avoid it if possible. What they shouldn't
             | be doing is trying to shove it into a single 32-bit integer
             | - if they parsed it into separate integers for each of the
             | individual parts (like a simple date representation would
             | do) then the issue would go away. Whether it's worth that
             | extra work to avoid the string comparison is debatable, but
             | if they go on to mask out parts of the version number and
             | look at them individually (Ex. Only the year, or only the
             | revision number) than it would probably be worth it to just
             | do all the parsing upfront and avoid any messing with
             | strings after that.
        
             | petee wrote:
             | I'm curious which languages you learned in CS101 (actual
             | question, not snark)
             | 
             | Every non-number, as you put it, is just a number to a
             | computer. Comparing binary is faster than sorting strings,
             | and it makes zero sense to waste memory simply so a human
             | could potentially read it.
        
               | jraph wrote:
               | But versions are for human beings.
               | 
               | Otherwise, a timestamp, a date, a commit hash or an
               | increment would do.
        
               | petee wrote:
               | That's not true, they can be for either humans,
               | computers, or both. Software still has to understand and
               | do something with that version number, even if it came
               | from a human. And if it has to store, sort, or process
               | that number a lot, it will still be faster to store and
               | compare binary than a string.
               | 
               | For comparison, I think some here would be shocked to
               | learn their IPv4 address is stored as an unsigned 32-bit
               | integer. Its not a number, and definitely not faster to
               | use as a string.
        
           | WoahNoun wrote:
           | Posets aren't numbers either.
        
           | lolinder wrote:
           | Comparing strings is trivial, and would work out of the box
           | with the format that they're using (YYMMDD###).
        
           | Jenk wrote:
           | > Version numbers
           | 
           | They still aren't compatible with number types. They are
           | groupings of numbers at best.
           | 
           | 2.9 is an earlier (not less than) version than 2.10.
           | 
           | 3.1.6 isn't a (strict) numerical format.
           | 
           | 5.4.11-beta1 has non-numerics.
        
             | marcellus23 wrote:
             | Did you read the link that we're all discussing here? The
             | versioning scheme they use is not any of those formats.
        
             | rat9988 wrote:
             | > 2.9 is an earlier (not less than) version than 2.10.
             | 
             | Not necessarily. Some projects go from 2.9 to 3. I'm not
             | sure what you are trying to prove.
        
               | Jenk wrote:
               | > They still aren't compatible with number types.
        
               | rat9988 wrote:
               | Why?
        
               | solarengineer wrote:
               | For software version numbering, I consider 2.9 to have
               | been released "earlier than" 3 (and not lesser than 3).
        
               | Spivak wrote:
               | How do you deal with a project like Ansible where 2.9.16
               | was released after 2.10.0 or Python 2.7.18 was after
               | 3.0.4?
               | 
               | I think version numbers are a partial ordering at best.
        
               | rat9988 wrote:
               | They aren't numbers, easy.
        
             | DSMan195276 wrote:
             | Ignoring the tags (which not everything uses) it's possible
             | to express all of those as a single increasing number by
             | simply putting enough zeros in, which does make them
             | representable as simple numbers, so I think you're kinda
             | splitting hairs. Most version number
             | representations/libraries will likely do something similar
             | to read it anyway even if you keep it a string - split it
             | into separate individual numbers and compare
             | major/minor/patch/etc separately, and by virtue of fitting
             | the individual parts into separate integers you're giving
             | them all a maximum value, which is what the zeros would do.
             | 
             | The problem is they shoved the individual parts into a
             | single 32-bit integer, which just isn't enough space so
             | they had to compromise and make some of the numbers have
             | extremely small ranges.
        
               | Jenk wrote:
               | There are exceptions to that rule, however - Maintenance
               | releases. Node, Typescript, Java, .NET, and I'm sure many
               | more obvious instances I need not list.
               | 
               | If you "just" increment you leave no room for showing
               | patching in your versioning strategy.
        
               | DSMan195276 wrote:
               | I'm not entirely sure what you're getting at? That's the
               | point of the `feature` and `patch` version numbers. If
               | you want you can put a 4th or 5th number in there as well
               | to fit whatever uses you have.
               | 
               | Perhaps you're missing what I meant by 'increasing' -
               | it's just a 1:1 conversion of the version number to a
               | single integer, it's not like you're assigning every
               | version a new number. 3.9.3 would become something like
               | 3009003, and 3.10.1 would become 3010001. If you compare
               | those representations then 3010001 always compares
               | higher, and there's also nothing preventing you from
               | releasing 3.9.3 after 3.10.1.
               | 
               | My point was that doing a format like the above (major, 3
               | digit minor, 3 digit patch) is not fundamentally
               | different from storing each individual number as it's own
               | integer, which most version libraries I've seen do at
               | some point. The problem is just that the range of each
               | number is restricted significantly by requiring 3 digits
               | rather than if you used individual 32-bit or 16-bit
               | integers for each one.
        
               | Jenk wrote:
               | We agree. :)
               | 
               | A "Version Number" is not just a "Number", as I said
               | right at the start.
               | 
               | Just to clarify, having an integral incrementing number
               | as the _whole_ version number strategy explicitly
               | prohibits the use of major /minor/patch.
               | 
               | Unless you intend on using 0s (instead of fullstops) as
               | delimiters I suppose.
               | 
               | Edit: as you demonstrate in your post. I'll stop posting
               | now :)
        
             | detaro wrote:
             | The reference was
             | 
             | > _Version numbers the way they're used here_
             | 
             | And none of that applies to them. Yes, there are versioning
             | schemes that work differently, irrelevant to the example
             | here.
        
             | tuwtuwtuwtuw wrote:
             | If you define your version numbers to be numbers, then your
             | version numbers will be numbers. I really don't get the
             | confusion over this.
        
               | Spivak wrote:
               | I mean if your standard for "numbers" is "can be mapped
               | 1-1 to integers" then everything is a number. The
               | operations you actually do to numbers have to have
               | meaning in the space you're defining.
               | 
               | Does "1.2.0" + "2.3.0" make sense in your world?
               | 
               | And if you're like what about ordering and comparisons,
               | then sure, you have a partially ordered set.
        
               | tuwtuwtuwtuw wrote:
               | I don't get what you're trying to add. If Microsoft
               | defined their version numbers as an integer then it's an
               | integer value. They didn't define it as say "1.2.0" so
               | not sure what that has to do with anything.
        
               | Robin_Message wrote:
               | Dates can be very meaningfully and sensibly converted
               | to/from a numeric representation, yet the addition of two
               | dates doesn't make sense, so I don't think not bring able
               | to add versions holds.
               | 
               | And not everything can be mapped 1-1 with the integers;
               | reals for example, and therefore arbitrary strings. (Of
               | course, that's only theoretically; with a limited string
               | length you can obviously manage)
               | 
               | You're right that the ordering is the key feature of a
               | version representation; munging it into an integer gives
               | you that for free but risks getting to overflow quite
               | easily (as in this case). I guess the conclusion is, use
               | a language like Rust or Ruby when you can define ordering
               | easily on structured data.
        
               | Jenk wrote:
               | The assumptions/traits/expectations that come with
               | numbers (and most importantly, that are embedded into the
               | number _types_) may not be consistent with _version
               | number_ types.
        
               | tuwtuwtuwtuw wrote:
        
               | Jenk wrote:
               | I think you need to read the thread again. The point
               | (there is just one) I've made in both replies has been
               | very clear and direct.
        
               | tuwtuwtuwtuw wrote:
        
               | Jenk wrote:
        
           | akersten wrote:
           | > the relevant one being a compare operation with a < or >
           | 
           | In Math we call that subtraction!
        
         | rbobby wrote:
         | YYMMDD + 4 digits of versions. At a glance, even a bit more
         | than a glance, that seems fine for a long. And if 2020 worked
         | and 2021 worked... why would 2022 break?
         | 
         | Lol.
         | 
         | I'd bet the conversation about this way back when it was being
         | decided was "will 3 digits for daily version/build be enough"
         | and the answer "go with 4, better safe than sorry".
        
         | MikusR wrote:
         | But you can add and subtract dates.
        
           | Turbots wrote:
           | Add March 5th to June 2nd...
        
             | _dain_ wrote:
             | August 5th.
        
           | db48x wrote:
           | You can only add a Duration to a Timestamp; you cannot add
           | two Timestamps.
        
             | [deleted]
        
           | adolph wrote:
           | The map is not the territory.
           | 
           | The efficacy of any computational operator on a specific
           | representation does not impute the same for all
           | instantiations since the semantic link between identity and
           | representation may only exist in the mind of the programmer
           | and not the computational device.
        
         | dehrmann wrote:
         | I used to work on a customer API that accepted these fields as
         | JSON. My first project was improving validation (I used JSON
         | schema) while not breaking existing integrations. While it's
         | true that those fields aren't numbers, I saw all those fields
         | sent as numbers.
        
         | fortran77 wrote:
         | > How badly does MS run their engineering?
         | 
         | Bad enough to be a 2.53 Trillion Dollar company.
        
         | ajross wrote:
         | It's neither a phone number, zip code, nor model number. It's a
         | version number. And version numbers don't multiply or divide,
         | but they do compare. This kind of code has a decades-long
         | history:                   #if BUILD_VERSION >=
         | FIRST_VERSION_THAT_WORKS         ...         #endif
         | 
         | And in fact if you look around, almost every large C or C++
         | project has a WHATEVER_VERSION token (c.f. LINUX_VERSION_CODE
         | for the kernel) that packs the version into a comparable
         | integer literal.
         | 
         | The bug here is that they picked an encoding that was obviously
         | going to overflow in a Y2.022K bug, not with the technique.
        
           | cesarb wrote:
           | > [...] almost every large C or C++ project has a
           | WHATEVER_VERSION token (c.f. LINUX_VERSION_CODE for the
           | kernel) that packs the version into a comparable integer
           | literal. The bug here is that they picked an encoding that
           | was obviously going to overflow [...]
           | 
           | Speaking of LINUX_VERSION_CODE, it had a similar problem
           | recently. See the article at https://lwn.net/Articles/845120/
           | which was summarized in this year's LWN.net retrospective at
           | https://lwn.net/SubscriberLink/879053/aaea44782e8c760d/ as
           | follows:
           | 
           | "Sometimes the most obvious things can be the hardest to
           | anticipate; consider, for example, the case of minor revision
           | numbers for stable kernel releases. A single byte was set
           | aside for those numbers, since nobody ever thought there
           | would be more than 255 releases of a single stable series.
           | But we live in a different world, with fast-arriving stable
           | updates and kernels that are supported for several years. It
           | should have been possible for us, and for the developers
           | involved, to not only predict that those numbers would
           | overflow, but to make a good guess as to exactly when that
           | would happen. We were all caught by surprise anyway."
        
             | ajross wrote:
             | Similar, but with the important distinction that this
             | problem was recognized months in advance and remedied with
             | some care (or kludge, depending on your preferences), and
             | didn't become a bug in production software.
             | 
             | All computers work in finite representations. All values
             | can overflow. Good engineering is about working within that
             | world and not trying to Quixotically design its absence.
        
         | comboy wrote:
         | Everything ends up in your database as bytes. You can say
         | everything is a number. It's just naming. Whether it's sane to
         | do basic math operations on them is loosely correlated with
         | whether user sees that number as an integer on his screen.
         | 
         | Most bugs are stupid and should be obvious. They happen.
         | 
         | You can look at your old code and say WTF, so judging decisions
         | in somebody's else complex system without having any idea about
         | requirements and constraints seems pointless.
        
         | michaericalribo wrote:
         | Well, to put on my pedantic hat and indulge my inner math
         | major, what you describe is algebra on top of objects--you're
         | talking about the math that applies to numbers, not the numbers
         | themselves. Specifically you described groups and fields and
         | rings...the symbols themselves are numbers, but they don't
         | recombine with each other in the same way as other numbers.
         | 
         | You're right that they shouldn't be implemented a numeric data
         | types.
         | 
         | That said, dates do have properties of modular arithmetic, so
         | in a strange sense they are very much numbers...
         | 
         | :p
        
         | hiptobecubic wrote:
         | Version numbers can of course be numbers, but the problem here
         | is that they were constructing a number like a string from
         | semantically meaningful constituent parts (and not testing
         | thoroughly).
        
           | raverbashing wrote:
           | And again, if there are no negative versions, they should
           | have used an unsigned int, not an int.
        
           | [deleted]
        
         | Kevin578 wrote:
         | isnt working with integers generally faster than working with
         | strings? that might be why some ppl store phone numbers and zip
         | codes as int
        
           | ben-schaaf wrote:
           | Not if the only thing you're doing with the number is
           | converting it from/to a string...
        
             | petee wrote:
             | And its very doubtful that is all Exchange is doing with
             | it. Likely they have a large list of definitions to compare
             | and track.
        
           | reaperducer wrote:
           | _that might be why some ppl store phone numbers and zip codes
           | as int_
           | 
           | Anyone who stores ZIP Codes as an int should have his dev
           | license revoked. You've just corrupted the data you store for
           | a hundred million people in the northeast.
           | 
           | I'm currently dealing with a situation where a system
           | developed by an offshore team stored Social Security numbers
           | as integers. They had no idea that an SSN can start with a
           | zero, and didn't even do a basic web search to see what the
           | possible range of values is before designing the database and
           | application.
        
             | Kevin578 wrote:
             | you can tell a 4 digit zip code has a leading zero that was
             | removed though. you'll also get faster sql queries if you
             | search for zip codes as int vs string
        
               | reaperducer wrote:
               | _you can tell a 4 digit zip code has a leading zero that
               | was removed though_
               | 
               | Only if you're 100% sure your date is completely clean.
               | Only very rarely is this the case, especially with ZIP
               | Codes because the data almost always traces back to human
               | input.
               | 
               | The initial query may be quicker, but then you have to
               | compensate for the missing digits elsewhere, likely
               | multiple times. You have to consider the expense to the
               | whole system, not just to one query.
        
         | snicker7 wrote:
         | Time is a number. At least, it makes sense to subtract them (I
         | guess you can say that time is a one dimensional affine space).
        
           | pjc50 wrote:
           | Time is a number _and a location_. If you normalize
           | everything to a reference time such as the UNIX epoch, you
           | can usually do subtraction. Even then you may have got the
           | times from a non-monotonic clock ...
        
           | bsza wrote:
           | Time is a number, but a date is not. 211231 + 1 != 211232.
        
             | karpierz wrote:
             | To be specific, that representation of date does not
             | implement integer addition. To be fair, neither do most
             | "number" types (uint, int, float, etc).
             | 
             | For uint, you actually have x + y = (x + y) mod MAX_UINT.
             | 
             | For float, sometimes x + 1 = x.
             | 
             | The issue is not that date is not a number, but that people
             | poorly reason about common cases of date arithmetic.
             | Similar stuff comes up for floats and ints but they're just
             | easier to reason about.
        
               | gkop wrote:
               | > For float, sometimes x + 1 = x
               | 
               | Would you spell this out for us?
        
               | cmeacham98 wrote:
               | Floats effectively work by specifying a level of
               | precision and a multiplier against that. For big numbers,
               | you need a lower precision (larger gap) between the
               | representable values. Eventually the precision gets so
               | low that adding 1 doesn't reach the next possible value
               | and rounds back down to your current value.
        
               | eska wrote:
               | If x is a huge number, then elimination can happen.
               | Floating point numbers store a mantissa and an exponent,
               | m^e. When you have a huge number the exponent will be
               | large. So the mantissa can not express the tiny number
               | anymore.
        
           | kaba0 wrote:
           | Bit of a nitpick, but due to relativity, time is not simply a
           | number though.
        
             | wyldfire wrote:
             | Relativity is not modeled in the vast, vast majority of
             | computer systems that track time. So the nitpick is
             | irrelevant.
        
               | kaba0 wrote:
               | But there are rare software that model it (eg. GPS
               | systems famously have to account for it) - so I think it
               | is a textbook definition of a nitpick.
        
           | kzrdude wrote:
           | just like pointers, it makes sense to subtract them and add
           | offsets but to straight up add them makes no sense.
        
         | darau1 wrote:
         | We use exchange at work. Daily, I will utter some form of
         | "Microsoft can't do anything right, man".
        
         | pvillano wrote:
         | side note
         | 
         | some numbers^* cannot be meaningfully multiplied or divided.
         | For example, 3^rd place, 30deg F, or 37.388N,-122.067S.
         | 
         | Some numbers can only be added to by numbers of a different
         | type. For example xdegC + ydegK, 3rd grader + year, absolute
         | position + offset. Similarly, subtracting two of these numbers
         | results in a different unit. e.g. position - position = offset
         | 
         | it would be great if someone could comment the exact
         | terminology for what I'm trying to describe.
         | 
         | * Types/Units
        
           | samus wrote:
           | Levels of measurement:
           | 
           | https://en.wikipedia.org/wiki/Level_of_measurement
        
           | mind-blight wrote:
           | I'm not sure if it's what you're looking for, but algebraic
           | days types are a fairly common way to encode different kinds
           | of days that have the same shape.
           | 
           | You may also be looking for fields:
           | https://en.m.wikipedia.org/wiki/Field_(mathematics). You
           | could probably also describe the relation between different
           | number types as linear operators over a vector space
        
           | jongalloway2 wrote:
           | F# has Units of Measure: https://docs.microsoft.com/en-
           | us/dotnet/fsharp/language-refe...
           | 
           | There are libraries that implement this concept in other
           | programming languages (C++, Java, C#, etc.)
        
           | john-aj wrote:
           | In statistics, one usually differentiates between
           | 
           | - nominal scales (e.g. man/woman),
           | 
           | - ordinal scales (elementary school/middle school/high
           | school),
           | 
           | - interval scales (degrees Celsius) and
           | 
           | - ratio scales (human height, degrees Kelvin).
           | 
           | Only ratio scales may be multiplied and divided. Interval
           | scales may be subtracted and added. Ordinal scales may only
           | be compared (less/greater/equal). Nominal scales may only be
           | compared in terms of (in)equality.
           | 
           | https://en.wikipedia.org/wiki/Level_of_measurement
        
         | SAI_Peregrinus wrote:
         | I'd say if they don't form an ordered field, they shouldn't be
         | called "numbers". The complex numbers really ought to be called
         | an algebra, not numbers. They're the dimension-2 Cayley-Dickson
         | algebra, after all!
        
       | hexo wrote:
       | Whats the point of using exchange? Why people can't just use
       | regular mail servers? Whats different?
        
         | awill wrote:
         | Every company I've worked at who uses self-hosted exchange uses
         | it because that's what they used 20 years ago. I don't know
         | companies deliberately using it.
         | 
         | I suppose office 365 is different. Smaller companies get a good
         | bundle with Teams, Office, mail etc..
        
         | bogantech wrote:
         | It ties in easily with AD, does shared mailboxes, calendars,
         | contact lists, meetings, automatic out of office, sorting,
         | legal hold, archiving, backup etc relatively easily without
         | having to glue together a hundred different things.
         | 
         | MS will support it & offers training. It can be managed easily
         | by the same windows admins they have managing their AD
         | infrastructure and desktop support.
        
         | hahajk wrote:
         | What are other good self-hosted email server options?
        
           | hexo wrote:
           | I don't know... postfix?
        
             | belltaco wrote:
             | Doesn't even have webmail.
        
               | petee wrote:
               | It doesn't need to, its just a backend. Postfix lists 8
               | webmail options, but you could use any interface you can
               | find.
               | 
               | http://www.postfix.org/addon.html#web
        
           | ananonymoususer wrote:
           | https://mailinabox.email/
        
         | frays wrote:
         | I'm more interested in hearing why these Sys Admins haven't
         | switched over to O365 yet?
        
           | ocdtrekkie wrote:
           | A local Exchange server has vastly better uptime than Office
           | 365, works when cloud services and the ISP is down, and costs
           | drastically less. Hilariously, the standing advice has
           | usually been for Exchange Online customers to still install
           | and operate a local Exchange server too, which means
           | switching to the cloud didn't even reduce your management or
           | hosting burden at all.
           | 
           | Sure, you get the occasional bug like this, but it's less
           | often than Microsoft screwing up the entire cloud.
        
             | easton wrote:
             | > Hilariously, the standing advice has usually been for
             | Exchange Online customers to still install and operate a
             | local Exchange server too
             | 
             | Only if you have a large tenant (> 2000 mailboxes) at the
             | time of transition, and even then there's ways around it. I
             | think if you were getting advice today, it would be to
             | avoid hybrid as much as possible and find any other way to
             | move over because of this stupid requirement.
        
               | EvanAnderson wrote:
               | As of the last time I checked (6 mos. ago) there is still
               | no supported managemenrt solution for Exchange Online
               | without local Exchange if you migrated to Exchange Online
               | via a hybrid migration.
               | 
               | Some people just modify AD attributes directly to get
               | around having an on-prem Exchange install but that's not
               | officially supported.
        
           | bluedino wrote:
           | Cost. Especially if you have a large amount of users, and you
           | already have the IT staff and servers to run it on (you can
           | try to justify it with less admin costs and less server costs
           | but the numbers don't add up for some orgs)
           | 
           | As an example, I worked at a healthcare org and it would have
           | been $70,000 a year for hosted Outlook, but only $110,000 to
           | buy the software outright and run it for ten years (700,000 -
           | 110,000 is a big savings)
        
             | iso1210 wrote:
             | HN wisdom is that it's impossible to run a single raspberry
             | pi with less than $2m/year spend on IT staff alone
        
             | [deleted]
        
             | robjan wrote:
             | You also have to run a datacentre or server room with the
             | on-prem version
        
               | [deleted]
        
               | isbvhodnvemrwvn wrote:
               | And meat terraform/ansible to run those.
        
               | gruez wrote:
               | >and you already have the IT staff and servers to run it
               | on (you can try to justify it with less admin costs and
               | less server costs but the numbers don't add up for some
               | orgs)
        
           | analog31 wrote:
           | Are they actually different, as in the nuts and bolts, or
           | just different shells on top of the same infrastructure?
        
             | carlhjerpe wrote:
             | You pay very little for these things to be someone else's
             | problem.
        
         | bluedino wrote:
         | Calendars, push, a bunch of other stuff that's useful
         | 
         | It's not perfect but it's by far the best mail server for
         | internal Email.
        
       | mymargora wrote:
        
       | jakub_g wrote:
       | Semi-relevant: "Practical time machines" (ironically, written by
       | MS engineer from another department)
       | 
       | https://textslashplain.com/2021/10/01/practical-time-machine...
        
       | Scarblac wrote:
       | The old joke "Every program grows until it can send email, except
       | for Microsoft Exchange" is still true on 1/1/22.
        
       | tomohawk wrote:
       | 2022 is already a great year!
        
       ___________________________________________________________________
       (page generated 2022-01-01 23:00 UTC)