简体   繁体   中英

C# Convert from and back to Unix timestamp

I have following unit test which fails

[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
}

The new (actual) Unix timestamp is minus one hour. My machine timezone is UTC+1. Does it mean, that DateTimeOffset is automatically setting up my timezone (UTC+1) into the datetime and when converting back into the timestamp the DateTimeOffset is removing the UTC+1 so there is one hour decrease? How can I manage timezone in both ways?

The problem is in .DateTime fragment in the line

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

According to 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 creates for .DateTime property a new DateTime instance with Kind == DateTimeKind.Unspecified , so you lose timezone (now Offset from DateTimeOffset is just added to DateTime ).

In order to correct the test put .UtcDateTime instead of .DateTime :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM