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.