C# 与 Unix 时间戳相互转换

C# Convert from and back to Unix timestamp

我有以下单元测试失败了

[Fact]
public void Convert_to_and_from_unix_timestamp()
{
    // Arrange
    var timestamp = 1636579063;
    var date = DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;

    // Act
    var unixTimeSeconds = ((DateTimeOffset)date).ToUnixTimeSeconds();

    // Assert
    Assert.Equal(expected: timestamp, actual: unixTimeSeconds);

    // result
    // Expected: 1636579063 // 10/11/2021 21:17:43
    // Actual: 1636575463 // 10/11/2021 20:17:43
}

新的(实际的)Unix 时间戳是负一小时。我的机器时区是 UTC+1。这是否意味着 DateTimeOffset 会自动将我的时区 (UTC+1) 设置为日期时间,并且在转换回时间戳时 DateTimeOffset 正在删除 UTC+1,因此减少了一个小时?如何以两种方式管理时区?

问题出在.DateTime行中的片段

    var date = DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;

根据reference source

private DateTime ClockDateTime {
  get {
    // Here we lose Timezone (Offset) - it just added to m_dateTime
    // Kind is Unspecified, that's why we can restore the fact
    // Offset == 0 and we actually have UTC datetime    
    return new DateTime((m_dateTime + Offset).Ticks, DateTimeKind.Unspecified);
  }
}
 
public DateTime DateTime {
  get {
    return ClockDateTime;
  }
}

.Net 为 .DateTime 属性 创建一个带有 Kind == DateTimeKind.Unspecified 的新 DateTime 实例,因此您丢失了时区(现在 Offset 来自 DateTimeOffset 只是 添加 DateTime).

为了更正测试用 .UtcDateTime 而不是 .DateTime:

    var date = DateTimeOffset.FromUnixTimeSeconds(timestamp).UtcDateTime;