如何在c#中将Unix纪元时间转换为实时时间?(新纪元开始于1970年1月1日)


当前回答

// 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()。

其他回答

不要担心使用毫秒或秒,只需执行以下操作:

    public static DateTime _ToDateTime(this long unixEpochTime)
    {
        DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        var date = epoch.AddMilliseconds(unixEpochTime);

        if (date.Year > 1972)
            return date;

        return epoch.AddSeconds(unixEpochTime);
    }

如果纪元时间以秒为单位,那么1972年就不可能增加毫秒。

更新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);
}

如果你想要更好的性能,你可以使用这个版本。

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);
}

应该对DateTime对象使用ToUniversalTime()。

如果您需要将包含UNIX时间的timeval结构体(秒,微秒)转换为DateTime而不损失精度,如下所示:

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);
}