如何在C#中将Unix 时期时间转换为实际时间?(始于1970年1月1日的时期)
2020更新
您可以使用DateTimeOffset来完成此操作。
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(epochSeconds);
DateTimeOffset dateTimeOffset2 = DateTimeOffset.FromUnixTimeMilliseconds(epochMilliseconds);
如果你需要 DateTime
对象而不是 DateTimeOffset
,那么可以调用 DateTime
属性
DateTime dateTime = dateTimeOffset.DateTime;
我猜你指的是Unix时间,它被定义为自1970年1月1日午夜(UTC)以来的秒数。
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime FromUnixTime(long unixTime)
{
return epoch.AddSeconds(unixTime);
}
.Net最新版本(v4.6)新增了对Unix时间的内置支持,包括从秒或毫秒表示的Unix时间转换为DateTimeOffset
以及从DateTimeOffset
转换为秒或毫秒表示的Unix时间。
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
转换为 Unix 时间戳(秒):long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
转换为毫秒级 Unix 时间:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
注意:这些方法用于将值转换为和从DateTimeOffset
转换。若要获取DateTime
表示,请使用DateTimeOffset.DateTime
属性:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
的问题,我该如何解决? - Happy Bird在此感谢LukeH,我整理了一些扩展方法以便于使用:
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 的评论,指出上述的 FromUnixTime
返回一个带有 Kind
为 Utc
的 DateTime
,这是可以接受的,但上述的 ToUnixTime
更加可疑,因为它没有考虑给定的 date
是什么类型的 DateTime
。为了允许 date
的 Kind
为 Utc
或 Local
,请使用ToUniversalTime
: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);
}
ToUniversalTime
方法将把一个 Local
(或者 Unspecified
)的 DateTime
转换成 Utc
时间。
如果你不想在从 DateTime
到 Unix 时间戳进行转换时创建一个 epoch DateTime
实例,你也可以这样做:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
函数才能正常工作。你需要添加一个检查或者进行转换。(个人偏向于添加检查) - CodesInChaosAddMilliseconds
,并且应该使用 Double 而不是 Float。否则你会得到错误的时间。 - Axel你实际上想要添加毫秒数,而不是秒数。添加秒数会导致超出范围的异常。
AddMillis
,如果你从秒开始,显然你需要使用 AddSeconds
。 - jamesSampicavar EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
这里有详细的文档说明 DateTimeOffset.ToUnixTimeMilliseconds
要仅获取秒级别的EPOCH,您可以使用:
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
使用以下方法将Epoch
转换为DateTime
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
但由于 Unix 时间的表示方式在某些系统上是一个带符号的 32 位数字,该表示方式将在 2038 年 1 月 19 日 UTC 的 3:14:08 到达 231-1 秒后结束。这被称为 2038 年问题,即 32 位有符号 Unix 时间会溢出。
我建议将其保存为长整型而不是 int
,并命名为 EPOCH_2038_SAFE
long EPOCH_2038_SAFE =
(long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
如果您想要更多信息,可以使用以下内容以更高的精度。
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
.Ticks
,则从DateTime减法中可得到一个漂亮的TimeSpan实例。 - user2864740如果您想要更好的性能,您可以使用这个版本。
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)得出以下数字:
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内部工作的方式。
// 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);
}
应该使用ToUniversalTime()函数来处理DateTime对象。
目前,您可以直接使用
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
它将会被返回为一个64位长的值
我使用以下扩展方法进行时间戳转换
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);
}
从 .Net 4.6 版本开始,请使用
DateTimeOffset.Now.ToUnixTimeSeconds()