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

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

1 Ответ

10 голосов
/ 28 июля 2011

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

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

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

С современными датами время всегда идет вперед, как вы и предполагали.С отрицательными историческими датами время фактически бежит назад!Полночь # 1/1/1800 # равняется -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 октября изкалендарь.:)

...