Если вы рассчитываете месяц на 30 дней, конечно, ваша математика будет отключена. Когда вы вычитаете 878 дней с 01.05.1981 г., .Net дает вам точную разницу, а не оценку, и эта разница учитывает високосные годы, если они есть. Ошибка не в методе Subtract (...), а в ваших собственных «ручных» вычислениях.
DateTime dt = new DateTime(1981, 5, 1, 13, 0, 0);
TimeSpan t = new TimeSpan(878, 13, 51, 0);
dt.Ticks
624931668000000000
t.Ticks
759090600000000
dt.Ticks - t.Ticks
624172577400000000
new DateTime(dt2)
{12/4/1978 11:09:00 PM}
Date: {12/4/1978 12:00:00 AM}
Day: 4
DayOfWeek: Monday
DayOfYear: 338
Hour: 23
Kind: Unspecified
Millisecond: 0
Minute: 9
Month: 12
Second: 0
Ticks: 624172577400000000
TimeOfDay: {23:09:00}
Year: 1978
Это общее количество тиков с эпохи. Сделайте эту математику, затем конвертируйте обратно в дату и время.
Также: исправьте свою математику. 878 дней - это 2 года и 148 дней. 01.05.1981 - 121-й день в году, поэтому вычтите 120, чтобы получить 1 января 1979 года. Это оставляет 28 дней. Начните считать в обратном направлении с конца 1978 года, и вы получите очень близко к ответу .Net. Ваш собственный ответ не близко.
РЕДАКТИРОВАТЬ на основе обратной связи
// zh-Hans is a chinese culture
CultureInfo ci = CultureInfo.GetCultureInfo("zh-Hans");
DateTime dt = new DateTime(1981, 5, 1, 13, 0, 0, ci.Calendar);
TimeSpan t = new TimeSpan(878, 13, 51, 0);
Обратите внимание, что вы все еще отнимаете 878 дней. Продолжительность месяца в этом случае не имеет значения, основываясь на юлианском календаре. Вероятно, вам нужно будет найти правильный код культуры для вашего конкретного календаря, а затем попробуйте это. Однако , с этим календарем я все равно получаю тот же ответ выше.
Помимо этого, я не уверен, как еще сделать математику. Если вы можете предоставить ссылку на то, как вы это делаете вручную, я могу помочь вам написать код.
РЕДАКТИРОВАТЬ 2
Теперь я понимаю. Попробуйте это:
DateTime dt = new DateTime(1981, 5, 1, 13, 0, 0, ci.Calendar);
int years = 878 / 365;
int remainingDays = 878 % 365;
int months = remainingDays / 30;
remainingDays = remainingDays % 30;
TimeSpan t = new TimeSpan(years * 365 + months * 30 + remainingDays);
DateTime newdate = dt.Subtract(t);