你如何在C#中转换纪元时间?

时间:2010-05-21 15:52:22

标签: c# time epoch

如何在C#中将Unix epoch time转换为实时? (Epoch开始于1970年1月1日)

14 个答案:

答案 0 :(得分:509)

我认为你的意思是Unix time,它被定义为1970年1月1日午夜(UTC)以来的秒数。

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

答案 1 :(得分:166)

latest version of .Net (v4.6)刚刚添加了对Unix时间转换的内置支持。这包括来自Unix时间和来自Unix或毫秒的时间。

  • Unix时间以秒为单位DateTimeOffset

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset以秒为单位的Unix时间:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • Unix时间(以毫秒为单位)DateTimeOffset

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset到Unix时间,以毫秒为单位:

long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();

注意:这些方法与DateTimeOffset进行转换。要获得DateTime表示,只需使用DateTimeOffset.DateTime属性:

DateTime dateTime = dateTimeOffset.UtcDateTime;

答案 2 :(得分:158)

归功于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返回DateTime Kind Utc,这很好,但上述ToUnixTime更令人怀疑的是,没有考虑给定DateTime的{​​{1}}类型。要允许date的{​​{1}}为dateKind,请使用ToUniversalTime

Utc

Local会将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); } (或ToUniversalTimeLocal转换为Unspecified

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

DateTime

答案 3 :(得分:22)

您实际上想要AddMilliseconds(毫秒),而不是秒。添加秒将使您超出范围异常。

答案 4 :(得分:8)

如果您想获得更好的性能,可以使用此版本。

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's version快2倍(如果是表演者)

这类似于DateTime内部工作方式。

答案 5 :(得分:7)

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

答案 6 :(得分:5)

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

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

    }

答案 7 :(得分:4)

当前您可以简单地使用

DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()

它将以64位长返回

答案 8 :(得分:1)

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

    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年加毫秒数。

答案 9 :(得分:0)

如果您需要将包含UNIX time的{​​{3}}(秒,微秒)转换为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);
}

答案 10 :(得分:0)

如果你没有使用4.6,这可能有助于来源: System.IdentityModel.Tokens

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

答案 11 :(得分:0)

使用方法 DateTimeOffset.ToUnixTimeMilliseconds(),它返回自1970-01-01T00:00:00.000Z以来经过的毫秒数。

  

只有Framework 4.6或更高版本支持此功能

var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

此处DateTimeOffset.ToUnixTimeMilliseconds

有据可查

答案 12 :(得分:0)

.Net 4.6及更高版本起,请使用DateTimeOffset.Now.ToUnixTimeSeconds()

答案 13 :(得分:-3)

这是我的解决方案:

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