Получение текущего мирового времени по Гринвичу

Как я могу получить текущее время? (в JavaScript)

Не время вашего компьютера:

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

Но настоящее точное мировое время?

Нужно ли подключаться к серверу (скорее всего, да, какой? и как я могу извлечь из него время?)

Все поисковые запросы, которые я делаю из google, возвращают (new Date).getHours().

Edit:

Я хочу, чтобы не показывать неправильное время, если у пользователя есть неправильное время на своем компьютере.

Ответ 1

Во-первых, чтобы получить точное время GMT, вам нужен источник, которому вы доверяете. Это означает какой-то сервер где-то. Javascript обычно может выполнять только HTTP-вызовы и только на сервере, на котором размещена данная страница (такая же политика происхождения). Таким образом, сервер должен быть вашим источником для GMT.

Я бы сконфигурировал ваш веб-сервер для использования NTP для синхронизации своих часов с GMT, и веб-сервер сообщит script, в какое время он, написав переменную на странице. Или еще создайте и XmlHttpRequest обратно на сервер, когда вам нужно знать время. Недостатком является то, что это будет неточно из-за задержек: сервер определяет время, записывает его в ответ, ответ проходит по сети, а javascript выполняется всякий раз, когда клиентский процессор дает ему таймлис и т.д. На медленная ссылка, вы можете ожидать секунд задержки, если страница большая. Вы могли бы сэкономить некоторое время, указав, как далеко от GMT пользовательские часы, и просто корректировать все расчеты времени с помощью этого смещения. Конечно, если часы пользователя медленные или быстрые (не только поздние или ранние), либо если пользователь меняет время на своем ПК, тогда ваше смещение вылетает.

Также имейте в виду, что клиент может изменять данные, поэтому не доверяйте никаким отметкам времени, которые они отправляют вам.

Edit: Ответ JimmyP очень прост и прост в использовании: используйте Javascript для добавления элемента <script>, который вызывает URL-адрес, например http://json-time.appspot.com/time.json?tz=GMT. Это проще, чем делать это самостоятельно, потому что сервер json-time.appspot.com работает как источник времени по Гринвичу и предоставляет эти данные таким образом, чтобы вы могли работать с политикой одного и того же происхождения. Я бы рекомендовал это для простых сайтов. Однако у него есть один главный недостаток: сайт json-time.appspot.com может выполнять произвольный код на ваших пользовательских страницах. Это означает, что если операторы этого сайта хотят профилировать своих пользователей или захватить их данные, они могут сделать это тривиально. Даже если вы доверяете операторам, вам также нужно верить, что они не были взломаны или скомпрометированы. Для бизнес-сайта или любого сайта с высокой степенью надежности я бы рекомендовал разместить решение времени самостоятельно.

Изменить 2: Ответ JimmyP содержит комментарий, который говорит о том, что приложение json-time имеет некоторые ограничения в отношении количества запросов, которые он может поддерживать. Это означает, что если вам нужна надежность, вы должны разместить сервер времени самостоятельно. Однако достаточно просто добавить страницу на своем сервере, которая отвечает тем же самым форматом данных. В основном ваш сервер принимает такой запрос, как

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

и возвращает строку, такую ​​как

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

Обратите внимание на foo(), который обертывает объект JSON; это соответствует обратному запросу = foo в запросе. Это означает, что при загрузке script на страницу он будет вызывать вашу функцию foo, которая может делать все, что захочет, со временем. Программирование на стороне сервера для этого примера является отдельным вопросом.

Ответ 2

Вы можете использовать JSON [P] и получить доступ к API времени:

(Код ниже должен работать отлично, просто протестировать его...)

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);
});

Ответ 3

Почему вы не отправляете время на каждую страницу? Например, где-то в html:

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

Затем вы можете запустить Javascript, пока сайт загружает и интерпретирует дату. Это уменьшит объем работы, которую должна выполнять сеть. Вы можете сохранить соответствующее местное время и рассчитать смещение каждый раз, когда вам это нужно.

Ответ 4

Вы можете использовать getTimezoneOffset, чтобы получить смещение между локальной датой и GMT, а затем выполнить математику. Но это будет так же точно, как часы пользователя.

Если вам нужно точное время, вы должны подключиться к серверу NTP. Из-за Same Origin Policy вы не можете сделать запрос с JS на другой сервер, а затем ваш. Я предлагаю вам создать серверную часть script, которая подключается к серверу NTP (на PHP или любом другом языке) и возвращает точную дату. Затем используйте запрос AJAX, чтобы прочитать это время.

Ответ 5

Небольшое дополнение к Mr. Shiny и New и Джеймс отвечает

Вот PHP script, который вы можете разместить на собственном сервере и использовать вместо json-time.appspot.com

<?php
header('Content-Type: application/json');
header("Expires: Tue, 01 Jan 1990 00:00:00 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

$error = "false";
$tz = $_GET['tz'];

if ( !in_array($tz, DateTimeZone::listIdentifiers())) {
   $error = 'invalid time zone';
   $tz = 'UTC';
}

date_default_timezone_set($tz);

?>
<?php echo htmlspecialchars($_GET['callback'], ENT_QUOTES, 'UTF-8' ); ?>({
 "tz": "<?php echo $tz ?>",
 "hour": <?php echo date('G'); ?>,
 "datetime": "<?php echo date(DATE_RFC2822); ?>",
 "second": <?php echo intval(date('s')); ?>,
 "error": "<?php echo $error; ?>",
 "minute": <?php echo intval(date('i')); ?>
})

Ответ 6

Как Mr. Shiny и New, вам нужен сервер где-то с правильным временем. Это может быть сервер, на котором вы находитесь, или какой-либо другой сервер, который отправляет правильное время в формате, который вы можете прочитать.

Если вы хотите использовать эту дату несколько раз на своей странице, на расстоянии одной или нескольких секунд, вы, вероятно, не хотите получать время от сервера каждый раз, но вместо этого сохраняете разницу и используете часы клиентов. Если это так, вот одно из многих решений:

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;
    }
}();

Включите его на свою страницу и позвольте серверной стороне script создать строку, например:

MyDate.calibrate(1233189138181);

где число - это текущее время в миллисекундах с 1 января 1970 года. Вы также можете использовать свою любимую фреймворк для AJAX и вызвать функцию выше. Или вы можете использовать решение JimmyP. Я переписал решение JimmyPs для включения в мое решение. Просто скопируйте и вставьте следующее внутри функции выше:

    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

Обратите внимание, что если вы измените имя функции из MyDate, вам необходимо обновить обратный вызов в this.calibrate_json в строке script.src.

Пояснение:

Mydate.offset - это текущее смещение между временем сервера и часами клиентов в миллисекундах.

Mydate.calibrate(x); это функция, которая устанавливает новое смещение. Он ожидает, что вход будет текущим временем в миллисекундах с 1 января 1970 года. Если разница между часами сервера и клиента составляет менее 60 секунд, будут использоваться часы клиентов.

Mydate.now() - это функция, которая возвращает объект даты, который имеет текущее откалиброванное время.

Mydate.calibrate_json (data) - это функция, которая либо берет URL-адрес ресурсу, который возвращает ответ на datetime, либо объект с текущим временем (используется как обратный вызов). Если ничего не предоставляется, он будет использовать URL-адрес по умолчанию, чтобы получить время. У URL должен быть знак вопроса "?" в нем.

Простой пример того, как обновлять элемент с текущим временем в секунду:

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);

Ответ 7

Я наткнулся на другое решение для тех, у кого нет доступа к серверной стороне вещей. Ответ на вопрос Получение времени сервера по умолчанию в jQuery?.

В принципе, вы можете захватить заголовок "Дата", выполнив запрос AJAX HEAD на "/". Не все серверы поддерживают это, и для его работы с конкретным сервером может потребоваться некоторое jiggery-pockery.

Проверьте реальный ответ для более подробной информации.

Ответ 8

Мы использовали API от EarthTools с большим успехом:

EarthTools

Служба возвращает XML с информацией, такой как текущие смещения GMT и временного интервала (при поставке широты и долготы). Мы использовали WebClient в сочетании с XMLDocument в VB-сервере нашей страницы ASP.NET для чтения и интерпретации XML.

Ответ 9

Вы можете сделать это в PHP

<?php
$json = file_get_contents( "http://json-time.appspot.com/time.json?tz=GMT" );
$obj = json_decode($json);
$timenow= $obj->{'datetime'};
$hournow= $obj->{'hour'}; 
$minutenow= $obj->{'minute'}; 
$secondnow= $obj->{'second'}; 
?>

$timenow содержит полную дату и время: "Пн, 05 Мар 2012 01:57:51 +0000", $hournow: "1" $minutenow: "57".

Ответ 10

Поскольку служба, связанная с ответом Джеймса, кажется, больше не работает, я нашел еще один хороший API для отдыха, который можно использовать для этой цели, и он отлично работает. Источником является этот сайт: timeapi, а код, который вы можете использовать, - это просто (с использованием библиотеки jQuery и обратного вызова jsonp, предоставляемого API ):

 $.getJSON("http://www.timeapi.org/utc/now.json?callback=?",function(json){
       //console.log(json)
       alert(json.dateString);
 });

При этом у вас будет дата и час в fomat, например

  September 02, 2016 09:59:42 GMT+0100

Если вы хотите манипулировать им в javascript, чтобы иметь часы, просто преобразуйте его в объект Date следующим образом:

  new Date(json.dateString)

Итак, например, вы можете написать вот так:

   $.getJSON("http://www.timeapi.org/utc/now.json?callback=?",function(json){

         var now = new Date(json.dateString);
         var hours = now.toLocaleTimeString();

         alert(hours)

    });

таким образом вы будете иметь точное местное время в часах.

Ответ 11

Если ваш javascript обслуживается с веб-сервера, вы можете использовать эту простую функцию для запроса времени с этого сервера. Он будет работать, если сервер вернет заголовок даты в ответе HTTP.

function getServerTime()
{
    var req = new XMLHttpRequest();
    req.open('GET', document.location, false);
    req.send(null);
    return new Date(req.getResponseHeader("Date"));
}

В результате кэширования это может привести к неправильному времени. Чтобы исправить это, вы можете использовать произвольный URL-адрес:

req.open('GET', "/time?r=" + Math.floor(Math.random()*10000000), false);