Как преобразовать двойное значение в DateTime в С#?

У меня есть значение 40880.051388, и я сохраняю его как двойное, если я открою Excel и вставлю в ячейку и применю следующий пользовательский формат «m/d/yyyy h:mm" к этой ячейке, я получаю "12/3/2011 1:14"

Как я могу сделать этот синтаксический анализ/преобразование в С#? Я не знаю, является ли значение миллисекундами от определенной контрольной точки, например времени эпохи, или значение находится в каком-то специально подготовленном формате, но как excel получает это конкретное значение? Можно ли это сделать на С#?

Я пытался работать с TimeSpan, DateTime и другими подобными вещами в Visual Studio, но ничего не получаю.


person fifamaniac04    schedule 17.12.2012    source источник
comment
Возможно, вам поможет: stackoverflow.com /вопросы/8829171/   -  person Felipe Oriani    schedule 17.12.2012
comment
если вы не знаете, что на самом деле представляет собой число, как вы узнаете, что выбор формата Excel правильный? Вы должны знать, какой дате на самом деле соответствует это число, и определить, что логически представляет это число, прежде чем решать, как его запрограммировать.   -  person Servy    schedule 17.12.2012
comment
возможный дубликат Как преобразовать double в datetime между Excel и С#   -  person Andrew Whitaker    schedule 17.12.2012


Ответы (5)


Похоже, вы используете старую дату OLE-автоматизации< /а>. Использовать

DateTime.FromOADate(myDouble)
person Jaime Torres    schedule 17.12.2012
comment
@JoelRondeau Я только что обнаружил, что DateTime.FromOADate дает точность всего в 1 миллисекунду. Вы можете получить гораздо более высокую точность, если вам не все равно. См. мой новый ответ в старой ветке. - person Jeppe Stig Nielsen; 18.12.2012

Попробуйте что-то вроде этого: -

double d = 40880.051388 ;
DateTime dt = DateTime.FromOADate(d);
person Rahul Tripathi    schedule 17.12.2012

Попробуйте использовать var dateTime = DateTime.FromOADate(40880.051388);.

Если вам нужно отформатировать его в строку, используйте для этого dateTime.ToString("M/d/yyyy H:mm", CultureInfo.InvariantCulture). Это даст вам 24-часовую строку (измените H на h для 12-часовой системы).

Если вам нужна большая точность (в 1000 или более раз), чем предлагает FromOADate, см. мой ответ в другой ветке.

person Jeppe Stig Nielsen    schedule 17.12.2012

Значение представляет собой смещение в днях с 30 декабря 1899 года. Итак, вы хотите:

new DateTime(1899, 12, 30).AddDays(40880.051388)
person Cory Nelson    schedule 17.12.2012
comment
Вы правы, я забыл, что они используют 30 декабря 1899 года в качестве отправной точки. Странные люди из Excel. Фиксированный. - person Cory Nelson; 17.12.2012
comment
@EricLippert Совершенно верно. Но также он теряет точность, потому что аргумент округляется/усекается до ближайшей миллисекунды. Вы знаете, почему фреймворк всегда отбрасывает такую ​​точность? Это не имеет никакого смысла. Я только что написал длинный ответ в другой ветке, который, надеюсь, вы захотите прочитать. - person Jeppe Stig Nielsen; 18.12.2012

Следующий простой код будет работать

DateTime.FromOADate(myDouble)

Однако, если производительность критична, она может работать недостаточно быстро. Эта операция очень требовательна к процессору, поскольку диапазон дат для формата даты OLE-автоматизации начинается с 30 декабря 1899 года, тогда как DateTime начинается с 1 января 0001 года по григорианскому календарю.

FromOADate вызывает функцию DoubleDateToTicks, используя myDouble в качестве единственного аргумента. Это возвращает количество тиков, и это значение используется для создания нового DateTime с неуказанным DateTimeKind.

Подавляющая часть этой работы выполняется функцией DoubleDateToTicks в mscorlib. Это включает в себя код для создания исключения ArgumentException, когда значение двойного числа равно NaN, и существует множество способов оптимизации производительности в зависимости от ваших конкретных потребностей.

person Kevin O'Shaughnessy    schedule 06.04.2016