Timeline for Did many programs really store years as two characters (Y2K bug)?
Current License: CC BY-SA 4.0
36 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jun 24, 2020 at 11:56 | comment | added | Chromatix | @supercat That still takes code space and active power. I think maybe you don't understand embedded development very well. | |
Jun 23, 2020 at 23:15 | comment | added | supercat | @Chromatix: Subtract 1461 until the result goes negative. Such a loop would require 25 iterations per 100 years. Then add 365 until it goes positive (a max of four iterations). | |
Jun 23, 2020 at 23:09 | comment | added | Chromatix | @supercat This still requires a routine to perform division with remainder by a 12-bit divisor, which is not trivial. On a full-fledged PC you can do whatever you like, but on a severely cost and power limited device, working in BCD is easier overall. | |
Jun 23, 2020 at 21:48 | comment | added | supercat | Given a Unix-style time, divide by 3600, subtract the number of hours between the Epoch and 2:00am local time of the first Sunday in March in the epoch. Then divide by 24 (note the residue), get the residue mod 1461, and the residue mod 365 to get the Sunday-relative yearday. If greater than 180 and the hour residue was 23, add 1 to the yearday. Depending upon the exact daylight savings rules, check for a yearday within a certain range and you're done. It's not even necessary to have a month-length table. | |
Jun 23, 2020 at 17:22 | comment | added | manassehkatz-Moving 2 Codidact | I've done this using YYMMDDhhmmss dates/times - build a table for the local time zone and see where the times hit. Not that big a deal. The big deal is usually figuring out what the data is supposed to be - and sometimes that means receiving data during standard time and not knowing until the next DST change whether the sending system will adjust for DST itself or not. I've seen it all... | |
Jun 23, 2020 at 17:09 | comment | added | supercat | @manassehkatz-Moving2Codidact: The simplest way I know of to handle DST correctly is to convert dates/times to linear UTC, and then identify within IO routines whether a particular date/time combo is within the daylight saving time interval. Making this work retrospectively requires having a list of DST-rule changes, but YYMMDDhhmmss dates/times are not a convenient format for such purposes. | |
Jun 22, 2020 at 22:26 | comment | added | manassehkatz-Moving 2 Codidact | and start/end dates change over time in different locations. As far as weekday from YYMMDD - that's easy, just make your assumption (depending on the use case) as to the century and then day-of-week is trivial. | |
Jun 22, 2020 at 22:25 | comment | added | manassehkatz-Moving 2 Codidact | @supercat DST - I've seen that butchered so often with modern systems that I'm almost surprised when it is done right on any system - old or new. For example, I have received numerous calendar invites via Outlook that have a time listed "mm/dd/yyyy hh:mm STANDARD TIME" during the summer and almost always the sender has no clue and intends the same time in DST - e.g., if they say 10:00AM STANDARD they really mean 10:00AM DST. And that's on a modern system with plenty of CPU cycles and RAM to handle anything! Plus can't expect a small RTC to get DST right anyway because the formula | |
Jun 22, 2020 at 19:20 | comment | added | supercat | @Chromatix: If one wants to do anything with values other than display them, code will be required to handle advancement across different lengths of month. How would you go about applying the end of daylight saving time if the system is powered on between 12:00am and 1:00am? And how would you compute a weekday from a YYMMDD-format date? | |
Jun 22, 2020 at 13:41 | comment | added | Chromatix | @supercat The only month that has a day count below 30 is February, which already needs special handling due to leap years. The incrementing is done within the RTC hardware anyway, the point is that the values don't need to be manipulated just to display them. | |
Jun 21, 2020 at 22:33 | comment | added | supercat | @Chromatix: BTW, how would one efficiently go about incrementing a YYMMDD-format date on a 4-bit micro? Even on a 4-bit micro, the logic to convert a number from up to 0x3:0xB into a decimal number up to 0x5:0x9 would seem easier than the comparison logic necessary to handle months whose lengths may have an upper nybble that is either 0x2 or 0x3. | |
Jun 21, 2020 at 22:24 | comment | added | supercat | @Chromatix: Incidentally, a similar issue arises with zero-terminated strings. There are some use cases where they offer some advantages over alternative formats, but unless strings are of trivial length, or the only thing one will do with a string is process the characters thereof sequentially, tracking the length as a number will be better than trying to use the location of the first zero. | |
Jun 21, 2020 at 21:41 | comment | added | supercat | @Chromatix: If a project never has to do anything with an RTC value other than display it, and in particular never needs to do any sort of arithmetic with times, then BCD RTC may offer some slight advantage over a linear counter. The moment a program has to do anything else with the value, however, any advantages that the hardware-parsed date would have had evaporate. Suppose, for example, one is supposed to have a clock automatically set the day of the week when given month+day+year. Really easy when using linear time. How would you figure out the weekday for a YYMMDD date? | |
Jun 21, 2020 at 21:38 | comment | added | supercat | @Chromatix: The primary reason for a specialized RTC chip or peripheral is to for situations where the main CPU is fabricated with a process that is optimized for speed instead of quiescent current. An RTC which is on a separate die, or is on the same die but can be kept powered while everything else is powered down, can use much less current when the system is idle than would be possible if the main CPU had to wake up once per second to bump a counter. If one is using a slow-speed low-quiescent-current CPU, however, there would be no need to have a dedicated hardware RTC. | |
Jun 21, 2020 at 19:36 | comment | added | Chromatix | @supercat Great! Now implement that on a 4-bit microcontroller with 256 bytes of ROM and a microamp power budget. Do you now see the problem? | |
Jun 21, 2020 at 19:20 | comment | added | supercat | @Chromatix: Ever since I started writing date-linearizing code, I've used March 1, 2000 as my epoch; if one treats March 1 as new-year day, one can always treat February as having 29 days since the year will advance after day 365 of most years. Once one has day from March 1, subtract out as many months as will fit, incrementing the month counter, and if the month is 13 or 14, subtract 12 and bump the year. Not really much harder than what would be done to increment a date. | |
Jun 21, 2020 at 19:17 | comment | added | supercat | @Chromatix: ...the remainder in that global. To e.g. divide a four-byte value by 60, zero the global, and then invoke that routine on each byte in sequence. The global will be left holding the residue. To convert a time to a date, use divmod32by8 to divide out 60, 60, and 24. One can then process the remaining linear date using 16-bit math. Then zero the year counter and, while the value is at least 1461, add 4 to the year and subtract 1461 from the counter. Then add two to the year if the value exceeds 730 (subtract 730, and one if it exceeds 365 (subtract 365). | |
Jun 21, 2020 at 19:13 | comment | added | supercat | @Chromatix: If one wants to do automatic daylight saving time compensation, or do almost anything with time other than display it as-is, one will need a way of adding an interval to a date, subtracting an interval from a date, and subtracting two dates to yield an interval. If one exploits a few tricks, converting a linear date to a YYYYMMDDhhmmss date is easy and efficient. Use a routine that divides a two-byte number whose upper byte is at a global and whose lower byte is targeted by a pointer, by a byte which is at least as big as the upper byte, placing the quotient at the pointer and... | |
Jun 21, 2020 at 19:06 | comment | added | rcgldr | Correction to my prior comment, the 6301 RTC assumes 00 is a leap year. It advances year 00 month 02 day 28 to year 00 month 02 day 29, then year 00 month 02 day 29 to year 00 month 03 day 01. This works for year 2000, but not 1900 or 2100. | |
Jun 21, 2020 at 17:56 | comment | added | Chromatix | @supercat If you presuppose that your computer has a sophisticated date/time processing library, then it probably does make sense to implement a straight binary counter and let the host CPU turn it into something human readable. However, most devices containing RTC hardware have extremely limited processing capability. The discrete RTC chips are most likely direct derivatives of the hardware that also goes into watches, clock radios, and suchlike. Having the RTC work in human-readable format directly is then more convenient. | |
Jun 21, 2020 at 17:51 | comment | added | Chromatix | @supercat It depends what sort of processing you're doing with it. Implementing the RTC hardware itself is quite simple, as evidenced by the fact that you can run an RTC chip off a button cell for several years without it losing time. The two BCD counters making up a pair of digits are simply mapped to a single byte when it comes to reading and writing them, and simple gate networks are sufficient to perform limit checking even on digit pairs. | |
Jun 21, 2020 at 16:28 | comment | added | supercat | @Chromatix: Sure, if one stores each digit separately, and ignores the effort required to deal with variable-length months, etc. But how is working with twelve BCD digits, some of which have to be limit-checked in pairs, easier than working with a 32-bit quantity? | |
Jun 21, 2020 at 15:16 | comment | added | Chromatix | @supercat Incrementing in BCD is simple enough that there are 74-series logic chips that can do it. You just need to reset the digit to zero and emit a carry, instead of stepping to the next higher value, when the 8 and 1 bits are set. By comparison, efficient linear time conversion requires the ability to multiply and divide. | |
Jun 21, 2020 at 14:57 | comment | added | supercat | @Raffzahn: Is advancing BCD date-time fields forward and backward significantly easier than converting to linear time and back? | |
Jun 21, 2020 at 8:09 | comment | added | Raffzahn | @supercat One can apply any local correction factor on a BCD date the very same way as on a time stamp. Done that, been there - with a system that had to enter, plan and utput dated for worldwide use with adjustment for either phase depending on viewpoint - a UK manager needs to see dates in another frame than an IN based engineer working in NP supervised by from SG. And don't even get me going on the added complexions by service level and its times as well as hollidays and work hours of either party involved :) Nonetheless, it worked quite great using BCD date/time fields. | |
Jun 21, 2020 at 7:16 | comment | added | supercat | @manassehkatz-Moving2Codidact: In places that observe daylight saving time, the correct time would be February 28 or 29, depending upon the year, at 11:30pm. When working with a Unix-style linear time, subtracting an hour for time change is simple. But with a BCD date, it's a lot harder. | |
Jun 21, 2020 at 5:45 | comment | added | manassehkatz-Moving 2 Codidact | @Raffzahn I actually thought of that. In most modern cases, that's likely to be the case. But for example with typical wired (even if cordless, but wired base station) phones, date/time is stored in RTC and only updated from the network as a side-effect of Caller ID - no incoming calls, no date/time update. | |
Jun 21, 2020 at 5:30 | comment | added | Raffzahn | @manassehkatz-Moving2Codidact If it's a phone, it'll get the actual date when connectingto the network anyway ... an if not connecting, the date might be the least issue :) | |
Jun 21, 2020 at 5:21 | comment | added | manassehkatz-Moving 2 Codidact | @supercat It should show whatever the RTC says. If the RTC was working correctly (I'm assuming it gets updated while the phone is off, just like in a typical computer) then that should be the correct date/time. | |
Jun 21, 2020 at 5:02 | comment | added | supercat | @manassehkatz-Moving2Codidact: So if when the phone is powered on the RTC says March 1, 30 minutes after midnight, and the last time the phone had been powered on was in September, what time and date should it show? | |
Jun 21, 2020 at 4:58 | comment | added | manassehkatz-Moving 2 Codidact | @supercat The hardware (but really software - firmware or microcode?) is marginally more expensive, but it means that retrieval is much simpler, as you don't have to decode a number of days (what's the start date? leap years?) into YYMMDD, which is what you typically want. Unless you want Unix time...then the Y2038 problem. | |
Jun 20, 2020 at 22:08 | comment | added | supercat | @scruss: Even the RTC hardware built into some 32-bit ARM chips such as the STM 32L series uses BCD for everything. What irks me most about such things is that there are very few applications where having a hardware clock in YYMMDD format would offer any advantage whatsoever compared with having a linear counter, despite the fact that the hardware is almost certainly more expensive. | |
Jun 20, 2020 at 19:38 | comment | added | rcgldr | There is a rollover issue with RTC. The Atari 520 ST and 1040 ST use a 6301 RTC chip. The chip will rollover from year "00" to year "01" assuming year "00" is a leap year. This works for 2000, but not for 1900 or 2100. The Atari ST BIOS just adds or subtracts 80 from the year when converting from/to the RTC format to a 16 bit integer format, where the year field is year minus 1980 (same as PC-DOS). I wrote a program to support years 1980 to 2079 with the RTC. | |
Jun 20, 2020 at 17:09 | comment | added | scruss | I was surprised to find that most standalone RTC chips only support two-digit BCD years, seemingly to maintain a level of compatibility with the IBM PC AT's MC146818. Ranging and century assumptions will cause additional problems with leap years, too. | |
Jun 20, 2020 at 16:26 | comment | added | Raffzahn | Don't forget that many systems would go about this with an assumption of useful range not matching a century. One system I know goes by a simple 'compile date + 30 years' rule. So when compiled 2020 all values of 50 and below will get 100 added, with a result still being an offset to 1900. As a result the range of 51..99 will be mapped to 1951..1999, while 00..50 reslts in 2000..2050. All based on the assumption that the software won't survive 30 years (after the last release) and future dates are far ahead. Of curse other applications use other, better fitting strategies. | |
Jun 20, 2020 at 14:45 | history | answered | Chromatix | CC BY-SA 4.0 |