Reputation: 25
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?
Upvotes: 1
Views: 2372
Reputation: 1974
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());
Edge cases:
2022-03-27 02:30:00 CET
.In this case according to the documentation and exception is thrown:
If dateTime corresponds to an invalid time, this method throws an ArgumentException.
2022-10-30 02:30:00 CET
could logically translate to either of 00:30:00 UTC or 01:30:00 UTC.In this case according to the documentation standard (winter) time is assumed:
If dateTime corresponds to an ambiguous time, this method assumes that it is the standard time of the source time zone.
Upvotes: 2
Reputation: 350
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);
}
}
}
Upvotes: 0