tags:

views:

870

answers:

7

How can i get the current time? (in JavaScript)

Not the time of your computer like:

now = new Date;
now_string = addZero(now.getHours()) + ":" + addZero(now.getMinutes()) + ":" + addZero(now.getSeconds());

But the real accurate world time?

Do i need to connect to to a server (most likely yes, which one? and how can i retrieve time from it?)

All the searches I do from google return the (new Date).getHours().

Edit:

I want to avoid showing an incorrect time if the user has a wrong time in his computer.

A: 

You can use the toGMTString method.

var d = new Date();
alert(d.toGMTString()); // Will give you: Wed, 28 Jan 2009 22:05:04 GMT

You can also get the current time offset:

var gmtHours = d.getTimezoneOffset()/60;
alert("The local time zone is: GMT " + gmtHours);
CMS
But that still gives local computer time
fmsf
Exactly, because JavaScript code is executed on the client browser. You will need to get the date from the server side, you can do it through AJAX, can you give some info of what are you using on the server side?
CMS
I'm using nothing! I have access to php though and mysql on the server. although last time i've coded it was 4 years ago and i remember nothing :(
fmsf
A: 

You could use getTimezoneOffset to get the offset between the local date and the GMT one, and then do the math. But this will only be as accurate as the user's clock.

If you want an accurate time, you should connect to a NTP server. Because of the Same Origin Policy, you can't make a request with JS to another server then yours. I'd suggest you to create a server-side script that connects to the NTP server (in PHP, or whatever language you want) and return the accurate date. Then, use an AJAX request to read this time.

Wookai
+5  A: 

First, to get the accurate GMT time you need a source that you trust. This means some server somewhere. Javascript can generally only make HTTP calls, and only to the server hosting the page in question (same origin policy). Thus that server has to be your source for GMT time.

I would configure your webserver to use NTP to synchronize its clock with GMT, and have the webserver tell the script what time it is, by writing a variable to the page. Or else make and XmlHttpRequest back to the server when you need to know the time. The downside is that this will be inaccurate due to the latency involved: the server determines the time, writes it to the response, the response travels over the network, and the javascript executes whenever the client's cpu gives it a timeslice, etc. On a slow link you can expect seconds of delay if the page is big. You might be able to save some time by determining how far off from GMT the user's clock is, and just adjusting all the time calculations by that offset. Of course if the user's clock is slow or fast (not just late or early) or if the user changes the time on their PC then your offset is blown.

Also keep in mind that the client can change the data so don't trust any timestamps they send you.

Edit: JimmyP's answer is very simple and easy to use: use Javascript to add a <script> element which calls a url such as http://json-time.appspot.com/time.json?tz=GMT. This is easier than doing this yourself because the json-time.appspot.com server works as a source of GMT time, and provides this data in a way that lets you work around the same-origin policy. I would recommend that for simple sites. However it has one major drawback: the json-time.appspot.com site can execute arbitrary code on your user's pages. This means that if the operators of that site want to profile your users, or hijack their data, they can do that trivially. Even if you trust the operators you need to also trust that they have not been hacked or compromised. For a business site or any site with high reliability concerns I'd recommend hosting the time solution yourself.

Edit 2: JimmyP's answer has a comment which suggests that the json-time app has some limitations in terms of the number of requests it can support. This means if you need reliability you should host the time server yourself. However, it should be easy enough to add a page on your server which responds with the same format of data. Basically your server takes a query such as

http://json-time.appspot.com/time.json?tz=America/Chicago&amp;callback=foo

and returns a string such as

foo({
 "tz": "America\/Chicago", 
 "hour": 15, 
 "datetime": "Thu, 09 Apr 2009 15:07:01 -0500", 
 "second": 1, 
 "error": false, 
 "minute": 7
})

Note the foo() which wraps the JSON object; this corresponds to the callback=foo in the query. This means when the script is loaded into the page it will call your foo function, which can do whatever it wants with the time. Server-side programming for this example is a separate question.

Mr. Shiny and New
usefull teory (not joking, nor hinorising) :) but how do i do that? me == noob in javascript
fmsf
an example or tutorial link will be great, and with that answer you'll get correct answer for this question :)
fmsf
@fmsf: since you are a noob, you're probably better off using JimmyP's answer. My answer involves programming on the server and giving a code sample is not trivial.
Mr. Shiny and New
+6  A: 

You can use JSON[P] and access a time API:

(The code below should work perfectly, just tested it...)

function getTime(zone, success) {
    var url = 'http://json-time.appspot.com/time.json?tz=' + zone,
        ud = 'json' + (+new Date());
    window[ud]= function(o){
        success && success(new Date(o.datetime));
    };
    document.getElementsByTagName('head')[0].appendChild((function(){
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = url + '&callback=' + ud;
        return s;
    })());
}

getTime('GMT', function(time){
    // This is where you do whatever you want with the time:
    alert(time);
});
J-P
Nice. Self contained. Terse.
Crescent Fresh
Wow, that's far simpler than my answer. But the downside is that you have to trust this site fully, or else they are running arbitrary code on your pages.
Mr. Shiny and New
You're right Mr Shiny... I think this API is quite trustworthy, it's hosted by Google and was created by Simon Willison (the guy who co-created Django) :)
J-P
+2 if it were possible.
Jason S
JasonS, I plussed again for you :)
benc
The API works okay, but tonight it's down because it has exceed Google's quota for the day. The quota for free AppEngine accounts is only 1.3 million requests daily.
Matt Miller
+1  A: 

Like Mr. Shiny and New said, you need a server somewhere with correct time. It can be the server where you site are or some other server that sends the correct time in a format that you can read.

If you want to use the date several times on your page, one or more seconds apart, you probably don't want to get the time from the server every time, but instead cache the difference and use the clients clock. If that is the case, here is one of many solutions:

var MyDate = new function() {
    this.offset = 0;
    this.calibrate = function (UTC_msec) {
        //Ignore if not a finite number
        if (!isFinite(UTC_msec)) return;

        // Calculate the difference between client and provided time
        this.offset = UTC_msec - new Date().valueOf();

        //If the difference is less than 60 sec, use the clients clock as is.
        if (Math.abs(this.offset) < 60000) this.offset = 0;
    }
    this.now = function () {
        var time = new Date();
        time.setTime(this.offset + time.getTime());
        return time;
    }
}();

Include it on your page and let your server side script produce a row like:

MyDate.calibrate(1233189138181);

where the number is the current time in milliseconds since 1 Jan 1970. You can also use your favorite framework for AJAX and have it call the function above. Or you can use the solution JimmyP suggested. I have rewritten JimmyPs solution to be included in my solution. Just copy and paste the following inside the function above:

    this.calibrate_json = function (data) {
        if (typeof data === "object") {
            this.calibrate (new Date(data.datetime).valueOf() );
        } else {
            var script = document.createElement("script");
            script.type="text/javascript";
            script.src=(data||"http://json-time.appspot.com/time.json?tz=UTC") +
                "&callback=MyDate.calibrate_json";
            document.getElementsByTagName('head')[0].appendChild(script);
        }
    }
    this.calibrate_json(); //request calibration with json

Notice that if you change the name of the function from MyDate you have to update the callback in *this.calibrate_json* on the line script.src.

Explanation:

Mydate.offset is the current offset between the server time and the clients clock in milliseconds.

Mydate.calibrate( x ); is a function that sets a new offset. It expects the input to be the current time in milliseconds since 1 Jan 1970. If the difference between the server and client clock is less than 60 seconds, the clients clock will be used.

Mydate.now() is a function that returns a date object that has the current calibrated time.

*Mydate.calibrate_json( data )* is a function that either takes an url to a resource that gives back a datetime reply, or an object with the current time (used as a callback). If nothing is supplied, it will use a default url to get the time. The url must have a question mark "?" in it.

Simple example of how to update an element with the current time every second:

setInterval(
    function () {
        var element = document.getElementById("time");
        if (!element) return;
        function lz(v) {
            return v < 10 ? "0" + v : v;
        }
        var time = MyDate.now();
        element.innerHTML = time.getFullYear() + "-" +
            lz(time.getMonth() + 1) + "-" +
            lz(time.getDate()) + " " +
            lz(time.getHours()) + ":" +
            lz(time.getMinutes()) + ":" +
            lz(time.getSeconds())
        ;
},1000);
some
A: 

Why don't you send the time with every page? For example somewhere in the html:

<span id="time" style="display:none;">
    2009-03-03T23:32:12
</span>

Then you could run a Javascript while the site loads and interpret the date. This would reduce the amount of work the network has to do. You can store the corresponding local time and calculate the offset every time you need it.

Georg
A: 

We've used an API from EarthTools with much success:

EarthTools

The service returns XML with information such as the current GMT & timezone offsets (when supplying a latitude & longitude). We used a WebClient in conjunction with an XMLDocument in the VB backend of our ASP.NET page to read & interpret the XML.

Kyle