Reputation: 6778
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?
Upvotes: 4
Views: 3770
Reputation: 186688
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;
Upvotes: 2