Почему рабочие дни Excel неправильны для 1900 года?

27

Этот вопрос основан на наблюдениях AdamV в его ответе на вопросе Как мне ввести название дня в ячейку в Excel?

Когда A1 имеет значение 2009-08-01, тогда:

  • =WEEKDAY(A1) получит 7
  • =TEXT(7, "dddd") получит Saturday
  • =TEXT(7,"dddd, yyyy-mm-dd") получит Saturday, 1900-01-07
  • =TEXT(1,"dddd, yyyy-mm-dd") получит Sunday, 1900-01-01
  • =TEXT("1900-01-01","dddd, yyyy-mm-dd") также получит Sunday, 1900-01-01

Последние два неверны: 1 января 1900 года фактически понедельник.
Различные источники подтверждают, что:

Чего мне не хватает? Почему Excel делает это неправильно?

Йерун Вирт Плюмерс
источник
1
Благодаря этому вопросу я немного перефразировал свой предыдущий ответ, чтобы прояснить, что 01.01.1900 не воскресенье, но Excel считает, что это так. Неточность не меняет сути того предыдущего ответа, который заключается в том, что использование номера дня недели в качестве основы для получения текста, отформатированного так, чтобы выглядеть как дата, является ошибочным и ненужным.
AdamV

Ответы:

40

Как описано в Microsoft KB 214058 :

Дни недели до 1 марта 1900 года в Excel неверны

БОЛЬШЕ ИНФОРМАЦИИ

Когда система дат в Microsoft Excel была изначально создана, она была разработана для полной совместимости с системами дат, используемыми другими программами для работы с электронными таблицами.

Однако в этой системе дат 1900 год неправильно интерпретируется как високосный. Поскольку в 1900 году не существует 29 февраля («високосный день»), день недели для любой даты до 1 марта 1900 года (день после «високосного дня») вычисляется неправильно.

«Другие программы для работы с электронными таблицами» относятся к Lotus 1-2-3 , который был довольно популярен в то время и неправильно предполагал, что 1900 год был високосным. Это объясняется еще более подробно в КБ 214326 :

Excel 2000 неверно предполагает, что 1900 год является високосным

БОЛЬШЕ ИНФОРМАЦИИ

Когда Lotus 1-2-3 был впервые выпущен, программа предполагала, что 1900 год был високосным, хотя на самом деле это не был високосный год. Это облегчало программе работу с високосными годами и не наносило вреда практически всем вычислениям дат в Lotus 1-2-3.

Когда были выпущены Microsoft Multiplan и Microsoft Excel, они также предположили, что 1900 год был високосным. Это предположение позволило Microsoft Multiplan и Microsoft Excel использовать одну и ту же систему последовательной даты, используемую Lotus 1-2-3, и обеспечить большую совместимость с Lotus 1-2-3. Отношение к 1900 году как к високосному году также облегчало пользователям перемещение рабочих листов из одной программы в другую.

Хотя технически возможно исправить это поведение так, чтобы в текущих версиях Microsoft Excel не предполагалось, что 1900 год является високосным, недостатки этого перевешивают преимущества.

Если бы это поведение было исправлено, возникло бы много проблем, включая следующие:

  • Почти все даты в текущих рабочих листах Microsoft Excel и других документах будут сокращены на один день. Исправление этого сдвига потребовало бы значительного времени и усилий, особенно в формулах, использующих даты.
  • Некоторые функции, такие как функция WEEKDAY, будут возвращать разные значения; это может привести к некорректной работе формул в таблицах.
  • Исправление этого поведения нарушило бы совместимость последовательных дат между Microsoft Excel и другими программами, которые используют даты.

Если поведение остается неисправленным, возникает только одна проблема:

  • Функция WEEKDAY возвращает неверные значения дат до 1 марта 1900 года. Поскольку большинство пользователей не используют даты до 1 марта 1900 года, эта проблема встречается редко.
grawity
источник
10
Вот связанный рассказ из стека биржи собственного Джоэла Спольски: joelonsoftware.com/items/2006/06/16.html
матовый
5
Смотрите также . Многие программисты ошибочно полагают, что работать с датами / временем легко :)
BlueRaja - Дэнни Пфлугхофт
3
Исторический придира: когда вы говорите, что 1-2-3 было «довольно популярным», вы подразумеваете, что когда-то это была доминирующая таблица
Исаак Рабинович
12

Вот причина, объясняемая самим Джоэлом: мой первый обзор BillG

Basic использует 31 декабря 1899 г. как эпоху вместо 1 января 1900 г., но по какой-то причине сегодняшняя дата в Excel была такой же, как и в Basic.

А?

Я пошел, чтобы найти разработчика Excel, который был достаточно взрослым, чтобы вспомнить почему. Эд Фрис, казалось, знал ответ.

«О,» сказал он мне. «Проверьте 28 февраля 1900 года».

«Сейчас 59», - сказал я.

«Теперь попробуй 1 марта».

"Это 61!"

"Что случилось с 60?" Эд спросил.

«29 февраля. 1900 год был високосным! Он делится на 4!»

«Хорошее предположение, но без сигары», - сказал Эд и на некоторое время заставил меня задуматься.

К сожалению. Я провел небольшое исследование. Годы, которые делятся на 100, не являются високосными, если они также не делятся на 400.

1900 год не был високосным.

"Это ошибка в Excel!" Я воскликнул.

"Ну, не совсем", сказал Эд. «Мы должны были сделать это таким образом, потому что мы должны иметь возможность импортировать листы Lotus 123».

«Так это ошибка в Lotus 123?»

«Да, но, вероятно, намеренный. Lotus должен был уместиться в 640K. Это не много памяти. Если вы игнорируете 1900, вы можете выяснить, является ли данный год високосным, просто посмотрев, есть ли самые правые два бита». равны нулю. Это действительно быстро и просто. Ребята из Lotus, вероятно, решили, что не имеет значения ошибаться в течение этих двух месяцев в прошлом.

Гиорги
источник
1
@JeroenWiertPluimers: На самом деле мой ответ с этой ссылкой был удален модератором, и я решил расширить свой ответ.
Георгий
2

Одним из решений этой проблемы является добавление 400 лет к году, чтобы определить рабочий день, как показано в следующей формуле = WEEKDAY (DATE (A4 + 400, B4, C4), 1), поэтому, если A4 = 1834, B4 = 12, C4 = 14. это вернуло бы 1 (воскресенье), что соответствует 14 декабря 2234 года. Это прекращает работать для дат до 1753 года, следующего за изменением григорианского календаря.

Адриан
источник