我如何获得当前时间? (在JavaScript中)
不是你电脑的时间:
now = new Date;
now_string = addZero(now.getHours()) + ":" + addZero(now.getMinutes()) + ":" + addZero(now.getSeconds());
但真正准确的世界时间?
我是否需要连接到服务器(很可能是,哪一个?我如何从中检索时间?)
我从谷歌搜索的所有搜索都会返回(new Date).getHours()
。
编辑:
如果用户的计算机时间错误,我希望避免显示错误的时间。
答案 0 :(得分:26)
您可以使用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);
});
答案 1 :(得分:20)
首先,要获得准确的GMT时间,您需要一个您信任的来源。这意味着某处服务器。 Javascript通常只能进行HTTP调用,而且只能访问托管相关页面的服务器(相同的源策略)。因此,该服务器必须是您的GMT时间来源。
我会将您的网络服务器配置为使用NTP将其时钟与GMT同步,并让网络服务器通过向页面写入变量来告诉脚本它的时间。或者,当您需要知道时间时,将make和XmlHttpRequest返回给服务器。缺点是由于所涉及的延迟,这将是不准确的:服务器确定时间,将其写入响应,响应通过网络传播,并且只要客户端的cpu给它一个时间片,javascript就会执行,等等。慢速链接如果页面很大,你可以预期延迟几秒钟。您可以通过确定用户时钟与GMT的距离来节省一些时间,并且只需通过该偏移调整所有时间计算。当然,如果用户的时钟速度很慢或很快(不仅仅是迟到或早期),或者如果用户在PC上更改时间,那么您的偏移量就会被烧毁。
另请注意,客户端可以更改数据,因此不要信任他们发送给您的任何时间戳。
修改强>:
JimmyP's answer非常简单易用:使用Javascript添加<script>
元素,该元素调用诸如http://json-time.appspot.com/time.json?tz=GMT之类的网址。这比自己更容易,因为json-time.appspot.com服务器作为GMT时间的来源,并以允许您解决同源策略的方式提供此数据。对于简单的网站我会建议。但是它有一个主要缺点:json-time.appspot.com站点可以在用户的页面上执行任意代码。这意味着,如果该网站的运营商想要分析您的用户或劫持他们的数据,他们可以做到这一点。即使您信任运营商,您也需要相信他们没有被黑客入侵或受到攻击。对于商业网站或任何具有高可靠性问题的网站,我建议您自己托管时间解决方案。
编辑2 : JimmyP's answer有一条评论表明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
})
注意包装JSON对象的foo()
;这对应于查询中的callback = foo。这意味着当脚本加载到页面中时,它将调用你的foo函数,它可以随时随地执行任何操作。此示例的服务器端编程是一个单独的问题。
答案 2 :(得分:6)
为什么不在每个页面上发送时间?例如html中的某个地方:
<span id="time" style="display:none;">
2009-03-03T23:32:12
</span>
然后,您可以在网站加载并解释日期时运行Javascript。这将减少网络必须完成的工作量。您可以存储相应的本地时间并在每次需要时计算偏移量。
答案 3 :(得分:3)
您可以使用getTimezoneOffset获取本地日期与GMT之间的偏移量,然后进行数学计算。但这只会像用户的时钟一样准确。
如果您想要准确的时间,则应连接到NTP server。由于Same Origin Policy,您无法使用JS向另一台服务器发出请求。我建议你创建一个连接到NTP服务器的服务器端脚本(用PHP或任何你想要的语言)并返回准确的日期。然后,使用AJAX请求来读取此时间。
答案 4 :(得分:3)
Mr. Shiny and New和James答案的一点点补充
这是一个PHP脚本,您可以将其放在自己的服务器上,而不是使用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')); ?>
})
答案 5 :(得分:2)
就像Mr. Shiny and 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;
}
}();
将其包含在您的页面上,让服务器端脚本生成如下行:
MyDate.calibrate(1233189138181);
其中数字是自1970年1月1日以来的当前时间(以毫秒为单位)。您还可以使用自己喜欢的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 更改函数名称,则必须更新 script.src this.calibrate_json 中的回调
说明:
Mydate.offset 是服务器时间和客户端时钟之间的当前偏移量,以毫秒为单位。
Mydate.calibrate(x); 是一个设置新偏移量的函数。它期望输入是自1970年1月1日以来的当前时间(以毫秒为单位)。如果服务器和客户端时钟之间的差异小于60秒,则将使用客户端时钟。
Mydate.now()是一个返回具有当前校准时间的日期对象的函数。
Mydate.calibrate_json(data)是一个函数,它将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);
答案 6 :(得分:2)
我偶然发现了那些无法访问服务器端的人的解决方案。 An answer问题Getting the default server time in jQuery?。
基本上,您可以通过对“/”执行AJAX HEAD请求来获取“Date”标头。并非所有服务器都支持此功能,并且可能需要一些jiggery-pockery才能使其与特定服务器一起使用。
答案 7 :(得分:0)
我们使用了EarthTools的API取得了很大的成功:
该服务返回XML,其中包含当前GMT和&amp ;;时区偏移(提供纬度和经度时)。我们在ASP.NET页面的VB后端使用WebClient和XMLDocument来读取&amp;解释XML。
答案 8 :(得分:0)
您可以在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
包含您的完整日期&amp;时间:“星期一,2012年3月5日01:57:51 +0000”,$hournow
:“1”
$minutenow
:“57”。
答案 9 :(得分:0)
由于与James's答案相关的服务似乎不再起作用,我找到了另一个可以用于此目的的良好的休息API,并且它工作正常。 源代码是这个站点:timeapi,您可以使用的代码就是这样(使用API提供的jQuery库和jsonp回调):
$.getJSON("http://www.timeapi.org/utc/now.json?callback=?",function(json){
//console.log(json)
alert(json.dateString);
});
有了这个,你就会有像
那样的日期和时间 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)
});
以这种方式,您将获得准确的当地时间。
答案 10 :(得分:0)
IMO,最简单的解决方案是启动AWS Lambda(或Google无服务器)并通过API网关附加它,为您提供时间服务器而无需管理任何基础架构。我的Lambda代码:
import datetime
import json
def lambda_handler(event, context):
dt = datetime.datetime.utcnow()
return {
'statusCode': 200,
'body': json.dumps({
'iso_time': dt.strftime('%Y-%m-%dT%H:%M:%SZ')
})
}
答案 11 :(得分:-1)
如果您的javascript是从Web服务器提供的,那么您可以使用此简单功能从此服务器请求时间。如果服务器在HTTP响应中返回Date标头,它将起作用。
function getServerTime()
{
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
return new Date(req.getResponseHeader("Date"));
}
暂停缓存这可能会返回错误的时间。要解决此问题,您可以使用随机网址:
req.open('GET', "/time?r=" + Math.floor(Math.random()*10000000), false);