Send data in server timezone issue - javascript

I've spent a lot of time trying to understand the timezones. But i'm still confused.
Design:
1) Server in a different time zone than client.
2) I got the following Info in API call:
/api/config/v1/system/time
{
"timeZoneOffset": -18000000, (milli sec)
"serverTimeUTC": 1485332569157,
"serverTime": "Wed Jan 25 03:22:49 EST 2017",
"timeZone": "Eastern Standard Time"
}
3) I have no access on the server. (Can't really change any code there!)
4) I have a complete access on client side. (Javascript)
Problem/Requirement:
I want to take clients time (PST, CST etc) and send it in the corresponding server time. (Whatever timezone the server is in) (Not necessarily UTC).
My code:
I've attempted the following but still confused as where I'm going:
getServerTimeZone: function(newTime){
var _this = this;
$.ajax({
url: '/api/config/v1/system/time'
})
.done(function(data) {
if(!newTime){
newTime = new Date();
}
//Get Server Timezone and offset
//Offset is in milli sec. Converting it to hours
var serverTimeOffset = data.timeZoneOffset / (60 * 60 * 1000);
// Get current timezone offset for host device
var x = new Date();
var clientCurrentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
//Calculate the difference
var actualOffset = Math.abs(clientCurrentTimeZoneOffsetInHours - serverTimeOffset);
//Format actual time in relative to server time
serverTime = moment.utc(newTime).zone(actualOffset).format('MM/DD/YYYY h:mm A');
});
},

Please see the modified code below, i used moment js manipulation feature utcOffset so we can change the timezone of the clients date.
It will give us the corresponding server date/time based on the date/time on the client.
getServerTimeZone: function(newTime){
var _this = this;
$.ajax({
url: '/api/config/v1/system/time'
})
.done(function(data) {
if(!newTime){
newTime = new Date();
}
//Get Server Timezone and offset
//Offset is in milli sec. Converting it to hours
var serverTimeOffset = data.timeZoneOffset / (60 * 60 * 1000);
// Get current timezone offset for host device
var x = new Date();
var clientCurrentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
// change the timezone using utcOffset
serverTime = moment(x).utcOffset(serverTimeOffset).format('MM/DD/YYYY h:mm A');
});
},
You can test it here, i used -5 offset.
https://jsbin.com/puvutevomo/edit?html,js,output

If I'm understanding the requirement correctly you shouldn't need to send any timezone specific information up to the server. When a date/time is given in ISO8601 format (and has an x on the end) it is in UTC format. Timezones at that point are irrelevant and only used for display purposes.
moment will display that date/time in the user's correct timezone automatically (based on the browser settings).
var d = moment('2016-01-01T00:00:00.000Z');
console.log(d.format('llll')); //This will output the date/time relative to the user's timezone automatically
var sendToServer = d.toISOString() //send this string up to the server. It is in UTC format.

Related

How to convert user input datetime into UTC and store in database with remote server in Javascript

I have a datetime which is from user input. And need to store into database.
The output of date in console.log() in remote server is different from local server.
Data from user input:
ui_date = '2018-05-23';
ui_time = '10:00'; // literally meant for 10 oclock
//.... i manage to concatinate ui_date and ui_time and convert to ISO datetime
Now...
Output from local server
console.log(myDate.toISOString());
// outputs: 2018-05-23T02:00:00.000Z
// This is correct UTC since I'm in philippines and the offset is +8
// Localserver automatically convert it to UTC
Output from remote server
console.log(myDate.toISOString());
// outputs: 2018-05-23T10:00:00.000Z
// This is wrong because it is in local time not UTC
It seems remote server cannot convert this datetime into UTC.
Does anyone have an idea about this?
UPDATE
showing the actual code:
By the way I'm using node.js as a server.
Input from user:
{
"date": "2018-05-23",
"time": "10:00"
}
my route:
router.post('/test_datetime', function(req, res, next) {
console.log(req.body.date);
console.log(req.body.time);
var date = req.body.date;
// get the date, month and year
var dd = new Date(date).getDate();
var mm = new Date(date).getMonth();
var yy = new Date(date).getFullYear();
// get the hour and min from "10:00" and convert to number
var hour = parseInt(req.body.time.substr(0, 2));
var min = parseInt(req.body.time.substr(3, 4));
// constructed datetime
var datetime = new Date(yy, mm, dd, hour, min).toISOString();
console.log(datetime);
});
local server output of datetime:
2018-05-23T02:00:00.000Z
Remote server output of datetime:
2018-05-23T10:00:00.000Z
The problem is your construction of the JavaScript Date because the method you use doesn't take in to account the client's offset to UTC.
Creating a new date from the date string, as your code does initially, will assume the date (and time) is local.
Then just setting the hours and minutes on that date will keep everything in sync.
let date = '2018-05-23';
let time = '10:00';
// parse the date and time using the local timezone info
let d = new Date(date + ' ' + time);
// Generate the UTC ISO string
let isoDateTime = d.toISOString();
console.log(isoDateTime);

Compare Javascript date with php current date

I am using the function :
var date = new Date();
in javascript. it gives the following output
"Sat May 13 2017 22:19:25 GMT+0500 (Pakistan Standard Time)"
Now I will embed this date in a URL and on server side , I will receive this date. On server i have a php script , now in this script i want to compare the date received from javascript client side with current php time and check if the difference between date time zone sent from javascript client side and current php date time zone is greater than 5 minutes or not .
You should use timestamp comparison.
JS:
var timestamp = (new Date()).getTime(); // send this to your php
PHP:
$timestampFromJs = intval($_GET["ts"]); // just made it up
$ts = time() * 1000; // js timestamp is milliseconds
if($ts - $timestampFromJs > 5000*60) ...
UPDATE: If you need timezone safe comparison:
JS:
var timestamp = (new Date()).getTime();
PHP:
$timestampFromJs = intval($_GET["ts"]); // just made it up
$date_utc = new \DateTime("now", new \DateTimeZone("UTC"));
$ts = $date_utc->getTimestamp() * 1000; // js timestamp is milliseconds
if($ts - $timestampFromJs > 5000*60) ...

time zone api INVALID_REQUEST

I can't seem to find what is causing this. I checked the url again and again and I can't seem to find what is wrong with it.
function setTime() {
min = $("#minutes").val();
hour = $("select").val();
odG = $("#odGodina").val();
doG = $("#doGodina").val();
dat = $("#datepicker").val();
dat = dat.split("/"); //mm.dd.YYYY
vreme = new Date(dat[2], dat[0], dat[1], hour, min);
sendInput(vreme);
}
function sendInput(time) {
console.log(time.getTime());
var url = "https://maps.googleapis.com/maps/api/timezone/json?location="+lat+","+lngt+"&timestamp="+time.getTime()+"&sensor=false";
var testResenje = $.ajax({
url: url,
}).done(function(response) {
offset = response.rawOffset / 3600 + response.dstOffset / 3600;
sendResponse();
console.log(offset);
});}
The url that gets build is:
https://maps.googleapis.com/maps/api/timezone/json?location=44.7220401,21.175114500000063&timestamp=1455189900000&sensor=false
Is there a problem with the number of characters long and lat have?
Or is my function order bad?
EDIT: Turns out if i have one less character in timestamp it works. Does that mean I can't use current time?
Google timezoneapi expects timestamp as seconds as how unix timestamp represents not milliseconds.
timestamp specifies the desired time as seconds since midnight, January 1, 1970 UTC.
ref: https://developers.google.com/maps/documentation/timezone/intro.

Setting timezone for running clock in JavaScript

Good days guys. I have this nice and clean code for a running clock.
<script type="text/javascript">
function DisplayTime(){
if (!document.all && !document.getElementById)
return
timeElement=document.getElementById? document.getElementById("curTime"): document.all.tick2
var CurrentDate=new Date()
var hours=CurrentDate.getHours()
var minutes=CurrentDate.getMinutes()
var seconds=CurrentDate.getSeconds()
var DayNight="PM"
if (hours<12) DayNight="AM";
if (hours>12) hours=hours-12;
if (hours==0) hours=12;
if (minutes<=9) minutes="0"+minutes;
if (seconds<=9) seconds="0"+seconds;
var currentTime=hours+":"+minutes+":"+seconds+" "+DayNight;
timeElement.innerHTML="<font style='font-family:Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&subset=latin,cyrillic-ext,latin-extfont-size:14px;color:#fff;'>"+currentTime+"</b>"
setTimeout("DisplayTime()",1000)
}
window.onload=DisplayTime
</script>
My only problem is it's based the system time. How can I set the timezone so that it will display the correct time based on the timezone specified?
There's nothing built into the JavaScript Date object that handles any timezones other than local (system) time and UTC.
You can do it by giving your Date instance the wrong time, using the delta between one of those timezones (local or UTC) and the time zone you want to use. It's easier if you use UTC.
So for instance, say we want our time in GMT+01:00:
var dt = new Date();
dt.setTime(dt.getTime() + (60 * 60 * 1000));
// ^^^^^^^^^^^^^^---- one hour in milliseconds,
// which is our offset from UTC/GMT
var hours = dt.getUTCHours(); // Use UTC methods to get time
var minutes = dt.getUTCMinutes();
var seconds = dt.getUTCSeconds();
Time stuff, particularly with timezones, is hard. You might look at using a library for it, although for just this sort of clock that would be overkill. One good library is MomentJS (which has a timezone add-on).
You can use getTimezoneOffset method of the Date object. It gives you the timezone offset, according to your timezone in minutes.
So in order to get the current time in UTC (+0 timezone) you can do something of the sort:
var tzOffset = CurrentDate.getTimezoneOffset();
// some timezones are not set hours, so we must calculate the minutes
var minutesOffset = parseInt(tzOffset%60,10);
// the offset hours for the timezone
var hoursOffset = parseInt(tzOffset/60, 10);
Then you need to do some math in your code to account for the offset:
var hours = CurrentDate.getHours() + hoursOffset;
var minutes = CurrentDate.getMinutes() + minutesOffset;
This would account for your timezone. If you want to calculate another timezone, that you specify, change the tzOffset above to show your timezone.
var tzOffset = CurrentDate.getTimezoneOffset() + TIMEZONE_HOURS*60;
TIMEZONE_HOURS is the timezone in hours you want, e.g. if you want UTC+3, you must set TIMEZONE_HOURS to 3.
As a whole timezones are a bit complicated task because they change a lot and there are some caveats with them. If you want to dwell more into this, check this answer in another question on SO
I have implemented your working code by adding one more function to obtain what you want. See this will help
function DisplayTime(timeZoneOffsetminutes){
if (!document.all && !document.getElementById)
return
timeElement=document.getElementById? document.getElementById("curTime"): document.all.tick2
var requiredDate=getTimeZoneTimeObj(timeZoneOffsetminutes)
var hours=requiredDate.h;
var minutes=requiredDate.m;
var seconds=requiredDate.s;
var DayNight="PM";
if (hours<12) DayNight="AM";
if (hours>12) hours=hours-12;
if (hours==0) hours=12;
if (minutes<=9) minutes="0"+minutes;
if (seconds<=9) seconds="0"+seconds;
var currentTime=hours+":"+minutes+":"+seconds+" "+DayNight;
timeElement.innerHTML="<font style='font-family:Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800&subset=latin,cyrillic-ext,latin-extfont-size:14px;color:#fff;'>"+currentTime+"</b>"
setTimeout("DisplayTime(-330)",1000)
}
window.onload=DisplayTime(-330);
function getTimeZoneTimeObj(timeZoneOffsetminutes){
var localdate = new Date()
var timeZoneDate = new Date(localdate.getTime() + ((localdate.getTimezoneOffset()- timeZoneOffsetminutes)*60*1000));
return {'h':timeZoneDate.getHours(),'m':timeZoneDate.getMinutes(),'s':timeZoneDate.getSeconds()};
}
#curTime{
background-color:#000;
}
<div id="curTime"></div>
visit this link as a reference
example:
var x = new Date();
var currentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
You can try using moment.js
It is very nice library which handles timezones too.

JQuery Countdown + Server Sync with AppEngine

I'm trying to use jquery countdown to sync with the server so the time is the same for all visitors. The files are being hosted on AppEngine using the static settings to host the HTML. PHP doesn't work on AppEngine.
Would it be possible to sync with the server time using Python under AppEngine's static settings? - how would I use datetime.now() in Jquery?
function countdown() {
var eventTime = new Date('May 23, 2012 08:00:00');
$('#time-left').countdown({ until: eventTime, layout: '<ul class="timer"><li class="days">{dn}</li> <li class="hours">{hnn}</li><li class="mins">{mnn}</li><li class="secs">{snn}</li></ul>',
serverSync: function() { return new Date('datetime.now()') }});
}
Thanks for your help.
its difficult to calculate time in client side because its vary in different time zones.... so get the server time in UTC and create a local time variable in UTC offset, then compare sec deff in local time
// return string must be in UTC time yyyy/MM/dd H:mm:ss format in Json result
$.get("timerequestmethod", function (data) {
var dateArray = data.split(' ');
var seconds = getSeconds(dateArray);
// create countdown until 'seconds' declare in above statement
});
getSeconds = (function (dateArray) {
var dt = dateArray[0].split('/');
var tm = dateArray[1].split(':');
var times = new Date();
times.setUTCFullYear(dt[0], (dt[1] > 0 ? dt[1] - 1 : dt[1]), dt[2]);
times.setUTCHours(tm[0]);
times.setUTCMinutes(tm[1]);
times.setUTCSeconds(tm[2]);
return (times - new Date()) / 1000;
});

Categories

Resources