Search code examples
c#datetimetimezoneutctimezone-offset

C# DateTime - converting a DateTimeOffset to another TimeZone


When converting a DateTimeOffset to another TimeZone, the OffSet is incorrect.

I've read many articles and experimented for too many hours, but can't see what I'm missing here:

// It's June in the UK and we're in British Summer Time, which is 1 hour ahead of UTC (GMT)
var UKoffsetUtc = new TimeSpan(1, 0, 0);

// It's 4pm - declare local time as a DateTimeOffset
var UKdateTimeOffset = new DateTimeOffset(2020, 6, 17, 16, 0, 0, UKoffsetUtc);

// Convert to UTC as a date
var utc = DateTime.SpecifyKind(UKdateTimeOffset.UtcDateTime, DateTimeKind.Utc);

// Get Aus TimeZoneInfo
var AUSTimeZone = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");

// Check the Aus offset from UTC
var AUSOffset = AUSTimeZone.GetUtcOffset(utc);
Console.WriteLine(AUSOffset); // Output is 10 as expected

// Declare Aus Time as DateTimeOffset
var AUSDateTimeOffset = TimeZoneInfo.ConvertTimeFromUtc(utc, AUSTimeZone);

// The Aus Offset from UTC is not correct 
Console.WriteLine(AUSDateTimeOffset.ToString("dd MM yyyy HH:mm zzz"));

The output is 18 06 2020 01:00 +01:00

Aus are 10 hours ahead of UTC (9 hours ahead of GMT) so the date and time are correct, but not the offset.

How can I get the correct offset in AUSDateTimeOffset?


Solution

  • You can create new offset and use it -

        // Create new offset for UTC
        var AUSOffset = new DateTimeOffset(utc, TimeSpan.Zero);
    
        // Declare Aus Time as DateTimeOffset
        var AUSDateTimeOffset = UKdateTimeOffset.ToOffset(AUSTimeZone.GetUtcOffset(AUSOffset));                              
        Console.WriteLine(AUSDateTimeOffset.ToString("dd MM yyyy HH:mm zzz"));
    

    Or:

    Use ConvertTimeBySystemTimeZoneId as suggested by Jimi in the comment!

        var finalDate = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(UKdateTimeOffset, "AUS Eastern Standard Time");
        Console.WriteLine(finalDate.ToString("dd MM yyyy HH:mm zzz"));