如何将Unix时间戳转换为日期时间格式,反之亦然?

976

这里有一个示例代码,但是接下来它开始谈论毫秒/纳秒的问题。

相同的问题出现在MSDN上,C#中自Unix时代以来的秒数

到目前为止,我得到了以下内容:

public Double CreatedEpoch
{
  get
  {
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
    TimeSpan span = (this.Created.ToLocalTime() - epoch);
    return span.TotalSeconds;
  }
  set
  {
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
    this.Created = epoch.AddSeconds(value);
  }
}

174
即将发布的 .NET 4.6(计划在今年晚些时候发布)将引入对此的支持。请参阅 DateTimeOffset.FromUnixTimeSecondsDateTimeOffset.ToUnixTimeSeconds 方法。还有毫秒级 Unix 时间的方法。 - Jeppe Stig Nielsen
7
另一个新增加的内容是DateTime.UnixEpoch。除非你需要使用DateTimeOffset而不是DateTime,否则我认为DateTime.UnixEpoch.AddMilliseconds(...)DateTimeOffset.FromUnixTimeMilliseconds(...).UtcDateTime更易读。 - M-Pixel
24个回答

0
public static class UnixTime
    {
        private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);

        public static DateTime UnixTimeToDateTime(double unixTimeStamp)
        {
            return Epoch.AddSeconds(unixTimeStamp).ToUniversalTime();
        }
    }

你可以调用UnixTime.UnixTimeToDateTime(double datetime))函数


0
在.NET中,有一个叫做DateTimeOffset的类,其已经有了一个名为FromUnixTimeMilliseconds的方法,它可以实现您要查找的功能。该方法接受自1970年01月01日T00:00:00Z(1970年1月1日12:00 AM UTC)以来已经流逝的以毫秒为单位的Unix时间。
要使用此方法,请首先将毫秒转换为DateTimeOffset:
long millisecs = 1677514053797;  // replace this with the Unix time you need to convert
DateTimeOffset unixTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(millisecs);

注意:偏移量具有Offset属性,该属性将设置为TimeSpan.Zero,表示UTC,它不是时区调整的。
接下来从偏移量创建一个DateTime实例:
DateTime dt = new DateTime(unixTimeOffset.Ticks, DateTimeKind.Utc);

将其从DateTime转换回Unix毫秒时间:

DateTimeOffset backToUnixTimeOffset = new DateTimeOffset(dt, TimeSpan.Zero);
long backToMillisecs = backToUnixTimeOffset.ToUnixTimeMilliseconds();

这里是它的文档:https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.fromunixtimemilliseconds?view=net-7.0https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tounixtimemilliseconds?view=net-7.0#system-datetimeoffset-tounixtimemilliseconds

希望这能帮到你。


0
使用NET 8
您还有另一种选择,可以使用新的TimeProvider类来获取时间戳。
 var timestamp = TimeProvider.System.GetUtcNow().ToUnixTimeSeconds();

-2

针对 .NET 4.6 及更高版本:

public static class UnixDateTime
{
    public static DateTimeOffset FromUnixTimeSeconds(long seconds)
    {
        if (seconds < -62135596800L || seconds > 253402300799L)
            throw new ArgumentOutOfRangeException("seconds", seconds, "");

        return new DateTimeOffset(seconds * 10000000L + 621355968000000000L, TimeSpan.Zero);
    }

    public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds)
    {
        if (milliseconds < -62135596800000L || milliseconds > 253402300799999L)
            throw new ArgumentOutOfRangeException("milliseconds", milliseconds, "");

        return new DateTimeOffset(milliseconds * 10000L + 621355968000000000L, TimeSpan.Zero);
    }

    public static long ToUnixTimeSeconds(this DateTimeOffset utcDateTime)
    {
        return utcDateTime.Ticks / 10000000L - 62135596800L;
    }

    public static long ToUnixTimeMilliseconds(this DateTimeOffset utcDateTime)
    {
        return utcDateTime.Ticks / 10000L - 62135596800000L;
    }

    [Test]
    public void UnixSeconds()
    {
        DateTime utcNow = DateTime.UtcNow;
        DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow);

        long unixTimestampInSeconds = utcNowOffset.ToUnixTimeSeconds();

        DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeSeconds(unixTimestampInSeconds);

        Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year);
        Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month);
        Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date);
        Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour);
        Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute);
        Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second);
    }

    [Test]
    public void UnixMilliseconds()
    {
        DateTime utcNow = DateTime.UtcNow;
        DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow);

        long unixTimestampInMilliseconds = utcNowOffset.ToUnixTimeMilliseconds();

        DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeMilliseconds(unixTimestampInMilliseconds);

        Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year);
        Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month);
        Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date);
        Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour);
        Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute);
        Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second);
        Assert.AreEqual(utcNowOffset.Millisecond, utcNowOffsetTest.Millisecond);
    }
}

4
我不理解。在.NET 4.6中,基础类库已经包含了这些方法(例如,请看我对上面问题的评论,或者其他一些新答案(2015年)。那么再次编写它们的意义是什么?你的回答是否指针对于4.6之前的版本的解决方案? - Jeppe Stig Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接