← Timeline
Avatar placeholder
Eliyahu Duvidzon
10-03-2021 11:34
Проблема 2000 года

Все объяснения про y2k говорят, что в девяностые памяти было мало и с целью экономии люди хранили две цифры из четырёх.

Так я не понимаю что это за экономия такая, когда дату хранят как строку? Минимальный формат даты в таком виде (yymmdd) занимает шесть (!) байт, тогда как в четыре влезает количество секунд (!) до 2038 года.

На самом деле прикол в том, что к концу века никто не помнил как менялись цифры левее десятков. Так что среди людей в среднем формат типа mm/dd/yy* был страшно популярен. А раз так, он использовался как формат сериализации. Дальше, нерадивые программисты которые хранили даты в сериализованном виде (не смотря на правда недешёвую память) спокойно могли получить свой y2k. Ну и передача по сети конечно.

Всё это усугублялось меньшим количеством реально работающих стандартов на эту тему. Сейчас если я сериализую даты, то по дефолту много где формат с милисекундами и разницей с gmt, не то что с четырьмя цифрами в году.

Я так понял, что в своё время было потрачено дохера денег, чтобы проверить, что все системы не подвержены этому багу, а если подвержены то исправить.

Не знаю на самом деле, сколько багов такого типа правда нужно было исправлять, но я сомневаюсь, что в критических системах их было много. Что не значит, что этого не надо было проверять.

Я гораздо больше боюсь проблемы 2038 раз уж на то пошло. Потому что хранить дату в юникс тайме это правда стандарт местами до сих пор.

*как мы понимаем, самая главная проблема с этим форматом, это день между месяцем и годом. такая запись не имеет права на существование, но почему-то всё равно популярна в америке 🤦‍♂️

To react or comment  View in Web Client
Comments (15)
Avatar placeholder

Когда-то компьютеры программисты не умели нормально считать, и предпочитали битмаски нетривиальным вычислениям.
В MSDOS FAT дата упаковывалась в 16 бит YYYYYYYMMMMDDDDD где YYY=год-1980, MMM=месяц, DDD=день.
Всё было бы хорошо до 2127 года, но вместо 1980+YYY многие ещё немного экономили и писали "19" 80+YYY , то есть даты на выходе получались, в зависимости от криворукости, 19100 или 1900

👍2
Avatar placeholder

многие ещё немного экономили и писали "19" 80+YYY

а это правда что-то давало или это вуду-оптимизация? потому что звучит, что от неё только хуже, особенно если в итоге нужно число

Avatar placeholder

Ну когда на ассемблере пишешь, может быть чуть короче. Говнокодеры существовали и 30 лет назад

Avatar placeholder

Кстати, на проблему 2037 года кто-то наступил уже в 2006 - они для получения "даты из будущего" прибавляли миллиард секунд у текущему времени

👍1
Avatar placeholder
Avatar placeholder

Так я не понимаю что это за экономия такая, когда дату хранят как строку? Минимальный формат даты в таком виде (yymmdd) занимает шесть (!) байт, тогда как в четыре влезает количество секунд (!) до 2038 года.

Кроме экономии места нужно было экономить вычисления. В 60-е гг., когда этот формат хранения даты укоренился в Коболе, реально думали, сколько лишних тактов понадобится для того или другого. И были сильны сторонники ассемблера, которые считали, что языки высокого уровня вообще не нужны, потому что тратят слишком много машинных ресурсов. Библиотеки тоже только начали появляться, а значит, как правило, всё, что не было встроено в язык, должно было быть написано с нуля в каждом новом проекте. Включая перевод даты в текст для отображения.

Я гораздо больше боюсь проблемы 2038 раз уж на то пошло. Потому что хранить дату в юникс тайме это правда стандарт местами до сих пор.

time_t уже везде 64-битный, так что проблема 2038 года будет актуальна или на каких-то очень старых системах, или в говнокоде.

👍3
Avatar placeholder

реально думали, сколько лишних тактов понадобится для того или другого

ок, но чтобы получить дату из строки yy нужно взять два байта каждый минус 48, один плюс другой и плюс 1900. Звучит как адъ по сравнению с просто хранить в одном байте значение года минус тот же 1900.

собственно моя мысль в том, что даже тогда если на хранении дат ты наступил на y2k, то это не оптимизация, это говнокод. потому что никакой оптимальный способ хранения чисел не упирается в круглые десятичные числа.

ну а сериализация с двумя символами на год с ней всё понятно, это не худшее что бывает.

time_t уже везде 64-битный, так что проблема 2038 года будет актуальна или на каких-то очень старых системах, или в говнокоде.

я по большей части про старый софт. грубо говоря в программе под 32битный вин ме двадцатилетней давности 32 time_t живёт на законных основаниях хотя бы. вопрос только в том откуда его забыли убрать

Avatar placeholder

ок, но чтобы получить дату из строки yy нужно взять два байта каждый минус 48, один плюс другой и плюс 1900. Звучит как адъ по сравнению с просто хранить в одном байте значение года минус тот же 1900.

А зачем получать число? Отображать, сравнивать, сортировать можно и без этого.

никакой оптимальный способ хранения чисел не упирается в круглые десятичные числа

Это если ты оптимизируешь по объему хранения. Но бывали и другие соображения. Ты слышал про binary-coded decimal, специальные команды для работы с ними? Про EBCDIC? Про разные размеры машинных слов в битах? Много было странных вещей в древние времена. И ещё - сейчас ты можешь легко сделать себе тулзу для визуализации чего угодно. А раньше было очень важно, что если ты отправляешь кусок базы данных прямо на печать, ты всё равно можешь увидеть, где там что.

👍1
Avatar placeholder
Avatar placeholder

но по сути понял и принял к сведению 🙂

то есть вместо "в девяностые памяти было мало и люди из экономии не хранили первых две цифры" правильнее говорить "в девяностые было дохера странных способов хранить даты, значительная часть которых могла иметь проблемы в районе 2000 года".

👍3
Avatar placeholder

Binary coded decimal это отдельный маленький адок, достойный своей статьи. Я удивляюсь, какой сон менеджерского разума породил это чудовище, и как оно было популярно пару десятков лет

👍1
Avatar placeholder

Ну я так понимаю, с перфокарты человеку легко прочитать такое число без произведения особых вычислений, просто помня двоичные репрезентации десяти цифр.

👍1
Avatar placeholder

А кроме того

BCD is very common in electronic systems where a numeric value is to be displayed, especially in systems consisting solely of digital logic, and not containing a microprocessor. By employing BCD, the manipulation of numerical data for display can be greatly simplified by treating each digit as a separate single sub-circuit. This matches much more closely the physical reality of display hardware—a designer might choose to use a series of separate identical seven-segment displays to build a metering circuit, for example. If the numeric quantity were stored and manipulated as pure binary, interfacing with such a display would require complex circuitry. Therefore, in cases where the calculations are relatively simple, working throughout with BCD can lead to an overall simpler system than converting to and from binary. Most pocket calculators do all their calculations in BCD.

The same argument applies when hardware of this type uses an embedded microcontroller or other small processor. Often, representing numbers internally in BCD format results in smaller code, since a conversion from or to binary representation can be expensive on such limited processors. For these applications, some small processors feature dedicated arithmetic modes, which assist when writing routines that manipulate BCD quantities.

😮1
Avatar placeholder

Представление на перфокарте это даже проще, чем EBCDIC - цифра это одна дырочка на соответствующем месте

Avatar placeholder

Ну это самый удобочитаемый вариант, а были и "бинарные" (люди хотели втискивать в перфокарты больше информации).

To react or comment  View in Web Client