Home > Blockchain >  C# DateTime does not contain TimeZone yet it somehows know in which way it has been initialized. How
C# DateTime does not contain TimeZone yet it somehows know in which way it has been initialized. How

Time:12-17

I am reading https://stackoverflow.com/a/6519330/1375882 and I understand that DateTime does not contain timezone. Indeed, there are no TimeZone member fields for DateTime. Yet there are ToLocalTime() and ToUniversalTime() members. E.g. I am testing my code in 2 timezone computer and it gives the trace (e.g. now it is 16.12.2021 16:17:23 in 2 timezone) and the code gives:

DateTime tmpNow = DateTime.UtcNow;

//16.12.2021 14:17:23 - this if fine, DateTime is UTC
tmp = tmpNow.ToString();

//16.12.2021 16:17:23
tmp = tmpNow.ToLocalTime().ToString(); 

//16.12.2021 14:17:23 - this is fine, DateTime is UTC
tmp = tmpNow.ToUniversalTime().ToString(); 

DateTime tmpCustom = new DateTime(2021, 12, 16, 16, 9, 10);

//16.12.2021 16:09:10 - this is strange, I assume that DateTime(...) is aware that it is
// executed in  2 and that 16:09:10 is in  2 and therefore ToString should be 14:09:10
tmp = tmpCustom.ToString(); 

 //16.12.2021 18:09:10 - this is strange, see previous
tmp = tmpCustom.ToLocalTime().ToString();

//16.12.2021 14:09:10 - complete loss of understanding. If initialization has been to 14:09:10 UTC 
// as I expected, then ToLocalTime.ToString had to bee 16:09:10, but ToLocalTime()... was 18:09:10
// hence ToUniversalTime() definitely had to be 2 hours before - 16:09:10.
tmp = tmpCustom.ToUniversalTime().ToString();

So, this is realy strange - the DateTime senses somehow whether it has been initialized with UTC or with simple combination of date-time-numbers. How to explain the DateTime code behavior and this depnedence on hidden timezone?

CodePudding user response:

All of this is in the docs, you just need to know where to look. Relevant here is the Kind property. It's an enum: Local, Utc or Unspecified.

When Local, it assumes the timezone of the current culture. See the docs for the constructor you use:

The Kind property is initialized to DateTimeKind.Unspecified.

Then head over to ToUniversalTime():

the value returned by the ToUniversalTime method is determined by the Kind property of the current DateTime object

[...]

Unspecified: The current DateTime object is assumed to be a local time, and the conversion is performed as if Kind were Local.

So if you change your code to new DateTime(2021, 12, 16, 16, 9, 10, DateTimeKind.Local), the methods thereafter will work as expected - apart from your comment claiming you expect "14:09" there. That won't happen.

  • Related