Home > Software engineering >  c# Convert DateTime from fixed timezone
c# Convert DateTime from fixed timezone

Time:05-27

I'm reading from external API dates like this:

2022-05-13 07:05:00

2022-05-13 13:00:00 ...

These dates are fixed in CET time. I want to convert them into UTC format like "yyyy-MM-ddTHH:mm:sszzz" so I can see UTC offset 02:00.

The problem is that I didn't find a way how to specify that my date is in CET timezone. Functions like ConvertTime, ConvertTimeToUtc doesn't work.

My code is:

    var time = new DateTime(2022,5,26,8,15,00, DateTimeKind.Unspecified);    // 2022-05-26 8:15:00 CET
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
    DateTime cet = TimeZoneInfo.ConvertTime(time, tz); // non sense, as no timezone info in time...
    var str = cet.ToString("yyyy-MM-ddTHH:mm:sszzz");

How to resolve this?

CodePudding user response:

You can manually set the hours back using:

// Currently CET is ahead of UTC by 2 hours
time = time.AddHours(-2);

And then you can format the date time object without worrying about the time zones.

edit: adding daylight saving.

First you have to check whether you are in the time where daylight saving is in effect or not.

To do this first get the datetime, then check if it is in the daylight saving period. Daylight saving goes into effect at the last sunday of march and is cancelled at the last sunday of october

currentTime = DateTime.Now();
string currentMonth = currentTime.ToString("MM");
string currentDay = currentTime.ToString("DD");

// Daylight saving is in effect
if ( currentMonth > '3' && currentMonth < '10' ) {
    time = time.AddHours(-2);
}

// Daylight saving is not in effect
else if ( currentMonth < '3' || currentMonth > '10' ) {
    time = time.AddHours(-1);
}

    // If it is march or october
else if(currentMonth == '3' || currentMonth == '10')
{

    // Find the last sunday
    var lastSunday = new DateTime(currentTime.Year,currentTime.Month,1);
    lastSunday = lastSunday.AddMonths(1).AddDays(-1);
    while (lastSunday.DayOfWeek != DayOfWeek.Sunday)
    {
        lastSunday = lastSunday.AddDays(-1);
    }
    string sunday = lastSunday.ToString("DD");

     // If it is march, check to see if the day is after or before last sunday
     if(currentMonth == '3'){ 
         if( currentDay > sunday )
         {
             // Daylight saving is in effect
             time = time.AddHours(-2);
         }
         else
         {
             // It is not in effect
             time = time.AddHours(-1);
         }
     }
     // If it is october, check to see if the day is after last sunday or not
     else if(currentMonth == '10'){
         if( currentDay > sunday )
         {
             // Daylight saving is not in effect
             time = time.AddHours(-1);
         }
         else
         {
             // It is in effect
             time = time.AddHours(-2);
         }
     }

}

CodePudding user response:

There is a cleaner way of doing it:

public static DateTime ParseCET(string dt)
{
    var cet = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
    var localTime = DateTime.Parse(dt);
    return TimeZoneInfo.ConvertTimeToUtc(localTime, cet);
}

The output is consistent and correct, always respecting daylight saving time period:

// winter time - prints "2/1/2022 11:00:00 AM"
Console.WriteLine(ParseCET("2022-02-01 12:00:00").ToString());

// summer time - prints "8/1/2022 10:00:00 AM"
Console.WriteLine(ParseCET("2022-08-01 12:00:00").ToString());
  • Related