Serving clients in different timezones - sql-server

I am trying to design an application that allows Support personnel to show system tray alerts between a certain time window in future on all user machines.
So we have clients in multiple time-zones checking in to a central server looking for any new alerts to be displayed.
The central DB has a table that stores the alert details with their start/end time and a webservice that responds to the clients by checking this table.
The challenge is that the client as well as the future trigger time on the server can be in any user-specified timezone.
Based on a few threads that I read here, the best practice is to store the start/end time in UTC in the database and convert it to the client's timezone when a request comes in.
That would mean converting all start/end times to client's timezone every few mins. I am worried this would be a major performance issue on the central server. Handling Daylight Savings times is also another point to consider.
Is there a smarter way to handle this? Any best practices to handle such scenarios would be really help.

Assuming you are using SQL, then you'd want to use DateTimeOffset as the data type. This type is capable of storing & manipulating both timezone and DST information.
Please see the accepted answer in this thread for the canonical answer to this class of issues: DateTime vs DateTimeOffset

Related

Does QuickBooks have any kind of audit log?

QuickBooks allows users to change posted periods. How can I tell if a user does this?
I actually don't need an audit log, but just the ability to see recently added/edited data that has a transaction date that's over a month in the past.
In a meeting today it was suggested that we may need to refresh data for all our users going back as far as a year on a regular basis. This would be pretty time consuming, and I think unnecessary when the majority of the data isn't changing. But I need to find out how can I see if data (such as an expense) has been added to a prior period so I know when to pull it again.
Is there a way to query for data (in any object or report) based not on the date of the transaction, but based on the date it was entered/edited?
I'm asking this in regard to using the QBO api, however if you know how to find this information from the web portal that may also be helpful.
QuickBooks has a ChangeDataCapture endpoint which is specifically for exactly the purpose you are describing. It's documented here:
https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/changedatacapture
The TLDR summary is this:
The change data capture (cdc) operation returns a list of objects that have changed since a specified time.
e.g. You can continually query this endpoint, and you'll only get back the data that has actually changed since the last time you hit the endpoint.

DATETIME or timestamp which i should prefer?

I am using SQL Server 2008. The server is in india. I want to store the users login and logout time. I can easily do that in SQL Server.
Now we have clients/admins from different countries who will check those login/logout time. They want these times in their respective time zone.
One more scenario is my clients travel from one country to another country, so the log time should be automatically updated as per the timezone.
So my understanding is I have to store the timezone info along with datetime for clients. So that I can use TimeZoneInfo::ConvertTime method to convert to different time zones.
I can give my clients an option to save their timezone while registration.
But my doubt is if my client changes his country do they need to change their timezone manually or is there any way i can automatically detect timezone. Is it feasible to check for the system timezone?
Or anyway storing timestamp can help me?
Use datetimeoffset. My company has operations all over Europe, a few Asian countries, and North America. Code your application so that it passes along the timezone setting of the current computer to the database. When a user travels, Windows can update the timezone information as it detects the geographical location of the user. I never had to worry about DST that way (imagine the fun dealing with daylight savings time in 2 continents).
Since the timezone info is stored, I can convert it to any timezone I want. Or the application reading the data can do that, using the local computer timezone.

One database, multiple frontends, maintaing request ordering

Assuming I have one database keeping a simple history with multiple front ends talking to it (one front end per server), I wonder what are the common solutions to deal with time. As soon as I have multiple servers, I cannot assume a global consistent clock, and I was interested in the possible solutions to maintain some kind of ordering between requests.
For a concrete example, let's say I want to record histories of customers, where history is defined as time ordered set of records. The record table would be as simple as (customer_id, time, data), and history would be all the rows where customer_id == requested id. Each request sent by the user would contain one record sent to one customer. Ideally, the time should refer to the "actual" time the request was sent to the front end by the customer (as that's the time as seen from the user POV). To be exact, I only care about preserving the ordering between records for each customer, not about the absolute time.
I am aware of solutions such as vector clocks, etc... but that seems rather complex, and I would expect this to be a rather common issue ?
Solutions which are not acceptable in my case:
Changing the requests arriving at the front end: I unfortunately have to work under the constraint that the requests are passed as is. I have complete control of whatever communication protocol is needed between front ends and database, though.
Server time clocks are synchronized
All request which require being ordered to each other are handled by the same front end server
[EDIT]: the question may sound a bit like red-herring, so here is my rationale for asking it: while this is not my issue right now, I am interested in the possibility to go to a platform like Google App Engine, which explicitly says that their servers are not guaranteed to be time synchronized. The solution to that issue for request ordering does not sound obvious to me - but maybe something like vector clock is actually the only "good" solution ?
When you perform any action that records history data to the database you could record two sets of datetime info:
the datetime as set by the DB when the record was inserted
the datetime passed through with the data as a legitimate piece of metadata.
The former would give you a central view of the world if you ever needed it, and the latter would let you reconstruct datetime from customers perspective.
If you were ultra-keen you could also pass through the datetime from the users browser by filling some sort of parameter/field using JavaScript.
As soon as I have multiple servers, I
cannot assume a global consistent
clock
Well, you can configure servers to sync their clocks to a time server. You could also configure your database server to sync to a time server, and configure the other servers to sync to your database server as often as you need to. (I'm not saying that's a great idea, just saying it's possible. If you have access to all the servers.)
Anyway . . . so the front ends are the only pieces of software you have that actually know when a request arrives. Is that right?
If that's right, then it's the front ends job to record the time of the customer's request, possibly in UTC, and then forward that timestamp to the database.
If you can't synchronize the server's clocks, then I think your only hope is to have every front ends ask just one specific server--maybe your database server, but maybe not--what time it is when a customer request arrives. A front end can do that by asking for daytime on port 13 (DAYTIME protocol, RFC-867), asking for time on port 37 (TIME protocol, RFC-868), or asking a time server on port 123 (either NTP or SNTP protocol, RFC-1305 and RFC-2030).
But after reading your edit, I think what you want is impossible. You seem to be saying that
what the front ends send doesn't
contain enough information to
reconstruct the "true" ordering
what the front ends send cannot be
changed
If the front ends can't send you any other information, vector clocks and interval tree clocks won't help.

How do I sort events created by different clients based on a global clock?

I have a newsfeed program, and I've got many client applications (about 70) across a few timezones that generate events, for example when a secretary schedules a meeting it adds to the list on the server. This list is served to every client that wants to view it. Currently each record has the following metadata:
random unique ID
local timestamp (YYYY:MM:DD:H:M:S:ms)
How do I sort these events on the server, such that they appear in the correct order they were submitted in? Currently they get mixed up since local timing doesn't match. I don't have any UTC timestamps (can I calculate these locally?), so I'm wondering if I can make-do with the information I got... or should I be getting more information from each client? I noticed even clients in the same timezone get events mixed up because their system time is not synchronized (is it possible to know the exact global time, or synchronize the system time with a server on Windows?)
I'm not asking for code, I just need a pointer in the right direction.
When storing temporal values it is essential to always use UTC. Anything else and you're screwed. You really should also store the related timezone along with the UTC.

How reliable is DateTime.UtcNow in Silverlight applications?

I have a silverlight application which users will be running in various time zones.
These applications load their data from the server upon start up, then cache it in IsolatedStorage.
When I make changes to the data on the server, I want to be able to change the "last updated time" so that all silverlight clients download the newest data the next time they check this date.
However, I'm a bit confused as to how to handle the time zone issue since a if the server is in New York and the update time is set to 2010-01-01 17:00:00 and a client in Seattle checks compares it to its local time of 2010-01-01 14:00:00 it won't update and will continue to provide old data for three more hours.
My solution is to always post the update time in UTC time, not with the time on the server, then make the Silverlight app check with DateTime.UtcNow.
Is this as easy as it sounds or are their issues with this, e.g. that timezones are not set correctly on computers and hence the SilverlightApp does not report the correct UTC time. Can anyone say from experience how likely it is that using DateTime.UtcNow like this for cache refreshing will work in all cases?
If DateTime.UtcNow is not reliable, I will just use an incremented "DataVersion" integer but there are other scenarios in which getting time zone sychronization down would make it useful to thoroughly understand how to solve this in silverlight apps.
DateTime.UtcNow is as reliable as the clock on the client system. So the question is entirely independent of Silverlight or .NET, the question is how much do you trust the system clock on the client machines?
You need to weigh the risk that a user of a machine may have incorrectly set the time on their machine because they have not set the time zone correctly. This risk is entirely human in nature.
Using an incrementing version number only has one downside, you need to first retrieve the current value before you can set a new one. If that isn't a problem then go with that and eliminate the FUD you might have around time zones.

Resources