How is local determined in ToLocalTime() - c#

When using ToLocalTime(), how is local time determined? Is local time from the server or the client? My assumption would be the server running the application.

It is the local time zone of the computer that code is running on. In an ASP.Net application, the code runs on the server - so that's the time zone that it will return.
The behavior of this function is actually dependent on the .Kind property of the source value. From the MSDN link you gave:
Utc - This instance of DateTime is converted to local time.
Local - No conversion is performed.
Unspecified -This instance of DateTime is assumed to be a UTC time, and the conversion is performed as if Kind were Utc.
This is non-obvious behavior. You can read other related problems with the .net DateTime class here and here.
A few other points:
If you follow best practices, you will set the server's time zone to UTC.
If you are trying to display time in the user's timezone, you'll have to use one of these strategies.

ToLocalTime(), in this case, executes on the server. Therefore the time is evaluated on the server, and it'll return the server time to the client.

It is the local time on the server.

Local here is the timezone of the machine that the function executes on.

Related

C# Datetime is increasing by 3 hours

My dates are being stored in sql server.
Windows server region and timezone are correct, but when I see the date in database it's increased by 3 hours, I think it is comming from some server configuration that is overriding, but don't know where else to look.
When I send date from local project to production database, it saves correctly, but when I use production website it doesn't.
Where else should I check to solve this?
It depends on the codebase running your production portal.
Use Datetime as utc and cater for it accordingly. Or add DatetimeOffset and calculate the difference when needed.
If you still have the luxury of refactoring, I advise you to take a little dive into the Dates and time handling, get a solid understanding of it, then code accordingly, so it doesn't fire back on you in later stages or usages.
The problem was in some machines of the load balance, there are several machines created from an image, the original was right but the copies were not, if I tried many times to save the registry, then I happened to be redirected to the machine with the correct configuration and then the record was saved with the correct date.
I just asked devops to correct the settings on the other machines.
If you want to get advantage of your local machine timezone you can use myDateTime.ToUniversalTime() to get the UTC time from your local time or myDateTime.ToLocalTime() to convert the UTC time to the local machine's time.
// convert UTC time from the database to the machine's time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var localTime = databaseUtcTime.ToLocalTime();
// convert local time to UTC for database save
var databaseUtcTime = localTime.ToUniversalTime();
If you need to convert time from/to other timezones, you may use TimeZoneInfo.ConvertTime() or TimeZoneInfo.ConvertTimeFromUtc().
// convert UTC time from the database to japanese time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var japaneseTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
var japaneseTime = TimeZoneInfo.ConvertTimeFromUtc(databaseUtcTime, japaneseTimeZone);
// convert japanese time to UTC for database save
var databaseUtcTime = TimeZoneInfo.ConvertTimeToUtc(japaneseTime, japaneseTimeZone);

Azure web app timezone error in asp.net webapi

I have web app in azure paas environment. I need to convert the time in different timezone, i have following code which run perfectly fine on dev machine but when i deploy on azure paas environment it throw error
TimeZoneInfo serverTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(TimeZone.CurrentTimeZone.StandardName);
return TimeZoneInfo.ConvertTimeToUtc(_lastUpdatedDate.Value, serverTimeZoneInfo);
First line throw exception. Error getting value from 'DateCreated' on 'ViewModels.Orders.OrderActivityViewModel'
A few things:
Don't use the TimeZone class. It is obsolete. Use only the TimeZoneInfo class.
The StandardName is NOT the same as the Id for all cases. It is also impacted by OS language, where the Id is not.
The local time zone's Id is at TimeZoneInfo.Local.Id, though there's no point in finding it by Id when you already have it. You'd just use TimeZoneInfo.Local.
If you're just converting local time to UTC, you don't need to mess with time zones at all, just use .ToUniversalTime() on your original DateTime or DateTimeOffset value.
The server's time zone probably already is UTC. That is the default in Azure anyway. Thus it isn't going to do anything at all.
If necessary, you can change Azure App Service's WEBSITE_TIME_ZONE setting (on Windows only), but I don't recommend that. If you have a specific time zone in mind, then you would pass that ID into TimeZoneInfo.FindSystemTimeZoneById.
As others pointed out, the error you reported isn't in the code you gave, so likely none of this is going to help you.

Managing Time zone and Daylight Saving in SQL Server

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')

How to log the real user time?

I am logging which users login to the app and times. I see the time is based on the app server which is this case Azure, so it's not the real time. I was interested to show the real times they login. It seems the app server is the default, how to make this time more legitimate?
var loginAudit = new LogInAudit();
loginAudit.CLIENT_IP = FDB.Utils.GetClientIP();
loginAudit.LOGIN_TIME = DateTime.Now;
loginAudit.LOGIN_USER_ID = objUser.LoginID;
loginAudit.LOGOUT_TIME = null;
loginAudit.TYPE = "IN";
loginAudit.USER_ID = objUser.UserID;
db.Entry(loginAudit).State = System.Data.Entity.EntityState.Added;
db.SaveChanges();
Showing dates relative to a clients particular timezone is generally considered a display problem, whenever you are dealing with storing dates/times it's almost always recommended that you record them as UTC. At the moment, you are recording the servers local time against the audit record which means absolutely nothing with regards to your clients.
What you want to do is record the current UTC time in the DB record
loginAudit.LOGIN_TIME = DateTime.UtcNow;
Then when displaying, convert it back to local time.
In order to do this you need to be culture aware, in other words, you need to know which timezone the client is on in order to translate from UTC back to local. For example, if I were a client, I would be working in GMT Standard Time time, so in order for me to see the audit time relative to me you would need to do
var gmt = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var localTime = tzi.ConvertTimeFromUtc(loginAudit.LOGIN_TIME, gmt);
In terms of how to get this information from the client, there are various ways of doing this like simply letting the user select from list of available TZ (reliable but intrusive) to using a 3rd party service to lookup the information based on their IP (not as reliable but better UX for the user) - I'll leave you to investigate and decide which is best for your app.
Alternatively, if you prefer to not deal with timezones and just work with dates you could just store the offset along with the UTC time which would give you the local time once calculated - see DateTimeOffset.
If all of your users are in one time zone,what I have done in the past was change the time on the server to be the correct time :-) It worked out well.
If your users span multiple time zones, you need to capture the time zone the user belongs to, and store your dates in UTC time. UTC time is universal time, which you convert to local time through the time zone. This is how it is typically handled.

Time conversion to client time c#

I have one application which need server to process the client request.
In this application time is very important.
Whenever client request anything, i would like to save the time of the request.
Problem is, my server is in US and client is in australia.
How can i change server time to client time and save it on database.
This should be accurate even during day light saving.
How can i achieve this
Ok i have save time in database as UTC.
On client side i have this code,
DateTime dt = booking.CreateDateTime.Value;
var localTime = TimeZone.CurrentTimeZone.ToLocalTime(dt);
When i print that localTime, it is 7 hour faster then local time.
How can i change that time to local time?
The guideline I know states that times should always be saved as UTC in the database, never local. This way you avoid many local time difference pitfalls (including daylight savings).
When you need the local time, retrieve it as UTC from the database and convert it. You can use the DateTime struct to help you out with this:
var utcNow = DateTime.UtcNow;
SaveToDB(utcNow);
var utcFromDb = RetrieveTimeFromDb();
var localTime = DateTime.ToLocalTime(utcFromDb);
It's typically best practice to store dates in UTC, and then translate to a locale when necessary.
var date = DateTime.UtcNow();
var tzi = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
var offset = tzi.GetUtcOffset(date);
Maybe take a look at the TimeZoneInfo class?
If that doesn't satisfy your needs, there's Noda Time.
Agreed that the time should be stored in UTC. The problem will comein when converting to the client's local time (not the server's). To convert to the client's local time, you will need to know the client's time zone information and store this with the UTC time in the db.
Then with both pieces of information you should be able use the above methods to convert to the client's local time.

Categories

Resources