Reputation: 23
I am trying to convert a DateTime into UTC from a source timezone. Date, time and timezone are taken as inputs from a user (presented as dropdown menu options).
Following is a portion of the code utilized for conversion:
string inputDateString = "2019-11-12T09:00:00.000"; //Taken as input from user
string inputTimeZoneString = "(UTC-03:00) Brasilia"; // Taken as input from user
DateTime dtStartdatetime = DateTime.Parse(inputDateString);
string sourceTimeZone = string.Empty;
foreach (TimeZoneInfo a in TimeZoneInfo.GetSystemTimeZones())
{
if (a.DisplayName == objCalendar.timezone)
{
sourceTimeZone = a.Id;
}
string strTimeZone = a.DisplayName.Substring(a.DisplayName.IndexOf(')') + 1);
string strTimeZone1 = objCalendar.timezone.Substring(objCalendar.timezone.IndexOf(')') + 1);
if (strTimeZone.Trim() == strTimeZone1.Trim())
{
sourceTimeZone = a.Id;
}
}
DateTime utc_time_start = TimeZoneInfo.ConvertTimeToUtc(dtStartdatetime, TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZone));
Console.WriteLine(utc_time_start.ToString("yyyyMMddTHHmmssZ"));
The problem is that this piece of code gives 20191112T120000Z as output when run on Dev system (based in IST timezone) whereas same code results in 20191112T110000Z as output when run on server (based in EST). Is this behavior due to difference in timezone of the systems on which it is being run? What is could be a possible solution for this situation? A particular time from a particular timezone should result in same UTC time irrespective of the machine where the code executes.
Upvotes: 0
Views: 823
Reputation: 241420
The time zone that your server is running in does not impact this code.
The difference is due to the end of DST for Brazil in 2019.
Windows released an update in July 2019 to cover this scenario. Specifically, this change is addressed by KB4507704 and Windows 10 Build 17763.652. Your dev environment has this update, the server does not. You should ensure your server is receiving Windows Updates. If it's missing this (5 months after release), it's probably missing more critical security updates as well.
Additionally, I strongly discourage matching time zone by display name for a few reasons:
The display names are localized by the primary language of the operating system, so they will be different, for example, on a server set for English than on a server set for Portuguese. (The globalization and localization settings in .NET are not used for this.)
The display names are potentially volatile. That is, if there is a reason to change the display name in a future update, the string will change from what you previously had used.
Instead, pass the Id
of the time zone as an input to TimeZoneInfo.FindSystemTimeZoneById
, and skip the matching bit in the middle entirely.
Upvotes: 1
Reputation: 668
You are not leaving your loop after you found a source time zone.
In your second part you search for a partial string of the time zone. Most probably this part finds a second time zone on your server. This can happen if the OS or .net versions differ.
Try:
string inputDateString = "2019-11-12T09:00:00.000"; //Taken as input from user
string inputTimeZoneString = "(UTC-03:00) Brasilia"; // Taken as input from user
var dtStartdatetime = DateTime.Parse(inputDateString);
string sourceTimeZone = string.Empty;
foreach (TimeZoneInfo a in TimeZoneInfo.GetSystemTimeZones())
{
if (a.DisplayName == inputTimeZoneString)
{
sourceTimeZone = a.Id;
break;
}
string strTimeZone = a.DisplayName.Substring(a.DisplayName.IndexOf(')') + 1);
string strTimeZone1 = inputTimeZoneString.Substring(inputTimeZoneString.IndexOf(')') + 1);
if (strTimeZone.Trim() == strTimeZone1.Trim())
{
sourceTimeZone = a.Id;
break;
}
}
DateTime utc_time_start = TimeZoneInfo.ConvertTimeToUtc(dtStartdatetime, TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZone));
Console.WriteLine(utc_time_start.ToString("yyyyMMddTHHmmssZ"));
Upvotes: 0