如何将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个回答

11

.NET Framework 4.6新增了Unix时间转换功能。

现在你可以更轻松地将日期和时间值与.NET Framework类型以及Unix时间相互转换。例如,在JavaScript客户端和.NET服务器之间转换时间值时,这可能是必要的。以下API已添加到DateTimeOffset结构

static DateTimeOffset FromUnixTimeSeconds(long seconds)
static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds)
long DateTimeOffset.ToUnixTimeSeconds()
long DateTimeOffset.ToUnixTimeMilliseconds()

这不会给你本地时间,而是获取UTC时间。 - Berend de Boer
@BerenddeBoer 这是一个合理的默认值。之后您可以根据需要应用自定义偏移量。 - Deilan
1
@BerenddeBoer 这误解了Unix时间的含义。Unix时间是自1970年1月1日UTC午夜以来的秒数。无论你在哪里,自那个时刻起经过的秒数都不会改变。将其转换为人类可读的本地时间显示与这种通用表示分开,这是应该的。 - Tanktalus

9
var dt = DateTime.Now; 
var unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();

// 1510396991

var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);

// [11.11.2017 10:43:11 +00:00]


7
System.DateTimeOffset.Now.ToUnixTimeSeconds()

7
从 .NET 4.6 开始,您可以这样做:
var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).DateTime;

7

我写了一个最简单的扩展,可以为我们工作。如果有人需要它...

public static class DateTimeExtensions
{
    public static DateTime FromUnixTimeStampToDateTime(this string unixTimeStamp)
    {

        return DateTimeOffset.FromUnixTimeSeconds(long.Parse(unixTimeStamp)).UtcDateTime;
    }
}

6

我只需将转换与1970年1月1日不进行本地时间调整的转换进行比较,就可以找到正确答案。

DateTime date = new DateTime(2011, 4, 1, 12, 0, 0, 0);
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan span = (date - epoch);
double unixTime =span.TotalSeconds;

4
DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds);

当然,你可以把unixEpoch设置为全局静态变量,这样在你的项目中只需要出现一次,并且如果UNIX时间是以秒为单位的,可以使用AddSeconds函数。
要进行相反的操作:
double unixTimeInMilliseconds = timeToConvert.Subtract(unixEpoch).TotalMilliseconds;

根据需要截断为Int64和/或使用TotalSeconds


3

Unix tick指的是1秒(如果我没记错的话),而.NET tick指的是100纳秒。

如果您在使用纳秒时遇到问题,您可以尝试使用AddTick(10000000 * value)。


3
Unix是指自纪元开始(即1970年1月1日)到现在的秒数。 - ScottCher

2

使用.NET 6.0,并使用long来避免2038问题:

从DateTime.UtcNow到UnixTime

long seconds = (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;

seconds 将包含自 1970 年 01/01 起的秒数 (UnixTime)

从 UnixTime 转换为 DateTime.UtcNow

DateTime timestamp = DateTime.UnixEpoch.AddSeconds(seconds);

代码演示:https://dotnetfiddle.net/xNhO6q


1

我需要将包含秒和微秒的 timeval结构(UNIX时间)转换为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);
}

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