Izacch
Izacch

Reputation: 483

Parse String into DateTimeOffset While Assuming TimeZone

Probably a super simple solution but I'm clearly missing something.

I have a string object with value "2020/07/29 13:30:00".

How can I parse that into a DateTimeOffset object and make the assumption that the time zone of that parsed time is "GMT Standard Time" for example, or any TimeZoneInfo I wish to specify preferably?

How can I then take that DateTimeOffset, and return its Utc time but to any specified time zone of my choice?

Many thanks

Upvotes: 5

Views: 4747

Answers (3)

canton7
canton7

Reputation: 42225

The easiest I could find is something like this.

I couldn't find any methods to parse a DateTimeOffset in a particular given timezone, but you can parse your string as a DateTime (with a Kind of Unspecified, which just acts as a container for the bits of information in the string, without trying to apply timezone knowledge to it).

Then you can ask a TimeZoneInfo for the UTC offset in a given timezone at the given local time, and apply this to the DateTime to create a DateTimeOffset.

Once you've got your DateTimeOffset, you can work with it using its ToOffset method, and TimeZoneInfo.ConvertTime.

string input = "2020/07/29 13:30:00";
var timezone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");

// DateTime.Parse creates a DateTime with Kind == Unspecified
var dateTime = DateTime.Parse(input);
Console.WriteLine(dateTime); // 7/29/2020 1:30:00 PM

// Since Kind == Unspecified, timezone.GetUtcOffset will give us the UTC offset in effect at
// the given local time in timezone
var dateTimeOffset = new DateTimeOffset(dateTime, timezone.GetUtcOffset(dateTime));
Console.WriteLine(dateTimeOffset); // 7/29/2020 1:30:00 PM +01:00

// Convert to UTC
Console.WriteLine(dateTimeOffset.UtcDateTime); // 7/29/2020 12:30:00 PM
Console.WriteLine(dateTimeOffset.ToOffset(TimeSpan.Zero)); // 7/29/2020 12:30:00 PM +00:00

// Convert to another timezone
var cst = TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time");
Console.WriteLine(TimeZoneInfo.ConvertTime(dateTimeOffset, cst)); // 7/29/2020 6:30:00 AM -06:00

Upvotes: 7

D A
D A

Reputation: 2054

This function should convert your date time string (with assumption this is GMT Standard Time) to any other timezone:

    public static DateTime? ToUTCTimeZone(string sDate, string timeZone)
    {

        DateTime utcDate = DateTime.Parse(sDate);

        DateTimeOffset localServerTime = DateTimeOffset.Now;
        utcDate = DateTime.SpecifyKind(utcDate, DateTimeKind.Utc);

        TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
        if (cstZone == null)
            return null;

        return TimeZoneInfo.ConvertTimeFromUtc(utcDate, cstZone);

    }//ToUTCTimeZone

Upvotes: 0

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131180

Try the DateTimeOffset.ParseExact overload that accepts a DateTimeStyles parameter.

This code:

var dt=DateTimeOffset.ParseExact("2020/07/29 13:30:00","yyyy/MM/dd HH:mm:ss",
                     CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal);

Returns 2020-07-29T13:30:00.0000000+00:00

There's no GMT Standard Time, that's a very unfortunate name used in Windows that somehow manages to mix up British and UTC time to the point that no-one knows what it means without looking at the docs. This was thoroughly discussed and explained in this question: Difference between UTC and GMT Standard Time in .NET. As one of the answers explains :

The names GMT Standard Time and GMT Daylight Time are unknown outside of Redmond. They are mythical animals that appear only in the bestiary called the Windows Registry.

If you wanted to assume British time and your machine uses a British timezone, you can use DateTimeStyles.AssumeLocal

Upvotes: 1

Related Questions