В общем, читаю Excel, где есть колонки с датой.
Когда я считываю Value в переменную, то дата превращается в такое число 38574.
Как можно это пофиксить?
В excel ячейка с датой выглядит так:
когда считываю ячейку
var cellVal = ws.Cells[i, kvp.Item1].Value?.ToString().Trim()??"";
получаю вот такую цифру:
38574
Если вызвать DateTime.FromOADate, то дата преобразуется в нормальную.
1)Можно ли этого избежать и сразу получать нормальную дату?
2)Если нет, то как я могу понять, что число является датой, что бы вызвать преобразование?
Комментить пока не могу. Поэтому пользуюсь формой ответа.
Я, как и @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. По пользовательским помощь слабовата, но тоже сгодится для начала.
Только зачем, в контексте вышеизложенного? Ты же знаешь, к какой ячейке ты обращаешься и что в ней лежит. Хотя, если дата сильно гуляет по точности и величине в результате вычислений, то может и понадобится изменить ее формат (читай - экранное представление).
.
Нашёл решение в виде вызова Text вместо Value.
Однако, все равно хотелось бы знать способ определения формата ячеек.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Делаю программу для парсинга текста из файловПрограмма для анкетирования
как узнать глубину рекурсии или как реализовать эту программу:Написать для NodeJS функцию, которая рекурсивно выводит список всех файлов и папок...
По идее должно делать плавную анимацию и при загрузке плавно появляться, но выдает ошибку, что slideDown и fadeOut не являются функцией