Я пытаюсь поддерживать еврейский календарь в своем проекте Noda Time , и мне нужно поддержать операцию «добавить год» — или, в более общем смысле, ответить на вопрос «Учитывая исходную дату и целевой номер года, что получится в результате?» свидание?"
Во-первых, я хотел бы проверить, правильно ли я говорю, что Microsoft неправильно дает ответ в .NET. Например, рассмотрим дату этого поста: 8 Сивана, 5774 год. Сиван — это 10-й месяц в системе нумерации гражданских месяцев високосного года, а 5774 год — високосный. Если мы добавим один год к сегодняшней дате, .NET сохранит номер месяца (10), оставив нам 8-й тамуз, 5775, потому что 5775 не високосный год. (Вспомогательный код находится внизу этого вопроса 1 .) Мне это кажется неправильным - следует сохранить сам месяц, а не номер месяца .
Предполагая, что мой подход верен (и что мы должны более разумно закончить с номером месяца 9, который является Сиваном в невисокосный год), это все еще оставляет некоторые крайние случаи:
У меня есть предложение:
Я считаю, что это близко, но не совсем так, как правило дня рождения, указанное в Календарных расчетах ( задокументировано для Hebcal ), где 30-е число (Адар I/Кислев/Хешван) будет сопоставлено с 1-м числом следующего месяца... но так пока приведенное выше предложение разумно в соответствии с еврейской традицией, оно будет более соответствовать другим аспектам моего кодекса. (Я рад выбросить последовательность из окна, если есть веская причина, но я бы предпочел сохранить ее в противном случае.)
Одним из проблемных аспектов всего этого является то, что он должен быть вне контекста. Я знаю, что вполне могут быть разные правила для разных контекстов, но, к сожалению, мне нужно правило «общего назначения».
Итак, разумно ли это предложение, или мне еще многое предстоит узнать о том, как отвечать даже на простые вопросы о еврейском календаре?
1 Справочный код .NET:
using System;
using System.Globalization;
class Test
{
static void Main()
{
var calendar = new HebrewCalendar();
DateTime start = new DateTime(5774, 10, 8, calendar);
// Prints 5774-10-08
Console.WriteLine(FormatYearMonthDay(start, calendar));
DateTime end = calendar.AddYears(start, 1);
// Prints 5775-10-08
Console.WriteLine(FormatYearMonthDay(end, calendar));
}
static string FormatYearMonthDay(DateTime date, Calendar calendar)
{
return string.Format("{0}-{1}-{2}",
calendar.GetYear(date),
calendar.GetMonth(date),
calendar.GetDayOfMonth(date));
}
}
Вы правы в том, что реализация .NET, по-видимому, не соответствует Галахе (т.е. еврейскому закону) ( Орах Хаим 55:10 и Мишне Берура там же), и ваши первые 2 правила верны и соответствуют Галахе .
Расчеты по еврейскому закону (там же, MB 45) правильно реализованы в HebCal вопреки вашему третьему правилу. В частности, если мальчик родился 30 хешвана 5700 года, его бар-мицва, отмечаемая через 13 лет, приходится на 1 кислева 5713 года.
Интересно, что если мальчик родился 1 кислева 5700 г., когда в хешване было всего 29 дней, он будет отмечать свою бар-мицву 30 хешвана 5713 г. Предположительно, возможно, HebCal опускает это правило, поскольку оно может зависеть от контекста бар-мицвы. предметом споров (см. Shaarei Teshuva , там же), а также кажется аномальным. См. здесь обоснование этого решения (стр. 11, вверху).
Я предполагаю, что пользователи расчетов еврейского календаря (такие как я!) будут ожидать соответствия еврейскому закону, потому что, вероятно, именно поэтому они используют календарь в первую очередь. Любая другая реализация будет сбивать с толку, несмотря на алгоритмическую элегантность или согласованность с существующим кодом.
Если бы мне пришлось реализовать эту функцию, я, вероятно, следовал бы правилам HebCal и, возможно, перегрузил бы addYears
метод, чтобы он принимал boolean isBarMitzva
параметр, который будет соответствовать правилам бар-мицвы. Таким образом, пользователи поймут, что календарные расчеты могут выполняться по другим правилам и не приведут к неожиданным результатам.
PS Я большой поклонник вашего "C# in Depth" и рекомендую его всем своим студентам.
Вы правы, для Адара I и Адара II результатом добавления года обычно будет Адар II, поскольку первый Адар (Адар I) является добавленным месяцем.
Что касается лишнего дня в месяце, то вообще все сдвигается на день вперед. (30 хешван == 1 кислев).
(Есть исключения из этого, но я думаю, что как правило - вы охватываете большинство случаев, для которых будет использоваться ваш календарь. Возможно, было бы полезно добавить перегрузку для выполнения «тупых» вычислений, как внедрение Microsoft.)
DanF
Джон Скит
мш210
Калеб
мш210
Джон Скит