How do you convert epoch time in C#?
如何在C中将Unix epoch time转换为实时?(从1970年1月1日开始的新纪元)
我假定您的意思是Unix时间,它定义为1970年1月1日午夜(UTC)以来的秒数。
1 2 3 4 5 | public static DateTime FromUnixTime(long unixTime) { return epoch.AddSeconds(unixTime); } private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); |
最新版本的.NET(v4.6)刚刚添加了对Unix时间转换的内置支持。这包括以秒或毫秒表示的到Unix时间和从Unix时间。
- 到
DateTimeOffset 的Unix时间(秒):
1 | DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000); |
DateTimeOffset 到unix的时间(秒):
1 | long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds(); |
。
- 到
DateTimeOffset 的Unix时间(毫秒):
1 | DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000); |
DateTimeOffset 到unix的时间(毫秒):
1 | long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds(); |
。
注:这些方法与
1 | DateTime dateTime = dateTimeOffset.UtcDateTime; |
号
由于所有的功劳都归功于Lukeh,我将一些扩展方法放在一起以便于使用:
1 2 3 4 5 6 7 8 9 10 11 | public static DateTime FromUnixTime(this long unixTime) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return epoch.AddSeconds(unixTime); } public static long ToUnixTime(this DateTime date) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return Convert.ToInt64((date - epoch).TotalSeconds); } |
号
请注意,下面来自codesinchaos的评论,上面的
1 2 3 4 5 | public static long ToUnixTime(this DateTime date) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds); } |
如果不想在从datetime移动到epoch时创建epoch datetime实例,也可以执行以下操作:
1 2 3 4 | public static long ToUnixTime(this DateTime date) { return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000; } |
。
您实际上想要添加毫秒(毫秒),而不是秒。添加秒将给您一个超出范围的异常。
如果您想要更好的性能,可以使用这个版本。
1 2 3 4 5 6 7 8 9 | public const long UnixEpochTicks = 621355968000000000; public const long TicksPerMillisecond = 10000; public const long TicksPerSecond = TicksPerMillisecond * 1000; //[MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime FromUnixTimestamp(this long unixTime) { return new DateTime(UnixEpochTicks + unixTime * TicksPerSecond); } |
号
从net471下的快速基准(benchmarkdotnet)中,我得到这个数字:
1 2 3 4 | Method | Mean | Error | StdDev | Scaled | -------------- |---------:|----------:|----------:|-------:| LukeH | 5.897 ns | 0.0897 ns | 0.0795 ns | 1.00 | MyCustom | 3.176 ns | 0.0573 ns | 0.0536 ns | 0.54 | |
号
比Lukeh的版本快2倍(如果性能更好的话)
这类似于datetime内部的工作方式。
1 2 3 4 5 6 | // convert datetime to unix epoch seconds public static long ToUnixTime(DateTime date) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds); } |
应该对datetime对象使用touniversaltime()。
我使用以下扩展方法进行历元转换
1 2 3 4 5 6 7 8 9 10 11 12 | public static int GetEpochSeconds(this DateTime date) { TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1); return (int)t.TotalSeconds; } public static DateTime FromEpochSeconds(this DateTime date, long EpochSeconds) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return epoch.AddSeconds(EpochSeconds); } |
号
使用datetimeoffset.tounixtimemillises()方法返回1970-01-01t00:00:00.000z以来经过的毫秒数。
This is only supported with Framework 4.6 or higher
号
1 | var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); |
号
这里有很好的记录:datetimeoffset.tounixTime毫秒
如果您不使用4.6,这可能有助于源代码:system.identitymodel.tokens
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /// <summary> /// DateTime as UTV for UnixEpoch /// </summary> public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); /// <summary> /// Per JWT spec: /// Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time. /// </summary> /// <param name="datetime">The DateTime to convert to seconds.</param> /// <remarks>if dateTimeUtc less than UnixEpoch, return 0</remarks> /// <returns>the number of seconds since Unix Epoch.</returns> public static long GetIntDate(DateTime datetime) { DateTime dateTimeUtc = datetime; if (datetime.Kind != DateTimeKind.Utc) { dateTimeUtc = datetime.ToUniversalTime(); } if (dateTimeUtc.ToUniversalTime() <= UnixEpoch) { return 0; } return (long)(dateTimeUtc - UnixEpoch).TotalSeconds; } |
号
如果您需要将包含
1 2 3 4 5 6 7 | DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private DateTime UnixTimeToDateTime(Timeval unixTime) { return _epochTime.AddTicks( unixTime.Seconds * TimeSpan.TicksPerSecond + unixTime.Microseconds * TimeSpan.TicksPerMillisecond/1000); } |
。
这是我的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public long GetTime() { DateTime dtCurTime = DateTime.Now.ToUniversalTime(); DateTime dtEpochStartTime = Convert.ToDateTime("1/1/1970 0:00:00 AM"); TimeSpan ts = dtCurTime.Subtract(dtEpochStartTime); double epochtime; epochtime = ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds); return Convert.ToInt64(epochtime); } |
。