views:

64

answers:

3

I have a date I'm reading from an API in the following format:

2010-03-15T00:00:00-04:00

When assigned to a date datatype in C#/VB.net, it's displayed as:

3/14/2010 11:00:00 PM //Note 3/15 is being displayed as 3/14

why is this displayed as the previous day? Is there a name for the format above?

+3  A: 

The date that you have shown is in UTC whereas when you did the conversion, it adjusted the DateTime instance for the local time zone.

You should be able to call the ToUniversalTime method to get the date in UTC format.

If you need the time entered as a literal for your local time zone, then you need to create a new DateTime instance using the date data (year, month, day, etc, etc) or through a series of calls to the SpecifyKind method to indicate whether the DateTime instance is for the local time zone or UTC.

casperOne
Unless I'm missing something, if it's *only* a timezone issue, the time should be 8:00:00 PM
Randolpho
Ah, excellent. I suspected as much, but it caught me offguard that it's doing the conversion without me asking for it.
Cory House
@Randolpho: 8:00PM assumes that the local time is 4 hours behind UTC. In this case local time appears to be UTC+3 somewhere in eastern Europe.
Paul Alexander
@Randolpho: That's assuming that the current time zone is (currently) -8 UTC (because of daylight savings, this value can vary).
casperOne
Okay, I don't think I'm getting local time at all. I think is a timestamp that appears to be UTC but is actually EST, which is what I need. So I just need to specify that this is a timestamp I'd like to take as is. How do I simply assign this to a date datatype without .net manipulating it?
Cory House
A: 

Its a timezone issue. If you are using .NET 3.5, you can use the TimeZoneInfo class for working with timezones that may help. In previous versions of .NET, you will have to use TimeZone which is not as robust.

Cody C
+1  A: 

Couple issues here:

1) make sure to notice that the original string includes a timezone offset of -04:00, so it's not in UTC format. The UTC version of the same point in time would obviously be 2010-03-15T04:00:00Z (ending Z means UTC / Zulu). When you then displayed the DateTime, it shows the local timezone version - since your local timezone is EST (-5), then it displays 1 hour before what appears in the original string (which was offset @ -4), hence the 11:00pm

2) it sounds like your goal here isn't to show the local timezone nor UTC versions of the timestamp, but instead keep it at the same offset as what the input string had specified. Luckily 3.5 added a type just for this kind of scenario: DateTimeOffset

if you were to use DateTimeOffset instead of DateTime, the default ToString output would then be:

[342] C:\ » $dto = [datetimeoffset]::parse('2010-03-15T00:00:00-08:00')
[343] C:\ » $dto.ToString()
3/15/2010 12:00:00 AM -08:00
[344] C:\ » $dto.DateTime.ToString()
3/15/2010 12:00:00 AM

Notice that it keeps both the same time and knowledge of the offset (hence the name of the type). If you don't care about the offset and just want to get the DateTime for whatever offset the input was in, you can just fetch the DateTime property (as shown above). If you need to stick with a DateTime and can't or don't want to switch to DateTimeOffset, this may be the way to go.

James Manning