Client Time shown instead of server Time in javascript - javascript

I am into strange issue of javascript Date() function, these are the details
Server Side : Struts (ActionForm, Action class, jsp)
Client Side : jQuery, javascript
Now, I need a server time on the page and manipulate using javascript. So, I did Calendar.getInstance().getTimeinMillis(); in the action class and save it as an ActionForm attribute.
Now, at the client side, I got the long value (timeinMillis) from the styleId. But, to manipulate, when I do
var curTime = parseInt($("#serverTime").val());
var serverTime = new Date(curTime);
Now, the serverTime is providing client machine date and not server date though we are providing timeinMillis of server.
The strange part is when I pass string value of a date instead of long timeinMillis from server and pass it as an argument, it works well.
Any idea?

This is because your javascript runs on client machine, so when you create new Date() in javascript it picks up the client machine time.
Answer to second query if you pass the sever date as string it will create date object of that date.
Use below function
function calcTime(offset) {
// create Date object for current location
d = new Date();
// convert to msec, add local time zone offsetand get UTC time in msec
utc = d.getTime() + (d.getTimezoneOffset() * 60000);
// create new Date object with supplied offset
nd = new Date(utc + (3600000*offset));
// return time as a string
return "The Server time is " + nd.toLocaleString();
}
Here you need to pass the offset of your server time with UTC

Finally resolved the issue with help of the above hints.
From java side, taken the offset from the UTC with the day light saving option.
so, in Action class
Calendar c = Calendar.getInstance();
TimeZone z = c.getTimeZone();
int offset = z.getOffset(c.getTimeInMillis());
This gives the offset of local timezone and UTC timezone including day light saving
At the javascript, I used,
var now = new Date();
var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
var sd = new Date(now_utc.getTime() + offset);
alert("The Server time is " + sd.toLocaleString());
And, this gives correct server time with the day light saving options.
Thanks a lot for your help, without them, would not be possible to work it out. Cheers!

A simple solution in PHP:
var phpDate = '<?php echo date('Y/m/d H:m:s');?>'
, serverDate = new Date(phpDate)
, month = serverDate.getMonth()+1 //getMonth() returns a 0-based number.
, day = serverDate.getDate()
, year = serverDate.getFullYear();
console.log(year + '-' + month + '-' + day);

If your server and client time are in different timezones and you want to show this difference to the user, then you have to send timezone information to the client as well.
Calendar.getInstance().getTimeinMillis() returns the number of milliseconds since the epoch, but it does not say anything about the timezone. It's just a number of milliseconds since midnight 1970/1/1 UTC and at any instant in time, this number is the same on any system (well, given the time is synced), regardless of system's timezone. This might give you the impression that you were getting client time instead of servers.
The reason why this works with string representation of date is the timezone information included in it, and Javascript's ability to parse that and take it into account when constructing the Date object.

Related

Convert the CST time to local browser time [duplicate]

i am using moment for getting server time .
moment.tz.setDefault("Asia/Kolkata");
var now = new Date();
var _p_date = moment.tz(now, zone).format();
time when inserting _p_date = 2016-01-05T18:32:00+05:30
But in database date variable is type of DATETIME. and time is saved as 2016-01-05 18:32:00.
and after that when i comparing with this to get time_ago funcionality. providing me wrong estimation.
using time ago = moment("2016-01-05T18:32:00.000Z").fromNow(); // is showing In 5 hours
Since your initial timezone is lost you have to create moment.tz object with selected timezone. Try this plunker
var date = moment.tz(moment("2016-01-05T18:32:00.000Z", "YYYY-MM-DDTHH:mm")
.format('YYYY-MM-DD HH:mm'), 'Asia/Kolkata');
console.log(date.fromNow());

Parse date in JavaScript that is sent by ASP.Net via a cookie

I am storing a datetime value in a cookie using ASP.Net server-side C# code.
On client-side, I am reading the date and converting it to UTC using JavaScript. The code for this is as given below.
Storing date time in ASP.Net
//DateTime.Now depends on location of web server
HttpCookie cookie = new HttpCookie("xyz", DateTime.Now.ToUniversalTime().ToString());
Response.Cookies.Add(cookie);
JavaScript code to read date time sent by ASP.Net
//cDate depends on user's location
//c is value read from cookie named 'xyz'
var cDate = new Date(c);
var cDate_utc = new Date(cDate.getUTCFullYear(), cDate.getUTCMonth(), cDate.getUTCDate(), cDate.getUTCHours(), cDate.getUTCMinutes(), cDate.getUTCSeconds());
When the end user's location is different from ASP.Net web server's location, then the datetime value in the cookie will be incorrectly interpreted by JavaScript. For example, in one case the value stored in cookie was 10/31/2015 7:29:54 PM and there is no way for JavaScript to know that this is UTC which means it would be incorrectly parsed on client-side.
Question: How can I pass DateTime value from ASP.Net to JavaScript in above scenario so it interprets correctly in JavaScript no matter what the geographical locations of end user's browser and ASP.Net web server are?
UPDATE with a solution that worked
After a lot of research, I came up with the following. The bottom line is to always work in UTC so day light savings does not cause problems with the programming logic.
Pass UTC and not local date time from ASP.Net server-side to client-side via a cookie using individual components of date time. Do not pass a date time string but individual components of date time as a comma-delimited list in following format: year,month, day, hours, min, sec, milliseconds. Passing individual components rather than a date time string from ASP.Net is better since JavaScript Date constructor can behave in an erratic manner when parsing a string especially if the format of string passed is not what the constructor likes. Passing individual components also helps in cross-browser consistent behavior since the Date constructor with individual components works well across all major browsers.
On client-side, read the cookie value and instantiate a Date object that will be the local time on browser side corresponding to server-side UTC time
Now you have the server-side ASP.Net passed date time in local date time on client-side. This might work for some cases, but can cause sudden surprises on client-side when daylight savings happens, so it's best to convert this client-side date to UTC.
Pass date time in UTC to client-side from ASP.Net
DateTime utcDateTime = DateTime.Noe.ToUniversalTime();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(utcDateTime.Year);
sb.Append(",");
sb.Append(utcDateTime.Month - 1); //since JavaScript uses a 0 based index for month
sb.Append(",");
sb.Append(utcDateTime.Day);
sb.Append(",");
sb.Append(utcDateTime.Hour);
sb.Append(",");
sb.Append(utcDateTime.Minute);
sb.Append(",");
sb.Append(utcDateTime.Second);
sb.Append(",");
sb.Append(utcDateTime.Millisecond);
HttpCookie cookie = new HttpCookie("xyz", sb.ToString());
Response.Cookies.Add(cookie);
Get UTC date time in JavaScript for passed ASP.Net date time
var c = getCookie("xyz");//getCookie is a custom JavaScript function to read cookie value
if (c) {
var dateArray = c.split(",");
//get local date time corresponding to ASP.Net passed UTC date time
var cDate = new Date( Date.UTC(dateArray[0], dateArray[1],dateArray[2], dateArray[3], dateArray[4], dateArray[5], dateArray[6])) ;
//get UTC date time so day light savings does not cause issues in logic on client-side
cDate_utc = new Date(cDate.getUTCFullYear(), cDate.getUTCMonth(), cDate.getUTCDate(), cDate.getUTCHours(), cDate.getUTCMinutes(), cDate.getUTCSeconds());
logInfo("date from cookie in utc is " + cDate_utc);
}
Although the comments already point you in the right direction:
If you use moment.js it will by default use UTC format and even if it wasn't (for completeness sake) you can use this format to specify an offset: 2013-02-08 09:30:26.123+07:00
You call the code like this: moment(cDate, $format);
If I understand your question correctly, you want to convert the date passed in the cookie from UTC to local time.
You can use Date.prototype.getTimezoneOffset()
getTimezoneOffset returns the offset from UTC to local time in minutes.
Adjust locally by subtracting the offset minutes...
new Date(dateServer.getTime() - ((60 * 1000) * dateServer.getTimezoneOffset()))
Here's an example...
var dateJan;
var dateJul;
var dateValue;
var divLocal;
var divServer;
var timezoneOffset;
dateValue = new Date('10/31/2015 7:29:54 PM')
divServer = document.getElementById('serverUTCTime');
divLocal = document.getElementById('localTime')
divServer.innerHTML = 'from server = ' + dateValue.toString();
// Get dates for Jan & Jul
dateJan = new Date(dateValue.getFullYear(), 0, 1);
dateJul = new Date(dateValue.getFullYear(), 6, 1);
// Get timezone offset
timezoneOffset = Math.max(dateJan.getTimezoneOffset(), dateJul.getTimezoneOffset());
// Check if daylight savings
if (dateValue.getTimezoneOffset() < timezoneOffset) {
// Adjust date by Jan offset
dateValue = new Date(dateValue.getTime() - ((60 * 1000) * dateJan.getTimezoneOffset()));
} else {
// Adjust date by Jul offset
dateValue = new Date(dateValue.getTime() - ((60 * 1000) * dateJul.getTimezoneOffset()));
}
divLocal.innerHTML = 'to local = ' + dateValue.toString();
<div id="serverUTCTime"></div>
<br/>
<div id="localTime"></div>

Convert utc date time to local date time using JavaScript or jQuery

I am storing a UTC date time in a SharePoint list and fetching it's value in c#, converting into milliseconds from 1 Jan 1970 and passing those milliseconds to JavaScript to get date object.
But when I create a date object, its value remains same as UTC date, I want that value to be in users local time zone and reflecting their daylight saving status.
You can use the TimezoneOffset in javascript, check the following code,
var d = new Date()
var n = d.getTimezoneOffset();
In this way you can calculate the time as you want.
Let me know if you need more details :)
When you create a new date in Javascript i assume you create it on the client side / client machine:
var d = new Date(millis);
The notion that the value remains the same in UTC no matter where you construct the Date object is correct, it's only a matter of how you display the date: in UTC or in the user's local timezone:
You can run this code to see the difference:
var local = date.toDateString() + ' ' + date.toTimeString();
var utc = date.toUTCString();
alert(local);
alert(utc);
Note that the value of millis is the milliseconds passed since 1970-01-01 00:00:00 UTC no matter where you are in this world. Calling new Date().getTime() on 2 opposite sides of the globe should return the same number of milliseconds.

getTimezoneOffset() method return different time on localhost and on server

I have a function in which I am calculating the current user location time based on the Australian NSW timezone minus the local offset. So for example I want to compare an event starting time in Australian (NSW) local time vs my local time I am getting the correct value if I open the website on my localhost. However I am getting 1 hour different if I visit the website on the uploaded server (test environment). So if the correct time is 04:00 on localhost I am getting 05:00 on the test environment.
Here is my function:
var date = {
formatFullDate: function(date, gmtTimeOffset) {
var localDate = this.getLocalTimeFromAustraliaTime(date, gmtTimeOffset),
month = this.addZeroToFront(localDate.getMonth() + 1),
hour = this.addZeroToFront(localDate.getHours()),
minute = this.addZeroToFront(localDate.getMinutes());
return localDate.getDate() + '/' + month + '/' + localDate.getFullYear() + ' ' + hour + ':' + minute;
},
formatTime: function(date, gmtTimeOffset) {
var localDate = this.getLocalTimeFromAustraliaTime(date, gmtTimeOffset),
hour = this.addZeroToFront(localDate.getHours()),
minute = this.addZeroToFront(localDate.getMinutes());
return hour + ':' + minute;
},
addZeroToFront: function(whatever) {
if (whatever < 10) whatever = "0" + whatever;
return whatever;
},
getUTCtimeOffset: function() {
var date = new Date();
return date.getTimezoneOffset();
},
getLocalTimeFromAustraliaTime: function (date, gmtTimeOffset) {
var gmtTime = new Date(date.getTime() - gmtTimeOffset*1000),
localOffset = new Date().getTimezoneOffset(),
localDate = new Date(gmtTime - localOffset*60*1000);
return localDate;
}
}
Some general details for my specific case:
Aus/NSQ time zone: UTC/GMT +10 hours
Finnish timezone: UTC/GMT +3 hours
So there is 7 hours different between AUS/NSW and Finland and the result is correctly displayed on localhost but not on the test environment. I am not sure why there is 1 hour different between these 2 cases.
EDIT: 1
This is how I am displaying the current local time
var tr = $('<tr style="cursor:pointer; color: #000000" id="' + categoryId + '_' + raceNumber + '_nextRaceTr"/>')
.append($('<td/>')
.append($('<p/>')
.html(date.formatTime(new Date(value.time), value.timezoneOffset))))
Where as time and timezoneOffset are the JSON response.
P.S - Dont pay attention if I am missing enclosing brackets or any other syntax error. I have only copied a small piece of code just to show how I am displaying the time on HTML.
The JavaScript Date object is always influenced by the time zone settings of the environment where it is running. In most cases, that's the user's browser. Users of different time zones will get different results running your code.
In general, you should beware of any code that follows a pattern like this:
var adjustedDate = new Date(someOtherDate.getTime() - someOffset);
You might think you're cleverly adjusting the behavior of the Date object to a different time zone, but in reality you're changing the referenced point in time and leaving the time zone the same!
Also, consider where you have:
var localOffset = new Date().getTimezoneOffset();
You might think you're getting the time zone offset for the user, but actually you are just getting the current time zone offset for the user. Remember, new Date() initializes to the current moment in time. The moment you're working with might have a completely different offset, depending on if the user happens to be in a time zone with daylight saving time or not and whether it was in effect at that time.
As far as your code goes, it's a bit difficult to tell what you're after since you didn't give examples of your input. You might want to take a look at moment.js, which has most of the formatting functions you might be looking for.
BTW - I don't see anything in your code that would actually bind it to any of the Australian time zones.
I recommend that you convert all times to UTC and store in that format. When you display a time for a user, you can convert to their local time from UTC. Just make sure that you do all calculations/conversions on the same machine on which you are going to display the time (e.g. if you are displaying dates in a webpage, don't calculate the local time on the server, send down an epoch timestamp to the browser and then convert it to local time using JavaScript).
var d = new Date(1413409549000);
alert(d.toString());

Node.js record date is greater than the current client date

When i write data in mongodb for the recording date i use new Date() in node.js and i return that date with ajax response. To calculate the time elapsed from the moment the data in mongodb i create a new date on the client side. Then i calculate the difference between the current date and the date of which came from the server.
Here is my code:
var now = new Date();
var post_date = new Date(date_from_server);
var elapsed = now - post_date/1000;
document.write(elapsed + " seconds elapsed");
But, unknown to me, the recording date is greater than the current date, and the difference between them for the first time has a value of -40 seconds!
Please help me to understand this point. I guess that's something I'm doing wrong. But what's wrong?
It seems that the time setup between the server and client is different. You may try to emit a getFinalTime event to server, where the second time is recorded and returned to client for calculation.

Categories