From yesterday (the first day of US day light saving adjustment had began.) the same code that runs on two different computers are giving different results. Here are the code:
DateTime t = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(
DateTime.UtcNow, r.timeZone);
While timezone used here is "US Eastern Standard Time"
Input (DateTime.UtcNow) is 2012/03/13 19:10:00
On a windows XP SP3 machine the code returns: 2012/03/13 14:10:00
On a windows server 2008 machine the same code returns: 2012/03/13 15:10:00
This is not expected. Any thoughts?
Best.
The current time zone on the XP machine is "US Eastern Standard Time" while the current time zone on the Server machine is "US Eastern Daylight Time". The US changed from Standard to Daylight time on Sunday. Perhaps the XP machine needs to have its time zone information updated.
Related
This question already has answers here:
TimeZoneInfo in .NET Core when hosting on unix (nginx)
(8 answers)
Closed 1 year ago.
I have deployed my asp.net core application in azure linux. I am trying to convert UTC time to 'Central Europe Standard Time'.
But, I am getting the following exception. In my local no issues, but I am getting issue after deployment.
The time zone ID 'Central Europe Standard Time' was not found on the
local computer. Could not find file '/usr/share/zoneinfo/Central
Europe Standard Time'.
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");
var cstTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, cstZone);
For the App Services that run on Linux, you should use Time Zone values from the IANA TZ database.
In your case Time Zone Central Europe Standard Time in linux could be Europe/Amsterdam
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
https://learn.microsoft.com/en-us/azure/app-service/faq-configuration-and-management#how-do-i-set-the-server-time-zone-for-my-web-app
Linux and Windows store timzones differently (see for example TimeZoneInfo in .NET Core when hosting on unix (nginx)).
One solution is to examine what is available and choose appropriately like shown at How to get TimeZoneInfo on Windows and Linux from www.ankursheel.com:
var nzTimeZone = TimeZoneInfo.GetSystemTimeZones().Any(x => x.Id == "New Zealand Standard Time")
? TimeZoneInfo.FindSystemTimeZoneById("New Zealand Standard Time")
: TimeZoneInfo.FindSystemTimeZoneById("Pacific/Auckland");
I have tried searching informations on net.core documentation (issue etc) without results.
The code is simpler:
[HttpGet()]
[Route("dob")]
public string dobTest()
{
var content = #"""1942-01-01T22:00:00.000Z""";
var settings = new JsonSerializerSettings()
{
//DateFormatHandling = DateFormatHandling.IsoDateFormat,
//DateParseHandling = DateParseHandling.DateTimeOffset,
DateTimeZoneHandling = DateTimeZoneHandling.Local,
//DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
};
var dob = JsonConvert.DeserializeObject<DateTime>(content, settings);
return $"dob: {dob.ToString("yyyy-MM-dd HH:mm:ss.fff")} - {dob.Kind}";
}
if I run this code on Mac or Linux the result is:
dob: 1942-01-02 00:00:00.000 - Local
if I run this code on windows the result is:
dob: 1942-01-01 23:00:00.000 - Local
My MacOs timezone is set on Rome(UTC +01:00)
Windows timezone is set on Rome(UTC +01:00)
the version of Newtonsoft.Json is 12.0.3
The version of net framework is net core 3.1
Linux and OSX both use the IANA time zone database for its primary source of time zone information, which has correct historical data for time zones in 1942 in Rome, under the identifier Europe/Rome. You can see that UTC+2 is the correct offset for the date given here as well.
Windows, on the other hand, does not have that history for this time zone. The equivalent Windows identifier is W. Europe Standard Time, which has an English display name of (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna. You can see the data Windows has in the registry under the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\W. Europe Standard Time
If you examine this key using RegEdit, you'll notice that unlike several other time zones, there is no Dynamic DST subkey for this zone. That means Windows is not aware of any historical differences in DST rules, and thus treats every year the under the same set of rules.
Windows does have historical data for some zones, but in general Microsoft only guarantees historical accuracy since 2010 per its DST/TZ support policy.
Thus, if you have the need in your application for historical time zone accuracy, then you should use IANA time zones only. In .NET, you can do this by using TZDB provider in the Noda Time library.
I have a transaction date stored in the database as DateTimeOffset UtcNow.
When I retrieve the date, I get something like the following
16/08/2020 9:12:34 PM +00:00
But I want to represent the time of transaction to represent the exact time in the timezone of UTC+1 which is where my client resides. But when I try to use the following code
TimeZoneInfo.ConvertTime(item.TransactionTime, TimeZoneInfo.FindSystemTimeZoneById("W. Central Africa Standard Time"));
I get the following error,
TimeZoneNotFoundException: The time zone ID 'UTC+1' was not found on the local computer.
I have also tried
TimeZoneInfo.ConvertTime(item.TransactionTime, TimeZoneInfo.FindSystemTimeZoneById("West Central Africa"));
Yet no luck.
What could I be getting wrong?
My application is on ASP.NET-Core 3.1 running on windows server.
Please help
TimeZoneInfo NaijaZone = TimeZoneInfo.FindSystemTimeZoneById("W. Central Africa Standard Time");
I got it working using the code up there, although it was writing that error above as well but I think whitespace affected the ID.
We currently are trying to implement time zone management in our application. Our server is in India. We will be saving all entries in server time. But when coming to the client side, we need to show the data in the client time. So I came into this conclusion that getting the client time zone from the front end and converting the server time to client time using the code below in the database will solve the problem.
DECLARE #ServerTime DATETIMEOFFSET(7) = '2015-02-21 22:06:08.6862774 +05:30' -- My server time
DECLARE #ClientTime DATETIMEOFFSET(7) = '2015-02-21 12:38:09.5421899 -04:00' -- My Client Time
SELECT SWITCHOFFSET(#ServerTime, DATEPART(TZ, #ClientTime))
My question is
Is there any better option?
Can this be done from the front end (C#)?
Last and most important question is:
How can I manage if the client machine is in daylight saving?
Any support will be appreciated.
You can do this in a much simpler way in .NET, since .NET has some "automatic" mechanisms to deal with this.
For example: if your client app invokes a web service and sends as argument a DateTime in local time (date.Kind == DateTimeKind.Local) the date is serialized with the offset ("2015-08-19T14:21+01:00") on the server side the date will be deserialized and converted to the server's local time. For instance, using the date above and if the server is in UTC the DateTime object would have the value "2015-08-19 13:21:00" (however you will not have any information about the timezone where the client is and where the date was created). If the date is sent again to the client the inverse conversion is made and the date will have the original value on the client.
This way the server will always process dates using local time and the client will always process dates in local time, although they do not know the timezone of each other.
I believe this mechanism does not deal well with ancient past dates because of daylight saving time, this is probably being limited by the information windows has about daylight saving time (as an example for the timezone "E. South America Standard Time" windows 8 only has DST information from 2006 to 2040 meaning that dates previous to 2006 could be misunderstood).
Having said that, I believe the best solution to deal with different timezones is to use UTC and convert to local time when displaying the date to the user, or always use DateTimeOffset instead of DateTime (DateTimeOffset also has information about the date timezone).
You can use:
SELECT CONVERT(datetime,'2019-03-11 11:59:59')
AT TIME ZONE 'UTC'
AT TIME ZONE 'US Eastern Standard Time';
It also handles daylight saving time.
While it is better to do this in client code, if you decide you need to work with time zones directly in SQL Server, you can now use my SQL Server Time Zone Support project.
Example:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')
I've developed an MVC 4 with C# application which I've deployed using Windows Azure to their datacenter in Virginia. I log user activity in my application recording both the username and the time that an activity was initiated. The time recorded needs to be converted to Fiji Standard Time. Based on what I have found online I wrote an extension method to help achieve this functionality.
public static DateTime ToFijiTime(this DateTime datetime)
{
datetime = DateTime.SpecifyKind(datetime, DateTimeKind.Utc);
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Fiji Standard Time");
DateTime MyDateTime = TimeZoneInfo.ConvertTime(datetime, tz);
return TimeZoneInfo.ConvertTimeToUtc(MyDateTime, tz);
}
However this doesn't really work well once it's deployed. I get the right date and almost the right time. For some reason it always gives the time as an "am" time. For example if the time should be 2/04/2013 6:30:19 PM (Fiji Standard Time)The time recorded is actually 2/04/2013 6:30:19 AM (Fiji Standard Time) but times that are in the morning like2/04/2013 1:30:19 AM are saved correctly. Can anyone please tell me what's wrong with my code?
Store the users timezone server side then,
Use following:
#TimeZoneInfo.ConvertTimeFromUtc(Model.CreatedOn, TimeZoneInfo.FindSystemTimeZoneById("E. US Standard Time"))
Also refer this :
Convert UTC/GMT time to local time