我想使用30天的月份从日期时间对象中减去时间跨度,忽略闰年等。
Date is 1983/5/1 13:0:0 (y/m/d-h:m:s)
Time span is 2/4/28-2:51:0 (y/m/d-h:m:s)
我可以使用DateTime和TimeSpan对象将时间跨度的年份和月份转换为天数(假设每月30天,每年约364天)。
new DateTime(1981,5,1,13,0,0).Subtract(new TimeSpan(878,13,51,0));
有了这个,我得到了结果:
{12/4/1978 11:09:00 PM}
上面的答案显然不会忽略我想忽略的因素,并给我一个准确的答案。但在这种情况下,这不是我想要的,所以我写了下面的代码。
public static CustomDateTime operator -(CustomDateTime DT1,CustomDateTime DT2)
{
CustomDateTime retVal = new CustomDateTime();
try
{
const int daysPerYear = 364.25;
const int monthsPerYear = 12;
const int daysPerMonth = 30;
const int hoursPerDay = 24;
const int minutesPerHour = 60;
retVal.Minute = DT1.Minute - DT2.Minute;
if (retVal.Minute < 0)
{
retVal.Minute += minutesPerHour;
DT1.Hour -= 1;
}
retVal.Hour = DT1.Hour - DT2.Hour;
if (retVal.Hour < 0)
{
retVal.Hour += hoursPerDay;
DT1.Day -= 1;
}
retVal.Day = DT1.Day - DT2.Day;
if (retVal.Day < 0)
{
retVal.Day += daysPerMonth;
DT1.Month -= 1;
}
retVal.Month = DT1.Month - DT2.Month;
if (retVal.Month < 0)
{
retVal.Month += monthsPerYear;
DT1.Year -= 1;
}
retVal.Year = DT1.Year - DT2.Year;
}
catch (Exception ex) { }
return retVal;
}
然后我得到:
1981/0/3-10:9:0
这非常接近我所追求的,除了我不应该每月0和年应该是1980年。任何形式的帮助都表示赞赏。
只是为了让事情再次清楚;在这种情况下,我必须使用一个30天的月份,忽略闰年,不同的月份等。我知道这是一件奇怪的事情。所以我几乎都是在“错误答案”之后,而不是托管类给出的确切答案。
答案 0 :(得分:2)
如果您估计30个月的一个月,当然您的数学将会被取消。当您从1981年5月1日减去878天时,.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天。 1981年5月1日是一年中的第121天,因此减去120到1979年1月1日。这将留下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);
答案 1 :(得分:1)
你不能假设一个30天的月份。您指定要减去878天。托管类(我假设你的意思是当你说本地时管理的)被设计成考虑闰年,不同的月数等。
使用托管类不会给你一个月的0。