views:

132

answers:

6

Hello, I am trying to convert a string of this format:

MM/dd/yyyy HH:mm

The input is from a US database, so, i.e.: 09/20/2010 14:30

I know that my string is always US time but when I display it, I need to translate that into the local time, so that string should be turned into:

09/20/2010 19:30 (for UK for instance)

I tried a few things but nothing seems to give me the correct solution when I run on a US machine vs a UK or Ge machine I tried:

CompletedDttm = DateTime.ParseExact(value, "MM/dd/yyyy HH:mm", CultureInfo.CurrentCulture);
CompletedDttm = DateTime.ParseExact(value, "MM/dd/yyyy HH:mm", new CultureInfo("en-US"));

They all work locally (US machine) but they don't convert the time to local time on a European machine.

Thanks Tony

+4  A: 

UPDATE: You have to know the timezone of the data (not just that it is "US") as well as the interpreting machine if you want to reliably convert it to anything else. You're not only looking at hours offset, but DST also which varies by location (not all locales abide by it). Eastern is either -4 or -5 depending on the time of year. And if the date is old enough you run into the issue that "summer" dates were changed recently.

Your best course is to ALWAYS store timestamps in UTC. Aside from that, you can just make guesses about the offset.


You should be working with UTC times (the new, slightly different, version of GMT) if you want to be converting to other time zones.

DateTime dt = new DateTime(DateTime.Parse('2010-10-06 19:40').Ticks, DateTimeKind.Local);
dt.AddHours(5);
dt.ToLocalTime();

You could also make use of TimeZoneInfo which will have DST information also.

Brad
The time I am getting comes from a US database. Are you saying to convert to GMT first and then to local?
tony
The example you gave assumes he has the date in his local time...which he doesn't.
jvenema
He is not exactly giving a lot of information to work with so I think this is the best answer he can expect.
Adkins
A: 

You could use string.Split. first with the '/' separator on the whole string. You will get "09" "20" and "2010 14:30" then apply the split 2 more times with ' ' and ':'

Catalin Florea
+3  A: 

Unless you specify otherwise, the parse will assume you mean to parse the string into your current timezone. US culture just means the expected format of the string, and has nothing to do with the timezone (for example, in the US it could be EST or it could be PST).

Your string contains no timezone information, so naturally you're going to get your value in whatever the local timezone is. You can either:

  1. Add the timezone info
  2. Change the timezone afterwards
jvenema
A: 

I think it's a display problem, but need more info to be sure. Try displaying the dates in yyyy-MM-dd format in both cases to check if the problem is on parse or display. You can create a custom format info object if you know exactly what you want to accept or display:

    public static DateTimeFormatInfo GetISOFormatInfo()
    {
        DateTimeFormatInfo dtFormat = new DateTimeFormatInfo();
        dtFormat.DateSeparator = "-";
        dtFormat.TimeSeparator = ":";
        dtFormat.ShortDatePattern = "yyyy-MM-dd";
        dtFormat.ShortTimePattern = "HH:mm:ss";
        return dtFormat;
    }
Kendrick
A: 

Using a Date without TimeZone information, you will not be able to know the UK time / Canada time etc... since you do not know who (which part of the world) instered that time. Since you specifically said that the time is US time, you can add the time difference for the different parts of the world to display the local time.

Vivek
+1  A: 

Try this - it converts local time (input in US format) to GMT and then prints in GB/DE format.

var zones = TimeZoneInfo.GetSystemTimeZones();    // retrieve timezone info
string value = "09/20/2010 14:30";

DateTime CompletedDttm = DateTime.ParseExact(value, "MM/dd/yyyy HH:mm",    
    new CultureInfo("en-US"));
DateTime FinalDttm = TimeZoneInfo.ConvertTime(CompletedDttm, 
    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"), 
    TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"));
string output = FinalDttm.ToString(new CultureInfo("en-GB"));

FinalDttm = TimeZoneInfo.ConvertTime(CompletedDttm, TimeZoneInfo.Local, 
    TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time"));
output = FinalDttm.ToString(new CultureInfo("de-DE"));

Output is, in turn:

20/09/2010 19:30:00

20.09.2010 20:30:00

Steve Townsend
That would work if I know I am in UK, how do I know where I am? In other words how to I query for the local Culture?
tony
@tony - if your times are correct for US timezone then you pass US culture to the ParseExact call. Code above assumes it's running on a box in the US. Sorry but I am in the US so hard to test for your non-US case. I think other comments re missing information in the date/time as stored are correct, by the way. If you cannot change the DB, this is more work to get all cases working properly.
Steve Townsend
I've changed the logic to assume input is EST not Local in the conversion. Still not 100% reliable I would think, and requires new target timezones to be handled as required.
Steve Townsend