[С# 9.0 и net7.0]
(* основная просьба редактировать)
(Почему Excel может иметь одно и то же представление значения даты как разные даты? 43708 может быть 31/08/19 и 01/09/23)
Дополнительную информацию о результате этого наблюдения можно найти в проблеме github («Некогерентное значение DateTime»)
У меня есть файл .xlsx из запроса HttpClient, и я читаю эти байты как поток. Я пытаюсь использовать ExcelDataReader в потоке; Я обнаружил, что значения даты и времени неверны. В таблице есть только один столбец даты, и все даты начинаются с 2021 года.
Все даты и время, прочитанные с помощью IExcelDataReader, являются конкретно 31/08/2019 - это не может быть из-за приведенного выше утверждения.
Когда я протестировал его на своем персональном компьютере, даты вернулись правильно, и я понял, что для передачи этого файла на мой компьютер мне пришлось сохранить его с помощью Excel.
Поток из запроса имеет ~ 2079 байт, в то время как файл (сохраненный Excel) имеет ~ 5569, поэтому я сравнил структуру байтов в обоих файлах в блокноте ++ и много тестировал, чтобы убедиться, что исходная версия на самом деле никогда не возвращает даты правильно (каждый другие данные верны), а вот с измененным все в порядке. Я проверил это поведение на 3 машинах, и результаты одинаковы. Итак, вот сделка
Я уже использую библиотеку ExcelDataReader, поэтому не хочу использовать другую для решения той же проблемы.
Исходный файл из запроса заканчивается словами «Реализация Антона Шеффера», буквально написанным в файле.
Уточнение
В то время как сохраненная версия Excel издается более понятным образом.
Глядя на структуру файла .xlsx как .zip в Windows, мы можем получить доступ к записи: xl/worksheets/sheet1.xml, хранящей данные таблицы из файла. В столбце 14º, дата один, значение, записанное в файл, равно 43708 это значение может быть интерпретировано excel двумя способами,
на 31.08.19 или 01.09.23. Я не знаю, что это определяет.
@T.Nielsen, я пытался изменить конфигурацию региона, но это просто перевернуло положение чисел. К сожалению, остается то же значение даты
Вы можете довольно легко заглянуть внутрь файла XLSX (как программист). Это ZIP-файлы, в основном содержащие структуру папок и XML. Если вы переименуете файл .XLSX в .ZIP и откроете его с помощью инструмента для работы с zip-файлами, вы сможете осмотреться внутри своего файла. Не ожидайте большого просветления, глядя на двоичный поток. Инструмент повышения производительности OpenXML SDK может позволить вам проверить структуру файла OpenXML (который представляет собой .XLSX) и сказать вам, что с ним не так. В эти дни Microsoft скрывает это на GitHub (последний раз, когда я ходил на охоту)





Я обнаружил, что дата всегда постоянно сдвигается на 1462 дня в прошлое. Я знаю, что это не решает корень проблемы, но пока это решение для нашего бизнеса. Добавление пропущенных дней к прочитанному значению устраняет проблему.
Спасибо @Flydog57 за объяснение того, что файлы xlsx структурированы как zip-файлы, поэтому я мог получить доступ к внутреннему содержимому файла и прочитать необработанные данные xml. Значения, записанные в содержимое xml в целевом столбце, равны 43708, что является числовым представлением даты 31/08/2019 буквально. В сохраненной версии файла excel то же значение 43708 представлено как 09.01.2023, причина этого остается неизвестной.
сравнение:
необработанный файл:
Excel сохраненный файл:
Я оставлю вопрос открытым, потому что эта непоследовательность представления необработанных значений даты интересна, и я действительно хотел бы знать, почему это происходит.
я думаю об удалении контекста С# и тегов отсюда, так как фокус вопроса сместился, и не так много кода задействовано
Внутри xlsx должен быть какой-то XML, например, <workbookPr date1904 = "true" defaultThemeVersion = "124226"/> — это сообщает Excel/ExcelDataReader, как интерпретировать числовые значения даты. Ошибка в том, что флаг date1904 не поднимается в ExcelDataReader, хотя должен!
@user8728340 user8728340, просматривая внутренний класс xlsWorkbook в библиотеке, есть внутреннее свойство, в котором хранится значение 1904, я не знаю, является ли это беспорядком от читателя, поэтому я закрыл проблему github и предположил, что это структурная проблема из превосходить
То, что вы видите, похоже, зависит от системы дат, установленной в вашем приложении Excel для книги.
Используя систему дат 1904 года, 43708 преобразуется в 1-Sep-2023
Используя систему дат 1900 года, 43708 преобразуется в 31-Aug-2019
Настройка находится под File=>Options=>Advanced=>When Calculating this Workbook
Excel хранит даты в виде порядковых номеров, начинающихся либо с 1/1/1900, либо с 1/1/1904, в зависимости от выбранной системы дат.
Большинство окон устанавливает по умолчанию систему дат 1900 года. При установке Mac по умолчанию использовалась система дат 1904 года. Вы должны знать, что система дат 1900 года имеет преднамеренную ошибку (предположительно, чтобы быть совместимой со случайной ошибкой Lotus 123), в которой 1900 год считается високосным.
См. Различия между системами дат 1900 и 1904 годов в Excel для более подробного объяснения.
В зависимости от ваших требований вам может потребоваться изменить систему дат в книге или использовать полученную вами константу 1462.
Спасибо за источник и тщательное объяснение с точки зрения Excel. Даже если в приложении (С#) я не мог использовать интерфейс excel для настройки этого всякий раз, когда это было необходимо для обработки отчета, знания, предоставленные вами, остаются полностью полезными.
Библиотека Excel, которая создала этот файл — PL/SQL «as_xlsx» Антона Шлеффера — сохраняет файлы с нестандартным значением свойства рабочей книги «date1904». Сам Excel устанавливает для свойства date1904 значение 1, но в файлах, созданных «as_xlsx», это true. ExcelDataReader не поддерживает это конкретное отклонение и продолжает возвращать неправильные даты на 4 года позже.
обычно мы видим такие вещи при использовании Excel, имеющего либо разные локализации времени выполнения на машине, либо фактические форматы файлов. специфичные для даты и времени такие настройки, как настройки среды и использование возможностей excel, неявно использующих те, которые вам могут повезти, это один из них. serverfault.com/questions/948175/…