2

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();
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Adams
  • 195
  • 1
  • 10
  • When you say "real" time, do you mean the time in the user's current time zone? – Robert Harvey Mar 24 '14 at 19:54
  • yes means users time. – Adams Mar 24 '14 at 20:01
  • 3
    Maybe this [SO answer could help](http://stackoverflow.com/questions/1091372/getting-the-clients-timezone-in-javascript). – keenthinker Mar 24 '14 at 20:04
  • If you go with @.paulwesterberg's answer to the question @pasty linked, you should consider using Noda Time on the server, since .net and windows use different naming conventions for timezones compared to that script (which matches the names in the [tz database](http://en.wikipedia.org/wiki/Tz_database)). – CodesInChaos Mar 24 '14 at 20:19

2 Answers2

1

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.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257
  • How does one capture the time zone that the user belongs to? – Robert Harvey Mar 24 '14 at 20:01
  • @RobertHarvey For proper clients it's easy. For web applications the only way I can think of is sampling the conversion function at enough points to uniquely determine a time-zone. – CodesInChaos Mar 24 '14 at 20:17
1

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.

James
  • 80,725
  • 18
  • 167
  • 237
  • You didn't explain how you would get the actual time zone from the client. – Robert Harvey Mar 24 '14 at 20:16
  • @RobertHarvey I was hesitant to go down that road because there are too many options, however, for completeness I have added a little snippet on ways of capturing this information. – James Mar 24 '14 at 20:33