DateTime.Kind
In Version 2.0 of the .Net framework, Microsoft introduced the DateTime.Kind property. The different kinds are as follows:
Local
Unspecified
Utc
Every Date
(the underlying CLR type is DateTime
) object has the Kind
property, which specifies what kind of date that object is. That is, it specifies whether the date value is local, UTC, or unknown.
If a Date
object has Kind = Local
, then no conversion is performed when the ToLocalTime
function is called. From the DateTime.ToLocalTime method, emphasis is mine:
Kind Results (of ToLocalTime)
----------- -----------------------------------------
Utc This instance of DateTime is converted to local time.
Local No conversion is performed.
Unspecified This instance of DateTime is assumed to be a UTC time,
and the conversion is performed as if Kind were UTC.
How does this apply to your situation?
When you use CDate
, the resulting Kind
is Local
. This means that when you call ToLocal
on it, no conversion takes place:
Dim valor = "2013-10-26T19:33Z"
Dim dtUTC = CDate(valor)
' dtUTC.Kind is Local
' The following does not do any conversion
Dim dtLocal = dtUTC.ToLocal()
A more complete example
This example shows what happens when you use CDate
, and what happens when the Kind
is explicitly set. The first two code blocks are equivalent - CDate
creates a Local
date. The third block shows what happens when you specify a UTC date.
Sub Main()
Dim valor = "2013-10-26T19:33Z"
Dim dtUTC = CDate(valor)
Dim dtLocal = dtUTC.ToLocalTime()
Dim iHoraIn = Hour(dtLocal.AddHours(1))
Dim kind = dtUTC.Kind
printDate(dtUTC, dtLocal, iHoraIn, kind)
Dim dtUTC2 = DateTime.SpecifyKind(dtUTC, DateTimeKind.Local)
Dim dtLocal2 = dtUTC2.ToLocalTime()
Dim iHoraIn2 = Hour(dtLocal2.AddHours(1))
Dim kind2 = dtUTC2.Kind
printDate(dtUTC2, dtLocal2, iHoraIn2, kind2)
Dim dtUTC3 = DateTime.SpecifyKind(dtUTC, DateTimeKind.Utc)
Dim dtLocal3 = dtUTC3.ToLocalTime()
Dim iHoraIn3 = Hour(dtLocal3.AddHours(1))
Dim kind3 = dtUTC3.Kind
printDate(dtUTC3, dtLocal3, iHoraIn3, kind3)
End Sub
Sub printDate(ByVal dtUtc, ByVal dtLocal, ByVal hora, ByVal utcKind)
System.Console.WriteLine("UTC: {0}, UTC KIND: {1}, LOCAL: {2}, HORA: {3}", dtUtc, utcKind, dtLocal, hora)
End Sub
The above produces this output:
UTC: 2013-10-26 09:33:00 PM, UTC KIND: Local, LOCAL: 2013-10-26 09:33:00 PM, HORA: 22
UTC: 2013-10-26 09:33:00 PM, UTC KIND: Local, LOCAL: 2013-10-26 09:33:00 PM, HORA: 22
UTC: 2013-10-26 09:33:00 PM, UTC KIND: Utc, LOCAL: 2013-10-26 11:33:00 PM, HORA: 0
So what you are seeing is not a bug - it is expected behavior. You are trying to convert what you think is a UTC Date; however in reality it is really a local date.
I believe what you are expecting to see is what happens in the third code block above. It creates a UTC date and converts it to local time.