German Wear Discount Shop - Click Here Write for Dotnet-friends and earn for your each submission [Dot]Net-Friends
Skip Navigation Links
Home
Latest
Fast Code
Articles
Tutorials
Online Resources
Forums
Login   | Hi, Guest


Calculate Client Time from the Server saved DateTime using ASP .NET Client Callback

Written by omerkamal on Jul 15, 2007
Determine the Client DateTime by adding client Timezone offset to the Server saved DateTime using ASP .NET 2.0 Client Callback

Explanation:

I had a hard time to find a good solution for my Dotnet-friends.com forum clients to display them the time in their regional time zone format instead of the server Timezone.
Whenever time is saved in your Database it is always a good practice to save UTC or GMT time in your database. If you save the responded client time then it will be very hard to mange it for the all different Timezones.
On the other hand if you are saving the Server time in your Database then there is a chance that you might change your Web Provider at some point of time. And then it is also possible that new Web host servers are not located at the same Timezone. So you will be lost!
How to change a DateTime to UTC or GMT?
DateTime DateTimeUtc = DateTime.Now.ToUniversalTime();
How to Change Server time to the Client time?
To change one Timezone DateTime to other we need the Timezone difference between both Timezones which is called Timezone Offset. Offset is basically calculated against or with the reference to UTC time.
So what is the Basic problem?
I mean we can save all the Timezones in our Database and then we will be able to calculate against our client Timezone. But for that, every Client must have told us his/her Timezone. This will be not possible at least in the anonymous visitor case.
So what are the ways we can adopt to tackle this issue?
There is a way to use JavaScript. This is very successful in a case when you are only using Plain page but not embedded Data Presentation Control (like Gridview, DataList, Details View, etc) and also you don’t need a time calculation against the server time.
To calculate the time against the server time you have to inform the server with Client Offset.
Ok, at this point of time if you are thinking that yeah we can do this with a hidden field inside our page then it’s not possible because data binding with your Data Presentation Controls happens earlier then your Page reads the Client side information with the Help of the JavaScript.
It is also possible to add JavaScript at the page load (and this will be one of our trick also) but still you won’t be able to change the dates in your Form because you have to tell your server the offset before the data Presentation Control loads.
So the 1st trick is to read the Client Timezone information at Page load which happens earlier then Load event of any other Control in the Page. The 2nd thing is to somehow pass the offset to the Server. The 3rd issue is to retrieve back the calculated information to the Client (without a Postback).
I had two methods in my mind to perform the 2nd and 3rd tricks (i.e. the Bi-directional Talk between a Client and the Server without the Page Postback)
(A)
1. Create a Profile Filed for each user (Registered or Anonymous both)
2. Get the Timezone Offset through JavaScript
3. Save the Timezone Offset to a Cookie
4. Read this Cookie in the server side
5. Save the Timezone Offset in the User Profile.
I did not like the idea because:
1.  We have to create (depends upon the website Visitors per second) thousands of Anonymous Profiles. This could get a too much load at some level
2.  We have to create Cookies. This might not be possible for every Browser and Client. Because many people don’t like Cookies
(B)
1. Use a Session variable
2. Get the Timezone Offset through JavaScript
3. Use the client Callback to send the offset to the server side
To use a Global Session Variable initialize it in Global.asax
 protected void Session_Start(Object sender, EventArgs e)
    {      
          Session["TimeZoneOffset"] = 0;
          Session.Timeout = 10;
    }
Initialize Session["TimeZoneOffset"]to zero as a default and set the Session Timeout to 10 minutes.
With the evolution of ASP .NET 2.0 we got very nice new Page tools. One of them is the Master Page creation. As it is very common to use Master pages in new generation web sites we are going to answer the both Problems at the same time.

Now, we are going to create a Client Callback system in our Master page (so it is accessible to each and every page). Add one Interface to your master page. Inherit your master page from System.Web.UI.ICallbackEventHandler Interface (keep in mind that Multiple-Class-Inheritance is not allowed in C# but Multiple-Interface- Inheritance can be used). This interface informs the server that it can be contacted in the form of a callback from the Client Computer.
protected void Page_Load(object sender, EventArgs e)
   {     
     if (!Page.IsPostBack)
         {
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
 
String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";
 
cm.RegisterClientScriptBlock(this.GetType(),"CallServer", callbackScript, true);
 
cm.RegisterClientScriptBlock(this.GetType(), "ReceiveData",
"function ReceiveServerData(context){callbackMessage.innerText = context;}", true);
         }
    }
Here we are registering and connecting Bi-directional methods. “CallServer” is a call from the Client to server. CallServer is taking one argument from Client to the server (Timezone offset in our case) whereas “ReceiveServerData” is where Server sends back the data after desired process on it.
You noticed that “ReceiveServerData” is sending data to an HTML Control “callbackMessage”. So insert a Tag on the page side.
<span id="callbackMessage" style="color:red">span>
This will display the returned calculated string inside the . Most probably you don’t want to show such information of the page. The Problem with the Tag is that you cannot hide your state information from the user. So I choose the Hidden field to solve my problem.
System.Web.UI.HtmlControls.HtmlInputHidden Hidden1;
cm.RegisterClientScriptBlock(this.GetType(), "ReceiveData",
"function ReceiveServerData(context){Hidden1.value= context;}", true);
We still need a JavaScript function which will be used to call the “CallServer” method. So let’s add the function to our Page.
cm.RegisterClientScriptBlock(this.GetType(), "SendValue",
             @"function SendClientTimeZoneOffset(){
             var now = new Date();
             var offset = now.getTimezoneOffset();        
             CallServer(offset,'');}", true);
The IF block of the Page_Load event will look like this after adding new script.
if (!Page.IsPostBack)
         {
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";
 
cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
 
cm.RegisterClientScriptBlock(this.GetType(), "SendValue",
@"function SendClientTimeZoneOffset(){
var now = new Date();
var offset = now.getTimezoneOffset();
CallServer(offset,'');}", true);
 
System.Web.UI.HtmlControls.HtmlInputHidden Hidden1;
cm.RegisterClientScriptBlock(this.GetType(), "ReceiveData",
"function ReceiveServerData(context){Hidden1.value= context;}", true);
         }

Further, we need to implement two Methods RaiseCallbackEvent(String) and GetCallbackResult() of the ICallbackEventHandler Interface:
    string returnValue = "0";
    public void RaiseCallbackEvent(String Offset)
    {
        if (Offset.Length == 0)
            returnValue = "Date Error!";
        else
        {
Session["TimeZoneOffset"] = Offset;
DateTime TestUTCDate=DateTime.Now.ToUniversalTime();
 
returnValue = TestUTCDate.AddMinutes(
Convert.ToDouble(Offset) * -1).ToString();
        }
    }
    public string GetCallbackResult()
    {
        return returnValue;
    }      
Here we are creating Test date “TestUTCDate”. Normally this can be your Server UTC Date either taken from the database or some manual date. For example, in Our Forum case we are getting Saved Dates on which Topics and messages were Created or edited. The return value is set to “0” by default. You noticed that how we are assigning the Timezone offset to our session sate variable “Session["TimeZoneOffset"]”.
There could be a Case that you need an Inline code inside your Data Presentation Control. In this particular case you can still use the “Session["TimeZoneOffset"]”  like this:
<%#DateTime.Parse(Eval("LastDate").ToString()).ToUniversalTime().AddMinutes(
Convert.ToDouble(Session["TimeZoneOffset"]) * -1)%>
 Eval ("LastDate")” is a Database field. This is accessed through a DataSource Object.
The Last thing which have to be done is to add the JavaScript Function "SendClientTimeZoneOffset()" to your Body Load event.

<body onload ="SendClientTimeZoneOffset();">


 That’s all. Now you execute your code and enjoy the result.
Visitors/Readers Comments
(for questions please use The Forum)



Scott

The Problem is allot easier than expected.

The Date that is passed in is the UTC Time taken from a database or what ever.

Dim LocalTimeDate As DateTime = Now
Dim
localzone As TimeZone = TimeZone.CurrentTimeZone
Dim
Culture As New CultureInfo(HttpContext.Current.Request.UserLanguages(0))

Dim DateTimeChanged As String

DateTimeChanged = DateTimeChange + localzone.GetUtcOffset(LocalTimeDate)

 

Hope this helps people.

16/07/2007 14:49:43 UTC

Omer Kamal

Hi Scott,

I have tried your suggestion but unlucky it does not work.

The Culture info does not do the said assignment rather it is meant to manipulate the data format (like in the Date case: German date 24/07/2007 to US 07/24/2007). I am not sure if it returns the different Timezones offset as Timezones are it self variant (daylight system). 

To make it more simple, as you are accessing the Culture info rather then timezone offset from the Client, you have to have some database to know what is the timezone offset for current client culture. Where as JavaScript reads it from the Client Computer.

On the other hand there are situations where IE language is set different then to local. Like i live in Germany but my IE Culture is set to en-us.

Please, guide me if I could not follow your example.

 

Thanks for your kind information.

22/07/2007 08:41:55 UTC

Jon
Anyone else getting an error in IE7 "Hidden1" is unidentified?

04/09/2007 13:24:43 UTC

dotnet-friends

The HTML control needs to be add to the Page.

read this:

Initializing and accessing HtmlInputHidden in the code behind

05/09/2007 01:22:39 UTC

'Anil' Radhakrishna
I think its possible to show UTC Date/Time recorded on the server in a user's regional time zone format with just Javascript.

I cooked up this Javascript function to do it. It uses Date.parseString (to convert a DateTime string to a Date object) & Date.add (to add or subtract specific elements of a Date) functions from Matt Kruse's Date library - http://www.javascripttoolbox.com/lib/date/examples.php

function showAsLocalDateTime(utcDateTime){
var localDateTime = new Date(utcDateTime);
localDateTime.add('m',-(utcDateTime.getTimezoneOffset()));
alert(localDateTime.toLocaleString());
}

This can be used in the .aspx like this -


It is not thoroughly tested. You can try it here - http://www26.brinkster.com/mvark/codegallery/Show_Server_DateTime_As_Local_DateTime.aspx

'Anil' Radhakrishna
Web Development Tips, Tricks & Trivia - http://mvark.blogspot.com/

07/09/2007 00:36:06 UTC

omerkamal

Hi Anil,

The problem is not only to show User UTC/GMT Time rather:

  1. Reading Client Time Zone offset from the Client Computer
  2. Reading Server Saved time
  3. Calculating the Client remot Time for it
  4. then It have to be also displayed to the Client.

07/09/2007 01:35:19 UTC

hj
good

24/09/2007 01:45:00 UTC

Abdul sathar

How to calculate the Time Duration from End time to Start time?

For example the start time is 2007-09-25 16:59:12 & End time is 2007-09-25 17:10:12.Please help me,how to write the C# Code for this.

26/09/2007 01:50:36 UTC

dotnet-friends

Read this:

https://dotnet-friends.com/Forum/ThreadMessages.aspx?Viewed=0&ForumID=5&TopicID=118&ThreadNew=0

27/09/2007 02:49:19 UTC

tamil

hai

i want to calculate the time difference between two textbox (time)values .how to do this .plz tell me the solution.

11/01/2008 01:50:58 UTC

noor alam
I am trying to convert time of a time zone to that of other time zone. I means if my server is in india and my user enter in from uk( suppose he had entered 12;30Pm) then at that movement Indian time will be displayed to me. but I am not get proper dll and function. if ther is some one pls help me to solve this.

05/03/2008 02:50:48 UTC

Jon Lacey
Any chance of the code as a download?
I am getting stuck (VB) creating the masterPage

17/06/2008 07:05:26 UTC

venugopal

function

{

 

 

 

 

 

 

 

 

 

 

det_time()debugger;var d = new Date();var month=d.getMonth();var day= d.toLocaleDateString();var time =d.toLocaleTimeString();var local=d.toDateString();var date1=d.toLocaleString();//var time=d.getTime();

 

//d.toTimeString();

 

//var t = c_hour + ":" + c_min + ":" + c_sec;

alert(date1);

}



call this  in  body  onload="det_time()"

11/09/2008 05:32:35 UTC

jeff
I may be mistaken but I don't think this will work when DST is taken into account.

07/01/2009 09:02:56 UTC




Add your Comments

Name:  
Message:
Note: For faster response please use Forums >> for your questions instead of the comments area! (Admin)