Подтвердить что ты не робот

Существует ли версия функции Delphi EncodeDate/DecodeDate, которая может обрабатывать B.C. даты?

Функции Delphi EncodeDate/DecodeDate, похоже, способны обрабатывать только даты после 1.1.0001. Существуют ли некоторые версии EncodeDate/DecodeDate, которые могут обрабатывать B.C. Значения tDateTime?

4b9b3361

Ответ 1

AFAIK TDateTime - это базовый тип Windows, общий для COM, Variants, DotNet и Delphi. Отрицательные значения могут использоваться для дат до 1899 года.

Но это не так просто - поскольку с отрицательными значениями возникает какая-то проблема, как указанная на этой странице:

Неотъемлемой частью является дата, дробь - это время. Date.time. Это просто. Вещи становятся нечетными, когда значение отрицательное. Это включено или до # 12/30/1899 #.

С современными датами время всегда бежит вперед, как вы подозреваете. С отрицательными историческими датами время действительно бежит назад! Midnight # 1/1/1800 # equals -36522, но полдень # 1/1/1800 # -36522.5 (меньше полночь!) и за одну секунду до полуночи -36522.9999884259 (даже Меньше). В полночь часы перескакивают вперед до -36521, что равно # 1/2/1800 #. Десятичная дробь все еще показывает время и интеграл часть - это дата, но каждая секунда уменьшает часы, в то время как каждая новая день увеличивает его, а не только на 1, но почти на 2. Отрицательные моменты действительно противоречивый.

Чтобы ухудшить ситуацию, значения времени для # 12/30/1899 # являются двусмысленными двумя способами. Во-первых, значение времени без даты равно этому времени на # 12/30/1899 #. Это означает, что 0,5 - полдень или полдень на # 12/30/1899 #, в зависимости от контекста. Ноль - либо полночь, # 12/30/1899 # или полночь # 12/30/1899 #. Другая двусмысленность в том, что все временные значения в два раза за # 12/30/1899 #. 0,5 - полдень № 12/30/1899 #, но -0,5 - полдень №12/30/1899 #. Неотъемлемой частью является дата, фракция - это время. Еще один сюрприз здесь: # 12/30/1899 11:59:59 PM # - # 12/29/1899 11:59:59 PM # = 2.99997685185185. Не 1, что вы обычно ожидаете в течение 24-часового периода. Будьте осторожны, когда работая с историческими датами.

Насколько я знаю, текущая реализация EncodeDate/DecodeDate будет работать, но вы можете столкнуться с проблемами при работе с отрицательными или близкими к нулю значениям TDateTime...

Вам лучше использовать свой собственный формат времени, например. ISO-8601 или простая запись как таковая:

TMyDateTime = packed record
  Year: SmallInt;
  Month: Byte;
  Day: Byte;
end;

И когда вы вычисляете информацию о продолжительности или показываете дату/время, вы должны знать, что "наше время" не является непрерывным. Поэтому вычисление с использованием трюка TDateTime=double не всегда будет работать должным образом. Например, я помню, что Тереза ​​из Авилы умерла в 1582 году, 4 октября, так же, как католические нации перешли от юлианского к григорианскому календарю, что потребовало удаление 5-14 октября из календаря.:)