PHP Time to Javascript Clock - javascript

I want to simply just pull the time from the server.
And continue it ticking with javascript.
My PHP.
//Get current UNIX timestamp (no offset, just straight timestamp)
$time = time()*1000;
//Get offset of server time
$offset = date('O');
// Convert into a new timestamp based on the timezone
$newtime = $time+$offset;
// a vardump($newtime) here gives me
// 1415169764400
My Javascript...
$(document).ready(function(){
// Here Im putting the server time into a variable
var serverTime = "<?php echo $newtime;?>";
//console.log(serverTime) gives me 1415169764400
// Local computer time into a variable
var localTime = new Date().getTime();
//console.log(localTime) here gives me 1415170692954
// Offset between the computer and the server
var timeDiff = serverTime - localTime;
// console.log(timeDiff) here gives me -928554
//The ticking clock function
setInterval(function () {
// Set clock to Computer time plus the time difference
var today = new Date(Date.now()+timeDiff);
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();
m = checkTime(m); //checktime() is just a leading zero function
s = checkTime(s); // checktime() is just a leading zero function
var formatted = h+":"+m+":"+s;
$('.serverTime').html(formatted);
}, 2000);
//PROBLEM IS THAT THIS DISPLAYS THE CURRENT TIME ON MY COMPUTER
// NO MATTER WHAT I TRY, IT ALWAYS JUST DISPLAYS THE LOCAL TIME
// No matter what PHP timezone I put.
// The time Diff and server times are working properly.
// Any ideas whats happening!!???
});
I normally would just use the users local computer time, but each server is in a different location, and when they are visiting this page, I want the clock to tick to the server they're currently visiting.

$time is the number of seconds since unix epoch, expressed as milliseconds. $offset is the number of hours difference from GMT*, Eg '-0800'. Your first problem is that you are adding the offset to the timestamp. At most, you are changing the time by 1.4 seconds, where you seem to intend to change the time by hours.
It would be much easier if you use a DateTime object instead. Then you can call .getOffset() which gives you the difference in seconds:
<?php
$date = new DateTime();
// Get offset for UNIX timestamp based on server timezone
$time = $date->getTimestamp();
//Get offset of server time
$offset = $date->getOffset();
// Convert into a new timestamp based on the timezone
$newtime = ($time + $offset) * 1000;
?>
So far, we've been dealing only with UTC dates. Your other problem is that you are using the local date methods to get values out. You should use the UTC versions of these methods.
//Actual ticking clock
setInterval(function () {
var today = new Date(Date.now() + timeDiff);
var h=today.getUTCHours();
var m=today.getUTCMinutes();
var s=today.getUTCSeconds();
m = checkTime(m);
s = checkTime(s);
var formatted = h+":"+m+":"+s;
$('.serverTime').html(formatted);
}, 2000);
Here's the whole thing, with simulated server time:
function simulateServerTime() {
var time = new Date();
// Add 1 minute and 12 seconds to simulate the clocks being a little out of sync
time.setMinutes(time.getMinutes() + 1, 12);
// Reduce to seconds to simulate php
time = Math.round(time / 1000);
// Specify an offset of -6 hours
var offset = -6 * 60 * 60;
return (time + offset) * 1000;
}
var serverTime = simulateServerTime();
var localTime = new Date();
// Offset between the computer and the server
var timeDiff = serverTime - localTime;
// The ticking clock function
setInterval(function () {
var today = new Date(Date.now() + timeDiff);
var h=today.getUTCHours();
var m=today.getUTCMinutes();
var s=today.getUTCSeconds();
m = checkTime(m);
s = checkTime(s);
var formatted = h+":"+m+":"+s;
document.querySelector(".serverTime").innerHTML = formatted;
}, 1000);
// Helper function for leading 0's
function checkTime(i) {
if (i<10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
<div class="serverTime"></div>
*Or, so says the documentation. Last week, my machine said -0700, which is the octal representation of -448. My time is neither 700 hours earlier than GMT, nor is it 448 hours earlier than GMT, it's 7 hours earlier. It annoys me that the documentation states that it is the time offset in hours, when really it's the time offset in ISO 8601 Format.

Timestamp is not include timezone offset. Everyone's unix time is a offset from Jan 1, 1970 in UTC
If you wish to display a server timezone in client, your PHP must provide a server timezone. And about client timezone, you can reference this .
Also, I like to using moment.js to handle date/time problems.
I just modified the client side javascript, using moment. Wish it's all you needed
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
<?php
date_default_timezone_set("Europe/Athens");
$serverTime = time() * 1000 ;
$timezone = date('O');
?>
<div id="result"></div>
<script>
var serverTime = <?php echo $serverTime;?>,
timezone = "<?php echo $timezone;?>",
timeDiff = serverTime - Date.now();
setInterval(function () {
result.innerHTML= moment().add(timeDiff).zone(timezone).format('HH:mm:ss Z') + "<br/>" + result.innerHTML ;
}, 2000);
</script>

Related

Javascript function to calculate the hours remaining to specific date or time

I need to count the remaining time in hours between today or actual date/time and a specific end date at 00:00 hrs.
I tried in this fiddle, but I get the counting of one month more than it should be.
https://jsfiddle.net/alonsoct/52ts89mz/
var endTime = new Date(2019,10,18,0,0,0) / 1000;
function setClock() {
var elapsed = new Date() / 1000;
var totalTime = endTime - elapsed;
var hr = parseInt(totalTime / 3600)
var min = parseInt(totalTime / 60) % 60;
var sec = parseInt(totalTime % 60, 10);
var result = hr + " hours, " + min + " minutes " + sec + " seconds";
document.getElementById('timeRemaining').innerHTML = result;
setTimeout(setClock, 1000);
}
setClock();
If I enter one month less in the "endTime" variable I get the correct result in hours count, but this is not fine I need to enter the real end date without the need to subtract one month.
Thanks
The code below is mostly your code with one change. I changed the input for endTime to an ISO format and omitted the time Zone. This, in theory, will default to your browser's timezone. I tested on your linked and it worked. Here is some additional information https://www.w3schools.com/js/js_date_formats.asp
var endTime = new Date("2019-10-18T00:00:00") / 1000;
function setClock() {
var elapsed = new Date() / 1000;
var totalSec = endTime - elapsed;
var h = parseInt( totalSec / 3600 )
var m = parseInt( totalSec / 60 ) % 60;
var s = parseInt(totalSec % 60, 10);
var result = h + " hours, " + m + " minutes " + s + " seconds";
document.getElementById('timeRemaining').innerHTML = result;
setTimeout(setClock, 1000);
}
setClock();
Here is a working solution with Vanilla JS:
var calcTime = setInterval(function(){
date_future = new Date(2019,10,18,0,0,0)
date_now = new Date();
seconds = Math.floor((date_future - (date_now))/1000);
minutes = Math.floor(seconds/60);
hours = Math.floor(minutes/60);
days = Math.floor(hours/24);
hours = hours-(days*24);
minutes = minutes-(days*24*60)-(hours*60);
seconds = seconds-(days*24*60*60)-(hours*60*60)-(minutes*60);
It's pretty easier with JQuery → http://hilios.github.io/jQuery.countdown/examples/show-total-hours.html
JavaScript counts months from 0 to 11.
January is 0. December is 11.
I think you were thinking that endTime will be October 18th, 2019 but actually it's November 18th, 2019.
You can see more relevant information here.
https://www.w3schools.com/js/js_dates.asp
Thanks.
If between the start-datetime and end-datetime a change takes place in winter / summertime remember to make summertime/wintertime adjustments
(if you get these values from e.g. an api:) if the startdate is specified by a client in location x and enddate is specified in location y, you have take into account that the startdate could potentially be in 00:00:00+14:00 timezone and end the endate in max -14 timezone.
if you only present 2 timeboxes: time 1 and time 2, you can map these anywhere on a 52 hours time-scale: -14 , +14 and the 24 hours gmt timescale where you then would normalize to. ( 0:00 could mean i am in Samoa +14, 14 hours ahead of the end of GMT 23:59:59 (14 further) or ahead of GMT 0:00 (14+24 further). Then there are countries which make local time decisions e.g. in India with +5.5 UTC or Burma +6.5 or newfoundland -3.5.
Since this is stackexchange and people will copy and paste these examples in their applications even if these applications are "on the internet" and so DO have users from every location in the world.
Therefore ... use a library: https://momentjs.com/ ; Get hours difference between two dates in Moment Js they have a helper https://momentjs.com/docs/#/displaying/to/ and see also: Moment.js - How To Detect Daylight Savings Time And Add One Day
You can see the same bug on https://www.timeanddate.com/countdown but they added in words : https://www.timeanddate.com/countdown/one-hour-offwintertijd (and they assume the end datetime is in the same location as the countdown datetime)

Javascript's date object toLocaleTimeString adds an hour

I'm trying to create a timer from when the user clicks a button.
To do this I tried to calculate the difference between two date objects. When I output the difference, it works. However thetoLocaleTimeString call returns a string with an extra hour added:
var start;
var timer;
function myTimer() {
var current = new Date();
var difference = new Date(current - start);
console.log(difference.getTime(), difference.toLocaleTimeString(navigator.language));
document.getElementById("timer").innerHTML = difference;
document.getElementById("timer2").innerHTML = difference.toLocaleTimeString('en-GB');
}
start = new Date();
timer = setInterval(myTimer, 1000);
draw();
<h1 id="timer"></h1>
<h1 id="timer2"></h1>
What am I doing wrong?
Specify the time zone as UTC in the options argument. Otherwise, the difference date will be adjusted to the user agent's time zone.
document.getElementById("timer2").innerHTML = difference.toLocaleTimeString('en-GB', { timeZone: 'UTC' });
Read more on the options argument and toLocaleTimeString in the MDN documentation.
var start;
var timer;
function myTimer() {
var current = new Date();
var difference = new Date(current - start);
console.log(difference.getTime(), difference.toLocaleTimeString(navigator.language));
document.getElementById("timer").innerHTML = difference;
document.getElementById("timer2").innerHTML = difference.toLocaleTimeString(navigator.language, { timeZone: 'UTC', hour12: false });
}
start = new Date();
timer = setInterval(myTimer, 1000);
draw();
<h1 id="timer"></h1>
<h1 id="timer2"></h1>
Because of the problems with JS and timezones, you are better of using something like moment.js's timezone (http://momentjs.com/timezone/) to do correct conversions (that keep in mind the shift of BST, GMT, differences between countries, etc..). For the purpose of your timer, the following would work as well, and is more accurate as well as simpler to reason about:
// Use Date.now() to get the time in milliseconds for this local computer
var start = Date.now();
var time = new Date();
// This function will prepend a 0 to a number lower than 10
function prependZero(v){
if(v < 9) return '0' + v;
else return v;
}
var timer = setInterval(function() {
// Calculate the difference using the computers local time strings
var difference = new Date(Date.now() - start);
document.getElementById("timer").innerHTML = new Date();
// Now use the Date mnethods to get the correct output:
document.getElementById("timer2").innerHTML = prependZero(difference.getHours()) + ':' + prependZero(difference.getMinutes()) + ':' + prependZero(difference.getSeconds());
}, 1000);
<h1 id="timer"></h1>
<h1 id="timer2"></h1>

Show JavaScript date - datetimeoffset(7) in database

The date is stored in the database as datetimeoffset(7).
The MVC controller gets the date from the database in the format "10/8/2015 6:05:12 PM -07:00" and passes it to the view as it is. I am trying to convert it to the correct date to show that in the view as mm/dd/yyy by doing the following:
var myDate = "10/8/2015 6:05:12 PM -07:00";
var newDate = New Date(myDate);
Then I'm formatting it to mm/dd/yyyy format after extracting the day, month and year.
IE11 and Safari do not like this and show error "Invalid date" in the console at the line
var newDate = New Date(myDate)
Chrome or Firefox doesn't show any problems.
Now I know that "10/8/2015 6:05:12 PM -07:00" is not a valid datestring. So my question is, how to handle this situation so all major browsers will show the correct date?
This function should work, I'm aware it needs some refactoring but it may be a good starting point.
function readDate(inputDate) {
// extract the date that can be parsed by IE ("10/8/2015 6:05:12 PM")
// and the timezone offset "-07:00"
var parsedDate = /([\s\S]*?)\s*([+-][0-9\:]+)$/.exec(inputDate);
//create new date with "datetimeoffset" string
var dt = new Date(parsedDate[1]);
// get millisecs
var localTime = dt.getTime();
// get the offset in millisecs
// notice the conversion to milliseconds
// the variable "localTzOffset" can be negative
// because the standar (http://www.w3.org/TR/NOTE-datetime)
var localTzOffset = dt.getTimezoneOffset() * 60 * 1000;
// to get UTC time
var utcTime = localTime + localTzOffset;
// extract hours and minutes difference
// for given timezone
var parsed = /([+-][0-9]+)\:([0-9]+)/.exec(parsedDate[2]);
var hours = parseInt(parsed[1]);
var minutes = parseInt(parsed[2]);
// convert extracted difference to milliseconds
var tzOffset = Math.abs(hours * 60 * 60 * 1000) + (minutes * 60 * 1000);
// taking into accout if negative
tzOffset = hours > 1 ? tzOffset : tzOffset * -1;
// construct the result Date
return new Date(utcTime + tzOffset);
}
Usage:
var date = readDate("10/8/2015 6:05:12 PM -07:00");

Get date time for a specific time zone using JavaScript

It seems that JavaScript's Date() function can only return local date and time. Is there anyway to get time for a specific time zone, e.g., GMT-9?
Combining #​Esailija and #D3mon-1stVFW, I figured it out: you need to have two time zone offset, one for local time and one for destination time, here is the working code:
var today = new Date();
var localoffset = -(today.getTimezoneOffset()/60);
var destoffset = -4;
var offset = destoffset-localoffset;
var d = new Date( new Date().getTime() + offset * 3600 * 1000)
An example is here: http://jsfiddle.net/BBzyN/3/
var offset = -8;
new Date( new Date().getTime() + offset * 3600 * 1000).toUTCString().replace( / GMT$/, "" )
"Wed, 20 Jun 2012 08:55:20"
<script>
var offset = -8;
document.write(
new Date(
new Date().getTime() + offset * 3600 * 1000
).toUTCString().replace( / GMT$/, "" )
);
</script>
You can do this in one line:
let d = new Date(new Date().toLocaleString("en-US", {timeZone: "timezone id"})); // timezone ex: Asia/Jerusalem
var today = new Date();
var offset = -(today.getTimezoneOffset()/60);
You can always get GMT time (so long as the client's clock is correct).
To display a date in an arbitrary time-zone, construct a string from the UTC hours, minutes, and seconds after adding the offset.
There is simple library for working on timezones easily called TimezoneJS can be found at https://github.com/mde/timezone-js.

How can I get seconds since epoch in Javascript?

On Unix, I can run date '+%s' to get the amount of seconds since epoch. But I need to query that in a browser front-end, not back-end.
Is there a way to find out seconds since Epoch in JavaScript?
var seconds = new Date() / 1000;
Or, for a less hacky version:
var d = new Date();
var seconds = d.getTime() / 1000;
Don't forget to Math.floor() or Math.round() to round to nearest whole number or you might get a very odd decimal that you don't want:
var d = new Date();
var seconds = Math.round(d.getTime() / 1000);
Try this:
new Date().getTime() / 1000
You might want to use Math.floor() or Math.round() to cut milliseconds fraction.
You wanted seconds since epoch
function seconds_since_epoch(){ return Math.floor( Date.now() / 1000 ) }
example use
foo = seconds_since_epoch();
The above solutions use instance properties. Another way is to use the class property Date.now:
var time_in_millis = Date.now();
var time_in_seconds = time_in_millis / 1000;
If you want time_in_seconds to be an integer you have 2 options:
a. If you want to be consistent with C style truncation:
time_in_seconds_int = time_in_seconds >= 0 ?
Math.floor(time_in_seconds) : Math.ceil(time_in_seconds);
b. If you want to just have the mathematical definition of integer division to hold, just take the floor. (Python's integer division does this).
time_in_seconds_int = Math.floor(time_in_seconds);
If you want only seconds as a whole number without the decimals representing milliseconds still attached, use this:
var seconds = Math.floor(new Date() / 1000);
You can create a Date object (which will have the current time in it) and then call getTime() to get the ms since epoch.
var ms = new Date().getTime();
If you want seconds, then divide it by 1000:
var sec = new Date().getTime() / 1000;
My preferred way:
var msEpoch = (+new Date());
var sEpoch = (+new Date()) / 1000;
For more information on the + jump down the rabbit hole.
The most simple version:
Math.floor(Date.now() / 1000)
EPOCH means time from 01 January 1970
var date = new Date();
Following line will return the number of milliseconds from 01 Jaunary 1970
var ms = date.getTime();
Following line will convert milliseconds to seconds
var seconds = Math.floor(ms/1000);
console.log("Seconds since epoch =",seconds);
In chrome you can open the console with F12 and test the following code:
var date = new Date().getTime()
console.debug('date: ' + date);
if (Date.now() < date)
console.debug('ko');
else
console.debug('ok');
https://www.eovao.com/en/a/javascript%20date/1/how-to-obtain-current-date-in-milliseconds-by-javascript-(epoch)

Categories

Resources