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


当前回答

Unix epoch是自1970年1月1日午夜UTC时间减去闰秒所经过的秒数。这意味着在1970年1月1日午夜,Unix时间为0。Unix纪元也称为Unix时间、POSIX时间或Unix时间戳。

使用。net Framework 4.6或更高版本使用datetimeoffset . tounixtimemillisecseconds()方法,它返回从1970-01-01T00:00:00.000Z开始经过的毫秒数。

var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

DateTimeOffset在这里有很好的文档。ToUnixTimeMilliseconds

要获得纪元只有秒你可以使用

 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位数字的系统上,表示将在231 - 1秒后结束,即发生在2038 UTC时间1月19日3:14:08。这被称为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;

其他回答

我使用以下扩展方法进行epoch转换

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

Unix epoch是自1970年1月1日午夜UTC时间减去闰秒所经过的秒数。这意味着在1970年1月1日午夜,Unix时间为0。Unix纪元也称为Unix时间、POSIX时间或Unix时间戳。

使用。net Framework 4.6或更高版本使用datetimeoffset . tounixtimemillisecseconds()方法,它返回从1970-01-01T00:00:00.000Z开始经过的毫秒数。

var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

DateTimeOffset在这里有很好的文档。ToUnixTimeMilliseconds

要获得纪元只有秒你可以使用

 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位数字的系统上,表示将在231 - 1秒后结束,即发生在2038 UTC时间1月19日3:14:08。这被称为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;

感谢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返回一个带有Utc Kind的DateTime,这很好,但上面的ToUnixTime更可疑,因为它没有说明给定日期的DateTime是什么类型。要允许date的Kind为Utc或Local,请使用tuniversal time:

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将本地(或未指定)DateTime转换为Utc。

如果你不想在从DateTime移动到epoch时创建epoch DateTime实例,你也可以这样做:

public static long ToUnixTime(this DateTime date)
{
    return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}

如果您需要将包含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);
}