Falsehoods Programmers Believe About Time (2012)
infiniteundo.com
infiniteundo.com
* Didn't think about time at all.
In most cases most don't think about time until it becomes a problem. It often ends up with a system which behaves in surprising ways, and is the equivalent to the developer believing any of those things in the article. But there is a difference in them believing those falsehoods, and simply not being a aware of them at all.
* Time moves forward
This is probably the biggest gotcha of all. Just imagine how many times int the past you did dt = now() - t0, then did something with dt like sleep(dt). Well time will move backwards sometimes and dt is negative. I bet this will make most people here worried and they'll think about code they wrote like that (sure did). I have seen systems freeze for example because they end up sleeping for a huge amount of time (negative number was cast to an unsigned huge number).
A small advice on how to improve errors related to time is to abstract it away from algorithms and code as much as possible. Instead of always calling gettimeofday() / time() / now() function to get the current time, in a piece of lower level code, try to pass it in as an argument. That will make code testable.
I have seen fun failing test cases. Something like encoding the current time the test was written and a dt to current time. The test was working for years then started failing eventually because of the hard coded time.
I agree. Smart library developers seem to agree, too. Example from Python docs:
https://docs.python.org/3/library/time.html#time.monotonic
The only (cough) problem is drilling this knowledge into developers' heads - and as you said, awareness that there even is a problem!
Slightly off-topic pet-peeve of mine: never used unsigned, unless you have an extremely good reason for it. Saving one bit is not one of them. You never know when you will need to do arithmetic on your unsigned values. Time going backwards is a good example of this.
Any code that uses time based scheduling should use a virtual implementation of time/scheduler to allow testing - this way you can say "sleep 10 hours" and then "move virtual time by 10 hours" and actually verify that the timeout is hit without the tests actually taking 10 hours. It also lets you test out logical edge cases such as `<=`, `>=` vs `<`, `>` which is surprisingly tricky with timeouts.
I've pitched this before (during a code review for something) and was laughed at by the team under some guise of YAGNI / developer gold plating. They honestly thought I was joking. Once I explained the issues mentioned in the article, they still thought it was a waste of time.
It takes just a few seconds to implement and makes the code so much easier to test / maintain.
[1] https://msdn.microsoft.com/en-us/library/system.concurrency....
Any class that needs to know the time has the following object injected in.
public interface IDateTime
{
DateTime UtcNow { get; }
DateTime Today { get; }
}
StructureMap is configured to pass in the following concrete implementation. public class DefaultDateTime : IDateTime
{
public DateTime UtcNow
{
get { return DateTime.UtcNow; }
}
public DateTime Today
{
get { return DateTime.Today; }
}
}
Obviously you can expand this to include local time, we haven't in order to prevent accidental use of Now when you mean UtcNow.All of our tests inherit from a base test that does various set up stuff (clear down the db in integration tests for example). One of the things it does is swap out DefaultDateTime with this...
public class TestDateTime : IDateTime
{
private DateTime _testDateTime;
public TestDateTime(DateTime testDateTime)
{
_testDateTime = testDateTime;
}
public void ChangeTimeTo(DateTime testDateTime)
{
_testDateTime = testDateTime;
}
public DateTime UtcNow
{
get { return _testDateTime.ToUniversalTime(); }
public DateTime Today
{
get { return _testDateTime.Date; }
}
}
Where _testDateTime is set to be sometime in August (always a good idea if you're developing in the UK!). This has the added advantage of making test runs deterministic (at least in this respect) even if you're not doing a time related test.It doesn't support this use case. Yet [2].
Now all we need to do is get rid of the filesystem and all other databases...
Can you please explain this one and hopefully link to an in-depth resource? I imagine you're talking about leap seconds, and/or the possibility that the system time is changed (whether manually or due to an ntpd update that corrects backwards). Are there other sources of this phenomenon?
I guess what I mean is that things like that are a nice piece of trivia, little fun facts, but nothing to be concerned of for most of us.
I'm having trouble wrapping my my head around this one. If the goal is maintaining a steady output, shouldn't they keep revolving at the same rate, without worrying about what day the "current" second (no pun intended) belongs to? After all, I'm assuming they don't "catch up" after leap days, they just run for an extra day at the same output level. Why would leap seconds be different?
Put another way, what do they need to spread those extra 30 turns over a 4 hour catch up period? Weren't they given an extra second in which to take care of them?
http://www.cleanlineenergy.com/technology/hvdc/how
And now I'm trying to think my way through it:
There is definitely DC with no frequency component, e.g., battery circuits. You've got a cathode, an anode, and a flow between them.
I'm trying to sort out if DC can have a frequency component. I seem to recall that rectified circuits can operate by basically (pardon crude metaphors) chopping off the negative side of the phase. You'll have a wave pattern, but it's all going in one direction. Pushed through sufficient capacitance or impedance and you'll likely smooth that out as well.
Which is getting me to wonder just how a DC generator works.
https://en.wikipedia.org/wiki/Dynamo
It's described (and matches my memory) of producing a "pulsing direct current". The commutator, a physical switch, maintains the polarity of current by breaking and switching between generator coils.
Dynamo is basically an AC gen with some crap in front to make output look DC.
"Pulsing DC current" is actually ac with >50% of the duty cycle zeroed out.
Again, could be very wrong here my memory is fuzzy as hell.
> A dynamo is an electrical generator that produces direct current with the use of a commutator.
>> A commutator is a moving part of a rotary electrical switch [...] that periodically reverses the current direction between the rotor and the external circuit
I'm glad I'm not the only fuzzy one here....
Your metaphor for rectified circuits is not crude, a half-wave rectifier will clip the negative portion of the signal to 0, a full-wave rectifier will actually invert the negative portion.
I wouldn't say you push it through sufficient capacitance or impedance, but you do want to smooth out this bumpy (now positive) wavy signal, so you low pass filter it, a simple resistor-capacitor circuit.
what we're describing is an AC/DC convertor
There's a distinction between a current which reverses flow, and one which varies, perhaps regularly, but without reversing flow.
The reason coordination of AC generation is crucial is that if you pump opposing cycles at each other, they simply cancel out. If you pump out-of-phase varying DC currents at each other, they amplify one another -- the sign is always positive, but the magnitude varies. I suspect that might also cause problems, but not in the same way as a going-nowhere-fast out-of-phase AC circuit would.
The phase-damping (and I very vaguely recall damped driven oscillators from physics: friends don't let friends drive damped ...), wouldn't be an AC/DC converter, but a form of power smoothing / power conditioning, I believe.
[5, 3, 5, 3, ...] = [4, 4, 4, 4, ...] + [1, -1, 1, -1, ...]
Every current that varies with a regular frequency is just the sum of a DC current and an AC current that reverses flow. I guess in most applications one can decompose them and analyze the two components separately.
Ideal DC has zero ripple, and looks like a straight line on a scope. Ideal AC is a sinusoid. AC-DC conversion tends to produce some ripple. At low power levels, a capacitor across the line and/or an inductor in series will level out the ripple. At high power and voltage, such filters become huge, and there are lots of tricks used to reduce the need for filtering.
Converting 3 phase power to DC works better than single phase, since at least two phases are always delivering power. There's no zero-power point, as there is with single phase, and the ripple is at 6x the AC frequency. (The higher the frequency, the less filtering required.) There's also a trick with transformers for converting 3-phase power to 6-phase power. This gets the ripple frequency up to 720Hz. This is an old trick; the NYC subway system has used it for many decades.
Converting DC to clean AC used to be tough. The home solar power industry took a long time to get inverters with good output waveforms. Early inverters produced square waves, which overheat motors and transformers. There's been a lot of progress, and power semiconductors have improved enormously in recent years. Now everything from electric cars to Diesel-electric locomotives to electric model airplanes have 3-phase inverters. Anything with a "brushless DC" (really synchronous AC) motor has an inverter driving it. The output waveform is usually a stairstep approximation to a sine wave. This can be filtered into a sine wave if necessary.
Power MOSFETs make this all possible. It's incredible how good they are as electrical switches. Turn-on resistances are in the milli-ohm range. That's as good as a mechanical switch, and better than a carbon-brush commutator.
Thanks for the info.
HVDC systems are connected to AC systems using rectifiers and inverters. An interconnect point is a switching power supply. A very large switching power supply. The output DC isn't perfectly clean DC and the output AC isn't a clean sinusoid; converters have to approximate and try to filter. Wikipedia has a nice explanation, with good pictures.[1]
I guess grandparent post is saying power companies go ahead and feed in extra cycles for the leap second. It's not something I'd heard of, but it wouldn't surprise me.
However, I just found that the _average_ frequency over a length of time should be exactly 50Hz, so it is, in fact, good for keeping time.
More here:
Separate from that, there was a scheme for sending time of day in the vertical retrace interval, to set clocks and VCRs. Few devices received that, although I once encountered a hotel TV with a built-in analog clock that did. (The clock was wrong; although it could set itself automatically, it had to be told manually which channel provided a time signal. That's probably why this feature never caught on. I was bored enough to figure out how to set the thing.)
US telephony used to be synchronized to an atomic clock in New Jersey. The TDMA multiplexing was kept in sync so that frames could be transferred synchronously without buffering. If the clock connection was lost, T1 to T3 lines would get slightly out of sync, and occasionally drop or add an 8-bit frame. This is unnoticeable in audio, but an error for modems.
But neither of these was a time count. It was just a square wave.
I think I heard about the TV frame syncing from an Australian YouTube video.
I'm from Europe where every TV and VCR would easily get a clock from TeleText (we also had fancy stuff like PDC to make sure your video recordings of TV shows didn't get cut off)
http://www2.nationalgrid.com/uk/Industry-information/electri...
Before quartz clocks were around, synchronous mains clocks were common, and accurate.
(The machine would actually mostly run fine off just a 5V DC input, or even off a 4.5V battery most of the time if you didnt need any of the things that required AC...)
[1] https://books.google.com/books?id=W0oEAAAAMBAJ&lpg=PA9&ots=4...
Also, wouldn't they have to slow down slightly rather than speed up? The second at midnight effectively takes twice as long, which is equivalent to the grid's waveform stopping for 1 second.
1. An instant in time - often represented as an integer number of milliseconds since January 1, 1970.
2. A date in the Gregorian calendar. This could also be an integer offset from a particular day, but it's better to encapsulate it in a class that allows you to add days or months, get the number of days between two dates, etc.
3. A timezone which is necessary to convert between the two types mentioned above.
Java has default classes to represent Types 1 and 3, but is missing a simple class for Type 2. So I designed one myself: http://calendardate.sourceforge.net
That's already an undefined statement ;-)
I mean, I guess you are actually aware of it, but that's not actually an instant in time, that's about 24 different spans of time, each 86400000 milliseconds long.
GP left out the time and timezone, but we still recognize that date as shorthand referring to the Unix epoch.
Actually LocalDate is a better representation for Type 2 because it doesn't encapsulate minutes, hours or seconds. This would make it ideal to represent "John's birthday" or "date on which the customer repaid loan".
In fact, I'm disappointed that Java has incorporated Joda time - new Java programmers will now need to crawl over a huge pile of time-based classes to pick out the ones they need, when for 99% of cases only the same 3 types are necessary. How many of these novice users will incorrectly use LocalDateTime to represent Type 1?
http://www.oracle.com/technetwork/articles/java/jf14-date-ti...
I still don't like how you can do things like Instant.from(DayOfWeek.MONDAY) (which results in a runtime exception), but at least at least it's slightly more type-safe than Joda, wherein all the conversion methods take an Object parameter.
POSIX time is actually not the number of seconds since 00:00 UTC on January 1, 1970, but the 864000 times the number of days since January 1, 1970, plus the number of seconds since the start of the current day.
See "1. There are always 24 hours in a day" (or rather, there are always 60 seconds in a minute, since the leap second makes the last minute/hour of the day longer, so there are still 24 hours in the day)
I'm not sure what a "tick" is, but POSIX time often purports to be the number of seconds (or similar) since 1970, (and thus, represent an instant in time) but in practice it isn't; that's the point of the parent poster: it's precisely the definition that he or she gave. (It's the number of days times a constant, etc.) While usually POSIX time represents an instant in time, it becomes ambiguous during leap seconds, and duration calculations with POSIX times will almost invariably be just arithmetic on the underlying value, which is going to be wrong over certain intervals (any interval crossing a leap second).
For the most part, nobody notices, but this is where and why weird bugs crop up.
1. For events in the past, a timestamp
2. For events in the future, a date/time pair with precision at least milliseconds and a timezone.
3. An ISO 8601 serialization/deserialization method
4. A duration type, which denotes a number of 'hours/minutes/seconds/days/weeks'.
5. A partial representation of date, to denote repeating events or events which last a whole day. The partial representation should optionally include a timezone. This allows me to say: '5th of May', or '22nd of November 1980, in CEST'.
For calculations of dates and times, it is very useful to have a notion of time intervals, durations of time and weekdays.
Hmmm...Can you give an example where that would be used? I'm thinking of a user who wants to be woken up at 7am even if they change their timezone. But that wouldn't require millisecond precision.
> A duration type, which denotes a number of 'hours/minutes/seconds/days/weeks'.. For calculations of dates and times, it is very useful to have a notion of time intervals, durations of time and weekdays.
Couldn't you do that with the first two types I mentioned? With two instances of Type 1 it's trivial to count the number of milliseconds between them. With two instances of Type 2 you can have d1.daysUntil(d2) or dq.monthsUntil(d2) etc.
> This allows me to say: '5th of May'...
Is that common enough and complicated enough to warrant an extra type? When I write code to process credit card payments, I just record the card expiry as two integers: expMonth and expYear. When I want to check if the card is expired I just create a Type 2 instance representing the last day of the month. Seems to me I could do something similar for 'repeat on 5 May'.
That may seem like a special case, but it is relatively common, it might also matter for normal business meetings in a foreign country - UK time is an hour behind France, so if you are a UK business man trying to have a meeting in Paris, you need to take time zones into account.
It is never trivial to calculate the duration between two times, because you may have to take into account leap years, leap seconds, months that does not have the same number of days, etc, not to mention if they are in two different timezones. That doesn't mean it isn't possible, but it is not trivial.
What is the last day of the month? That depends on the month, and if that is February it also depends on the current year. If you need to process credit cards, you might need to know the last banking day of the month, which could be quite early during e.g easter. BTW to know when easter falls, your dating system needs to know about the lunar calendar.
This doesn't even begin to touch what happens in countries that celebrate Ramadahn.
A Skype call is actually a good example of when not to use a data type which encapsulates 'time zone plus instance in time'. That's because there is not one but multiple time zones associated with a single instance in time - each Skype caller will have his or her own time zone. The time of the call should be treated as a pure 'instance in time' without reference to any particular time zone. When it comes to displaying the time to a particular user, you would have formatting code which takes (a) the user's time zone; (b) the user's language; (c) a format pattern; and (d) the instance in time; and returns (e) a string representation of the time for that user.
If the computer's clock is based UTC it is trivial to find the duration between two 'instants in time': it's just t2 - t1. An instant in time (what I called Type 1) is independent of any calendar system so months, leap years, time zones, etc. don't matter when calculating the duration between two Type 1 values.
However, in practice most system clocks are not based on UTC but rather Unix Time [1]. Due to leap seconds, such clocks do not always 'tick' in a monotonic way. So I accept that it is usually not trivial to accurately find the duration between two times. But the solution is not to burden the programmer with an extra type - instead, just add a method to the existing 'instant in time' class like this: t1.millisecsUntil(t2).
To find the days in any given month, a 'date in the Gregorian calendar' class (what I call Type 2) can handle that easily - just call the daysInMonth() method. Again, no need to create new type.
Easter, Islamic dates, Buddhist dates, banking days, etc. are all based on Type 2 - ie. an abstract concept of a 'day' without reference to any time zone or any particular instant in time.
The duration in milliseconds is (almost always) easy to find. However, you often want to find the duration in months, weeks, days, etc. etc. This again requires a reference timezone and calendar system.
Your 'type 2' day is actually very difficult to define. For example, when I talk about the 12th of October 2016, I will see it as a time-interval in central European time. Your time-interval might be different. By the way, you can only handle the daysInMonth case. Other examples would fail: weeksInMonth, weeksInYear, hoursOfMonth, etc. etc.
The durations are very useful for basic arithmetic on time. An hour isn't always an 60 times 60 seconds (leap seconds) and a day isn't always 24 hours. So, if you have two buttons in your UI which move your appointment around, or which calculate the end-time of a one-hour appointment, you want to be able to use the type '1 hour', and not 60 times 60 times 1000 milliseconds.
The partial dates are very common and miscalculations are often made. It is notoriously difficult to calculate with partial dates and warrants a type with associated methods/functions. I see myself often writing something like: `new LocalDate(5,5).toInterval().contains(now)` (where obviously, the localdate is automatically deserialized from JSON or sth alike).
1. 1AM happens 24 times a day
2. Ok, so 1A is screwed up because of DST. Noon happens 24 times a day.
3. The maximum distance between time zones is 24 hrs
4. Time zones are in 1hr increments
5. In half hour increments?
6. UTC offset is a good thing to store in someone's profile
7. People live in a fixed number of UTC offsets
Time zones change linearly from east to west and west to east
For each physical location there is exactly one time zone
The time zone you use is a matter of geography, not political affiliation.
* One geographical location won't change its timezone over time
* Apart from DST, one geographical location won't change its timezone over time
* If a location changes timezone, the leap is always less than an hour, maybe a few hours
* Ok, less than a day
* Why are you talking about 2011, December 30th in Samoa Islands?
Care to elaborate?
What I understood was same geographical location with several time-zones at an instant in time.
Modulo border disputes I don't know of any such thing.
In those places, if you ask a user where they are, and then show them a time zone based on that, it may not reflect what they think.
No DST is awesome, but causes no end of coordination problems with people outside of AZ... for important meetings like job interviews basically the only option is to be prepped on both hours.
The reservation thing is fun with cell phones - in northern parts of the state, there are places where your cell phone will adjust time by an hour depending on which cell tower you manage to connect to. So one moment your screen will display 2:30, the next 3:30, and a few minutes later it's back to 2:30 again. You fall back to using relative times; "we'll meet in an hour, etc."
(I look at my watch, I have 2:30) "What time do you have?"
"3:30"
"Ok. Let's meet in an hour. That's 4:30 for you." (Which I know will be 3:30 for me)
My watch also runs for years on a single battery. I probably get asked for time once a week by somebody whose phone has died. (Wearing a watch is the universal symbol for "I have the time")
My chosen solution was a script to be triggered by a cronjob that ran when reports needed to be emailed out, but not otherwise, eg, at 6am in every timezone, every Monday. All I needed to do was figure out what times those were. Simple right?
It didn't take long until I realised I needed to make some concessions to reality. :)
As one example, some clocks are cpu specific (rather than system specific). When a thread gets scheduled to a different cpu, it might be talking to a different clock, and getting a backwards time.
The user might also be changing the clock while the program is running, of course.
If the forward direction of time is important, make sure the the source of time is a monotonic clock API.
The issues with timezones, and offset calculations can be problematic too... fortunately most environments and language platforms have systems in place to at least convert to/from local to utc, while that doesn't resolve for time drift, or mis-set times, it does handle a lot of issues to always use utc, or use date/time + location if not using utc...
Another hard one is leap minutes/seconds, daylight savings time changes, etc.
The linux kernel boots 5 minutes before the end of time, so that anyone whose code would break when jiffies wraparound will see that breakage soon after boot. That's a great, great feature.
One of my brothers worked for an embedded device manufacturer that got bitten. The software worked great unless it was started in the first five minutes after a reboot. But since booting and waiting five minutes is easy, the fix was, too.
The nonzero boot-time value made it simple to fix a bug that occurs every 497 days. Fantastic, say I.
That is, they did not account for wraparound, they just avoided it. Is that correct?
* Every week has a weekend
* Weekends are always Saturday and Sunday
* Weekend days never change within a locale
* Weekend days are always on consecutive days
Back when I used to work the night shift on non-standard days, doing any kind of scheduling with an electronic device was a real pain. Even today many scheduling tools don't cope well with overnight meetings.
https://en.wikipedia.org/wiki/Workweek_and_weekend#Muslim_co...
Another example from the same Wikipedia page :
> Brunei Darussalam has a non-contiguous working week, consisting of Monday to Thursday plus Saturday. The days of rest are Friday and Sunday.
* Weeks always start on Sunday
vs.
* Weeks always start on Monday
> Excel stores dates as sequential serial numbers so that they can be used in calculations. By default, January 1, 1900 is serial number 1, and January 1, 2008 is serial number 39448 because it is 39,447 days after January 1, 1900.
That's from the Microsoft's documentation of Excel[1]. Note this part: "because [Jan 1, 2008] is 39,447 days after January 1, 1900"
In [3]: (datetime.datetime(2008, 1, 1) - datetime.datetime(1900, 1, 1)).days
Out[3]: 39446
Off by one, Microsoft. And yes, Excel does the same thing — i.e., the docs match the product.If you're wondering why, it's b/c Excel incorrectly thinks that 1900 is a leap year. (Also, this is why a lot of Window's clocks track time since 1901, as it makes leap year calculations simpler… for now.)
[1]: https://support.office.com/en-us/article/DATEVALUE-function-...
* A timestamp is not a date.
Many people believe a timestamp is a "more detailed date". In reality, every timestamp is in (at least) two different dates, depending on what timezone you look at it in.
The terrible java.util.Date is probably one reason.
1) Given two events that happened in two different locations, one happened before the other or they happened at the same time [1]
2) All the devices comprising your system will agree on what offset each timezone is (alternatively: will have the same version of the tzdb)
Number 2 is not a theoretical problem: if you have users in a country where the timezone can change at short notice (e.g. Turkey), how do you handle the fact that across all the different Android versions their phones will have different opinions on what the time is and what timezone they are in?
[1] https://en.wikipedia.org/wiki/Relativity_of_simultaneity
Now in the case of dates, there's the epoch, and a precision determined in terms of that epoch, there are compatibility workarounds between 32-bit and 64-bit time... we add have leap days and leap seconds, and of course: the fact that clocks go out of sync, timezones and daylight saving time, as well as a long long list of things.
Some countries move dates for DST every year.
Then, there are days that "do not exist" (September 1752 in UK/US, etc, when they moved from the julian to the gregorian calendar).
See https://developer.apple.com/library/content/technotes/tn2169...
As a programmer you need to be able to make assumptions, otherwise it gets crazy complicated.
the solution i found (when dealing with this problem in C# a few years ago) is that you need to poll the time in an update loop (running at, say 10hz or whatever resolution you need). if you have a sudden jump in time between two loops, chances are the computer was asleep.
or there was a leap second.
or you are sampling local time instead of UTC and daylight savings just occurred, or the user crossed timezones.
or the user changed their clock manually.
Or the computer resynced with the time server (happens quite often, and can cause negative time to elapse. Better check the CPU for elapsed ticks instead!)
man... this is starting to sound like roll-your-own-cryptography ;)
I recommend submitting that to HN. Looks as if it was a couple of months ago, but definitely worth the resubmission as it didn't take:
https://hn.algolia.com/?query=https:%2F%2Fgithub.com%2Fkdeld...
pulling data from processes that run in different timezones and trying to merge that all together has been really fun.
-Your clock works the way you think it does
I was working for a company that makes pico-second clocks. It turns out, that all clocks experience drift. Like a gyroscope, each clock has it's own peculiarities and hyper-local environment, and like a gyroscope, they all tend to record and count time in different ways. If you have a clock, you know what time it is. But if you have 2 clocks, you are never sure. Now, we extend this to many clocks and we then have an ensemble of them, and (thank god) it ends up being a normal distribution that we then take the mean of. Now with picosecond clocks, the local gravitational environment, temperature, wear history, etc all end up being very big factors in time keeping. For most systems, this would be a catastrophe. You'd have to bury the clocks in some mountain, gravitationally 'shielded' away from things, temperature controlled, super clean, etc, and only take the time once a day or something. It turns out that if you run those calculations, you can only keep time to a part in 10^-16. Fortunately though, we discipline time to that of the Earth. Days and years are the thing we must subside to. And these things are only good to about a part in 10^-12, so we have 10,000 parts of 'error' to live in. It turns out, the Earth is a pretty bad clock, overall. It was pretty cool, years after I left that job, to walk into NIST and see an ensemble of our old clocks in the room where the US second is measured.
-Leap seconds always occur on the same date/time of the year.
The terrible earth-quake in Fukushima really did a number on the international timing community too. The change in distribution of mass of the Earth was so much that it slowed the year down by ~1 millisecond in total. I hope that the readers of the article and the rest of the comments here can appreciate that such a change, though to a normal person is small, is actually quite a lot for computers and other logic based systems. The 'leap-second', in reality a millisecond, was chosen to occur not on the last night of February of the following year, but was pushed forward to the last night of June. This did not make the people that sell super precise clocks very happy. Typically, the leap-second night is one of mayhem for clock sellers and the people that support the sold clocks. As this usually happens at midnight, far past when you have to put your kids to bed, the 'push notification' of the new time is in weary hours. That means starting about 1 minute after midnight, you start getting flooded with calls from your customers. Now, the purchasers of hyper-precise clocks tend to be very wealthy and powerful and very angry and sleepy that all of their very expensive computers are now 'all broke'd' in the literal middle of the night. Most of the time, you can reach out to the IT guys of these large oil&gas, Wall-Street, military, educational, and other types of firms and make contacts and let them know things will start to get out of whack. And they tend to learn that this usually happens in early March. Well, for this end of June leap-second, we knew things were going to be hairy. And they were. I was not even close to senior enough to be on those calls, but I came in the next day and all the senior guys were STILL on the phones with the various companies. When I left, they were on the phones still. I think they must have been up for at least 50 hours, judging by the amounts of RipIts scattered about the floors. That is what I call a salary job.
In all, I learned that humans think that time works in one way, but it really is 'what a clock measures' and is an abstract concept we put a lot of value into. And no, we will never be able to make a program that can take all of these considerations into account. All that will do is make the troubleshooting process a lot longer. Time is ephemeral, the Earth makes a bad clock, and mammals are diurnal. Those 3 things make clocks and time-keeping a 'hands on' job.
Falsehoods programmers believe: https://encrypted.google.com/search?hl=en&q=%22things%20prog...
http://www.metafilter.com/117073/Falsehoods-Programmers-Beli...
By way of lists, a pretty comprehensive one: http://spaceninja.com/2015/12/08/falsehoods-programmers-beli...
More in another comment: https://news.ycombinator.com/item?id=12675830
* That there's never a \0 in a pathname
wchar names on MSWin UNICODE and WinCE. Symbian uses UTF16.
* That paths are seperated by /
Yes, Windows NT accepts /, VMS, VOS, RISC OS also, but MacOS classic had :, and VMS uses []. And there are still \ pathseps only, like DOS, OS/2, SYMBIAN, Novell NETWARE, AmigaOS4. Native Acorn RISC OS uses . as pathsep and : as in DOS.
Just the easiest ones.
But what makes matters more complicated, is that on AmigaOS "/" is equivalent to "." on Unix systems, and "//" equivalent to "..", and "."/".." are legal filenames. AmigaOS doesn't have an equivalent to "/" in Unix (everything is rooted in a volume, and there are many volumes), but ":" can be used to prefix a path to make it relative to the root of the current volume...
It breaks all kinds of assumptions people make..
Could the system's timezone change? Yes. If you're manipulating time sanely, you're already using a timezone aware time class - particularly when serializing - and that's great. But if you're uncertain, it's best not to try to rectify. Your program will never be able to guess with any success.
Almost all of this post strikes me as along the vein of the questions of Babbage - "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" Almost all of these are the wrong numbers. Rather than leading you to the simple, correct solution (Use good serialization formats and timezone aware datastructures) it leads you down a path of paranoia, convinced the world is out to get you. If you're programming for that world, you're either a DRM programmer and should burn in hell, or you're doing it wrong. Trust your environment and OS and make damn sure that when you're setting up those layers you set them up right - Don't worry that every second open() call will return an invalid filehandle, just because.
There was a quote by a nasa engineer that an incorrect action is better than no action at all, but I cant find it at the moment.
Yesterday my friends Mac crashed hard while they were working on a foolishly unsaved one-and-a-half page document in LibreOffice.
At the next start LibreOffice gives a big warning of "Oh shit things are really wrong, should I fix them for you? [Continue | Cancel]" .
Thank you LibreOffice team for making it so that within the time of a phone call to me plus the time it took to press "Continue" they were able to recover the their document and continue working.
This "attempt to rectify" the problem, could only have made things better not worse, so that's reasonable to implement.
I am not saying that every problem needs a solution like this. But blanket statements like "crash whenever there is a problem with your environment", while certainly the correct way to do it in some cases, leads to software that's really shitty use if that's all the software does.
Because while
> Almost all of these are the wrong numbers.
is correct from a programmers point of view, we aren't talking about the numbers a user put in, but rather numbers that the user has no control about.
And not many things are more annoying than computers doing unexpected things for reasons that are incomprehensible to you.
There is no reason to handle leap seconds in a flappy bird game, or fork your database server to implement "proper" time handling with historically correct time zones and all the appropriate conversions between them, if you are writing a Twitter client.
> Thank you LibreOffice team for making it so that within the time of a phone call to me plus the time it took to press "Continue" they were able to recover the their document and continue working.
Uh, that's exactly what the OP was advocating, if I understand correctly. On a consistency check failure (i.e. an assert), crash immediately [1]. If the application correctly handle transactional state changes, it will be able to recover on startup from the replay log, as all changes are immediately persisted on the log.
This approach is known as "Crash Only Software", and it is pretty much the only approach for writing robust applications.
[1] Syncing the replay log to stable storage can be a good thing though.
High level talks about low-level concerns are rarely helpful. This overview of detailed problems without links or even understanding of the relevant literature (It doesn't even mention the scenario that time runs backwards, which is way more common and terrible than pretty much anything on the list). This was a bad post, and it's bad training - Bringing up superficial questions without giving places to check answers for sanity. Many people will likely think about these issues halfheartedly, form half-baked answers, and propagate mistakes. Good learning not only asks questions, but asks follow ups and helps reach complete solutions.
When it comes to time, a crash is not the most likely outcome of not thinking about what could happen. More likely your code will stall or do the wrong thing.
Think about polling, pinging other systems or rate limiting. At the end of daylight savings time your code could easily stall for an hour or DDOS another system because rate limiting fails.