EPPlus портит даты

179
24 марта 2018, 13:36

В общем, читаю Excel, где есть колонки с датой.

Когда я считываю Value в переменную, то дата превращается в такое число 38574.

Как можно это пофиксить?

В excel ячейка с датой выглядит так:

когда считываю ячейку

 var cellVal = ws.Cells[i, kvp.Item1].Value?.ToString().Trim()??"";

получаю вот такую цифру:

38574

Если вызвать DateTime.FromOADate, то дата преобразуется в нормальную.

1)Можно ли этого избежать и сразу получать нормальную дату?

2)Если нет, то как я могу понять, что число является датой, что бы вызвать преобразование?

Answer 1

Комментить пока не могу. Поэтому пользуюсь формой ответа.

Я, как и @vikttur Пастернака (си-диез) тоже не читал. Но по Екселю он правильно написал, только очень кратко. Я местами его повторю (не в упрек :))

Все твои телодвижения, упомянутые в вопросе и в комменте - от лукавого. Получилось, типо, и ладно...

То, что ты видишь на экране в ячейке Екселя - форматированное представление даты. А дата у него состоит из целой части - дни откуда-то там, и дробной части текущих суток. По сути - Double. Но есть нюансы (мы не про них), поэтому Ексель, а по сути - не Ексель, а VBA, для хранения даты использует свой, суррогатный тип данных Date.

Вот тут и возникает основной момент: начиная манипулировать с датой нужно явно привести ее в Double dDate_As_Double = CDbl(dDate_As_Date). После этого можно совершать различные манипуляции. Ну, а когда надо будет ее вернуть VBA взад - так же, явно, конвертнуть обратно dDate_As_Date = CDate(dDate_As_Double).

Т.е. на VBA это выглядело бы так:

'
dDate_As_Date_Src = ws.Cells[i, kvp.Item1].Value
dDate_As_Double_Src = CDbl(dDate_As_Date_Src)
' ... do any you want, For example:
dDate_As_Double_Tgt = dDate_As_Double_Src + 5             ' add 5 days
dDate_As_Double_Tgt = dDate_As_Double_Tgt - (5 / 24)      ' minus 5 hours
dDate_As_Double_Tgt = dDate_As_Double_Tgt + (31 / 1440)   ' plus 31 minutes
dDate_As_Double_Tgt = dDate_As_Double_Tgt + (17 / 86400)  ' plus 17 seconds
dDate_As_Double_Tgt = dDate_As_Double_Tgt - (0.003141592) ' minus Pi milliseconds 
dDate_As_Date_Tgt = CDate(dDate_As_Double)
ws.Cells[i, kvp.Item1].Value = dDate_As_Date_Tgt
'

Плюсов у такого подхода - мульон. Например:
- все эти ужимки и прыжки с первым днем недели, первой неделей года, началом недели каким днем - остаются за скобками простой арифметики;
- разница между датами считается влет;
- доступны манипуляции с отрицательными величинами;
- етсетера, етсетера, как писал великий летчик-артиллерист АС - Пушкин. .

Add:

Однако, все равно хотелось бы знать способ определения формата ячеек.

Что значит "определения"?

Велика и могуча русская языка. Редкий птиц ... etc. :)

Если узнать формат: есть RW свойство у ячейки Cells(1,1).NumberFormat, емнип...
Если задать формат: опять через него же... :)

Запиши рекордером макрос - будет тебе рыба. По встроенным форматам - Ф1. По пользовательским помощь слабовата, но тоже сгодится для начала.

Только зачем, в контексте вышеизложенного? Ты же знаешь, к какой ячейке ты обращаешься и что в ней лежит. Хотя, если дата сильно гуляет по точности и величине в результате вычислений, то может и понадобится изменить ее формат (читай - экранное представление).
.

Answer 2

Нашёл решение в виде вызова Text вместо Value.

Однако, все равно хотелось бы знать способ определения формата ячеек.

READ ALSO
Передача контекста базы данных

Передача контекста базы данных

Начал изучать юнит-тестыВозникла проблема

196
Парсинг текста из файла в форму

Парсинг текста из файла в форму

Делаю программу для парсинга текста из файловПрограмма для анкетирования

173
Как узнать глубину рекурсии?

Как узнать глубину рекурсии?

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

266
Не работают функции slideDown и fadeOut

Не работают функции slideDown и fadeOut

По идее должно делать плавную анимацию и при загрузке плавно появляться, но выдает ошибку, что slideDown и fadeOut не являются функцией

193