解释ToUnixTimeMilliseconds
Explain ToUnixTimeMilliseconds
我正在尝试寻找更好的方法将 DateTime 转换为 C# 中的 unix 时间戳
我发现有一个DateTimeOffset.ToUnixTimeMilliseconds方法:
public long ToUnixTimeMilliseconds()
{
return this.UtcDateTime.Ticks / 10000L - 62135596800000L;
}
这个方法是什么意思? 常量有什么用?
更新:
我猜 10000L 正在从 FRAME 转换为毫秒。但是 62135596800000L 呢?
解释一下这个方法:
public long ToUnixTimeMilliseconds()
{
return this.UtcDateTime.Ticks / 10000L - 62135596800000L;
}
DateTime.Ticks单位是100纳秒间隔。
将此除以 10_000 得到毫秒,这解释了除以 10000L。
这是因为一纳秒是十亿分之一秒,也就是百万分之一毫秒。
要将纳秒转换为毫秒,您需要除以 1_000_000。
但是,刻度是 100 纳秒单位,因此除以 1_000_000 之外,您必须除以 1_000_000/100 = 10_000。这就是为什么将 100 纳秒单位除以 10_000 得到毫秒。
Unix 纪元(对应于零的 Unix 时间)是 1970 年 1 月 1 日午夜。
日期时间纪元(对应于 DateTime.Ticks 零值)是 0001 年 1 月 1 日。
从 0001 年 1 月 1 日到 1970 年 1 月 1 日之间的毫秒数是 62135596800000。这解释了 62135596800000 的减法。
给你!
注意:您可以计算近似值 毫秒数,如下所示:
Approximate number of days per year = 365.24219
Number of years between 0001 and 1970 = 1969
Thus, total approx milliseconds = 1969 * 365.24219 * 24 * 60 * 60 * 1000
= 62135585750000
确切的数字很难计算,但按照上面的公式计算出来是 62135596800000。
其实通过the source code的考察我们可以发现:
public long ToUnixTimeSeconds() {
// Truncate sub-second precision before offsetting by the Unix Epoch to avoid
// the last digit being off by one for dates that result in negative Unix times.
//
// For example, consider the DateTimeOffset 12/31/1969 12:59:59.001 +0
// ticks = 621355967990010000
// ticksFromEpoch = ticks - UnixEpochTicks = -9990000
// secondsFromEpoch = ticksFromEpoch / TimeSpan.TicksPerSecond = 0
//
// Notice that secondsFromEpoch is rounded *up* by the truncation induced by integer division,
// whereas we actually always want to round *down* when converting to Unix time. This happens
// automatically for positive Unix time values. Now the example becomes:
// seconds = ticks / TimeSpan.TicksPerSecond = 62135596799
// secondsFromEpoch = seconds - UnixEpochSeconds = -1
//
// In other words, we want to consistently round toward the time 1/1/0001 00:00:00,
// rather than toward the Unix Epoch (1/1/1970 00:00:00).
long seconds = UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
return seconds - UnixEpochSeconds;
}
// Number of days in a non-leap year
private const int DaysPerYear = 365;
// Number of days in 4 years
private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
// Number of days in 100 years
private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
// Number of days in 400 years
private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
// Number of days from 1/1/0001 to 12/31/1600
private const int DaysTo1601 = DaysPer400Years * 4; // 584388
// Number of days from 1/1/0001 to 12/30/1899
private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
// Number of days from 1/1/0001 to 12/31/1969
internal const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
我们现在可以使用它来计算到 1970 年的毫秒数:
719162 (DaysTo1970) * 24 (hours) * 60 (minutes) * 60 (seconds) * 1000 (milliseconds)
= 621355967990000
我正在尝试寻找更好的方法将 DateTime 转换为 C# 中的 unix 时间戳
我发现有一个DateTimeOffset.ToUnixTimeMilliseconds方法:
public long ToUnixTimeMilliseconds()
{
return this.UtcDateTime.Ticks / 10000L - 62135596800000L;
}
这个方法是什么意思? 常量有什么用?
更新: 我猜 10000L 正在从 FRAME 转换为毫秒。但是 62135596800000L 呢?
解释一下这个方法:
public long ToUnixTimeMilliseconds()
{
return this.UtcDateTime.Ticks / 10000L - 62135596800000L;
}
DateTime.Ticks单位是100纳秒间隔。
将此除以 10_000 得到毫秒,这解释了除以 10000L。
这是因为一纳秒是十亿分之一秒,也就是百万分之一毫秒。
要将纳秒转换为毫秒,您需要除以 1_000_000。
但是,刻度是 100 纳秒单位,因此除以 1_000_000 之外,您必须除以 1_000_000/100 = 10_000。这就是为什么将 100 纳秒单位除以 10_000 得到毫秒。
Unix 纪元(对应于零的 Unix 时间)是 1970 年 1 月 1 日午夜。
日期时间纪元(对应于 DateTime.Ticks 零值)是 0001 年 1 月 1 日。
从 0001 年 1 月 1 日到 1970 年 1 月 1 日之间的毫秒数是 62135596800000。这解释了 62135596800000 的减法。
给你!
注意:您可以计算近似值 毫秒数,如下所示:
Approximate number of days per year = 365.24219
Number of years between 0001 and 1970 = 1969
Thus, total approx milliseconds = 1969 * 365.24219 * 24 * 60 * 60 * 1000
= 62135585750000
确切的数字很难计算,但按照上面的公式计算出来是 62135596800000。
其实通过the source code的考察我们可以发现:
public long ToUnixTimeSeconds() {
// Truncate sub-second precision before offsetting by the Unix Epoch to avoid
// the last digit being off by one for dates that result in negative Unix times.
//
// For example, consider the DateTimeOffset 12/31/1969 12:59:59.001 +0
// ticks = 621355967990010000
// ticksFromEpoch = ticks - UnixEpochTicks = -9990000
// secondsFromEpoch = ticksFromEpoch / TimeSpan.TicksPerSecond = 0
//
// Notice that secondsFromEpoch is rounded *up* by the truncation induced by integer division,
// whereas we actually always want to round *down* when converting to Unix time. This happens
// automatically for positive Unix time values. Now the example becomes:
// seconds = ticks / TimeSpan.TicksPerSecond = 62135596799
// secondsFromEpoch = seconds - UnixEpochSeconds = -1
//
// In other words, we want to consistently round toward the time 1/1/0001 00:00:00,
// rather than toward the Unix Epoch (1/1/1970 00:00:00).
long seconds = UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
return seconds - UnixEpochSeconds;
}
// Number of days in a non-leap year
private const int DaysPerYear = 365;
// Number of days in 4 years
private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
// Number of days in 100 years
private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
// Number of days in 400 years
private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
// Number of days from 1/1/0001 to 12/31/1600
private const int DaysTo1601 = DaysPer400Years * 4; // 584388
// Number of days from 1/1/0001 to 12/30/1899
private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
// Number of days from 1/1/0001 to 12/31/1969
internal const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
我们现在可以使用它来计算到 1970 年的毫秒数:
719162 (DaysTo1970) * 24 (hours) * 60 (minutes) * 60 (seconds) * 1000 (milliseconds)
= 621355967990000