Это должно быть так просто, как:
public static DateTime FromJulian(double julianDate)
{
return new DateTime(
(long)((julianDate - 1721425.5) * TimeSpan.TicksPerDay),
DateTimeKind.Utc);
}
Как видите, 1721425.5
- это так называемая григорианская эпоха, то есть значение, которое юлианская дата имела в начале пролептического григорианского календаря, в 0001 1 января, 00:00: 00.0000000, откуда .NET DateTime
имеет свое происхождение.
РЕДАКТИРОВАТЬ: если вы хотите, чтобы ваш метод генерировал исключение на «крайних» входах вместо того, чтобы возвращать недопустимое значение, сделайте следующее:
public static DateTime FromJulian(double julianDate)
{
return new DateTime(
checked((long)((julianDate - 1721425.5) * TimeSpan.TicksPerDay)),
DateTimeKind.Utc);
}
Обратите внимание, что мы выполняем умножение с перегрузкой double operator *(double, double)
(встроенной в C #). Это дает как можно меньше ошибок. Преобразование из double
в long
вызовет checked
контекст, если double
находится вне диапазона long
. Если это преобразование прошло успешно, конструктор DateTime
может выдать ошибку, если значение long
выходит за пределы допустимого диапазона для .NET DateTime
.
НОВОЕ РЕДАКТИРОВАНИЕ: вдохновленный другим потоком (Преобразование DateTime в юлианскую дату в C # (ToOADate Safe?)), вы также можете разработать очень простое решение с использованием DateTime.FromOADate
. Тем не менее, см. Другую публикацию о переполнении стека, написанную мной, о недостатках точности метода FromOADate
.
person
Jeppe Stig Nielsen
schedule
20.09.2015