首页 文章

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

提问于
浏览
307

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

10 回答

  • -3

    我认为你的意思是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);
    
  • 19

    有了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 UtcDateTime ,这很好,但上面的 ToUnixTime 更令人怀疑,因为它没有考虑给定的 date 是什么类型的 DateTime . 要允许 dateKindUtcLocal ,请使用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 (或 UnspecifiedDateTime 转换为 Utc .

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

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

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

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

  • 0
    // 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对象 .

  • 5

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

    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内部工作方式类似 .

  • 150

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

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

    如果您需要将包含 UNIX timetimeval struct(秒,微秒)转换为 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);
    }
    
  • 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;
        }
    
  • 7

    这是我的解决方案:

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

相关问题