我一直在尝试使用以下公式将给定的日期转换为刻度,由于我刚刚开始编写此函数,因此我尚未考虑month
和day
的值:>
public static long DateToTicks(int year, int month, int day) {
var leapYears = (year - 1) / 4;
var result = ((year - 1) * 365 * OneDay.Ticks) + (leapYears * OneDay.Ticks);
return result;
}
OneDay.Ticks
是一个常量,其值为3600 * 24 * 1000 * 10000
。
我所面临的问题是,当我从零天(即0001-01-01、0002-01-01)开始计算滴答声时,它可以正常工作,直到我到达101年,再获得一天!我将结果与DateTime
中.Net Core
结构返回的值进行比较。例如:
var myResult = DateToTicks(100, 01, 01);
var dateTimeResult = new DateTime(100,01,01).Ticks;
在此日期之前,myResult == dateTimeResult
始终为真,但是当我进入下一个世纪时,我看到DateTime
struct返回的结果落后一天,而当我进入下一个世纪时,该值将翻倍。
但是,我知道在101年中,有25个leap年,这意味着我必须将75
年乘以365
,其余的乘以366
,然后将它们相加,我不明白为什么我的结果与点网的DateTime
结果不同。
我的方法有什么问题?鉴于该日期和日期并不重要(始终设置为01
)。
答案 0 :(得分:2)
因为您似乎不想看C#代码。我在那儿找你-花了我1分钟时间
private static long DateToTicks(int year, int month, int day) {
if (year >= 1 && year <= 9999 && month >= 1 && month <= 12) {
int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
if (day >= 1 && day <= days[month] - days[month - 1]) {
int y = year - 1;
int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
return n * TicksPerDay;
}
}
throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
}
和
public static bool IsLeapYear(int year) {
if (year < 1 || year > 9999) {
throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_Year"));
}
Contract.EndContractBlock();
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
这是直接链接
https://referencesource.microsoft.com/#mscorlib/system/datetime.cs,891f8af5025ab2f3
答案 1 :(得分:0)
将您的leap年计算逻辑更改为此,即可正常工作:
var leapYears = ((year - 1) / 4) - (year / 400 > 0 ? ((year) / 100) - (((year) / 400)) : ((year - 1) / 100)) + (year % 100 == 0 && year % 400 != 0 ? 1 : 0) + (year == 100 || year == 200 || year == 300 ? -1 : 0);
答案 2 :(得分:-1)
简单地除以4并不是确定a年的正确方法。
这是测试for年的一种方法:
年份可以平均除以4;
如果年份可以除以100,则不是NOT年,除非;
该年份也可以平均除以400。然后是a年。
因此,1900年不是a年,而2000年是a年。