为什么ColdFusion的纪元时间比JavaScript的纪元时间晚一个小时?

14
我正在编写一个应用程序,需要在运行在 Windows Server 2008 上的 ColdFusion 8 服务器端和使用 JavaScript 的客户端(在 Google Chrome 中进行测试)获取时代时间。问题是,ColdFusion 生成的时代时间比 JavaScript 生成的晚一个小时。我已经验证了客户端和服务器端的日期/时间设置都是正确的。
这是我如何使用 ColdFusion 设置时间戳的方式:
<cfset cfEpoch = DateDiff("s", "January 1 1970 00:00", DateConvert("Local2utc", now()))>

这是我用JavaScript设置它的方式:
var jsEpoch = Math.round(new Date().getTime()/1000.0);

JavaScript纪元与此网站(http://www.epochconverter.com/)匹配,这是有道理的,因为他们使用的方法与我使用的方法相同。ColdFusion纪元落后一个小时。以下是我运行的内容,尝试解决这个问题:
<cfset localDate = now()>
<cfset utcDate = DateConvert("Local2utc", localDate)>
<cfset epoch = DateDiff("s", "January 1 1970 00:00", utcDate)>

<cfoutput>
    Local Date: #localDate# <br>
    UTC Date: #utcDate# <br>
    Epoch: #epoch#
</cfoutput>

那段代码输出:
Local Date: {ts '2013-04-30 17:44:56'} 
UTC Date: {ts '2013-04-30 21:44:56'} 
Epoch: 1367354696

所以我很困惑。本地日期和UTC日期值都是正确的。看起来唯一的解释是DateDiff()函数没有正常工作,但我已经测试了其他日期,它似乎运行良好。我想我可以只需将3600添加到它生成的时代值中,但我不想在不知道为什么首先会得到错误值的情况下这样做。有人看到我漏掉了什么吗?


你的JVM版本是什么?你所在的时区是哪个? - Adam Cameron
3个回答

10

写一个简单的脚本,你可能会注意到一些非常奇怪的事情。

这是它对我输出的内容。

  • 1367360584 - Javascript时间
  • 1367360594 - 纪元秒(将纪元转换为本地时间)
  • 1367356994 - 纪元秒(将本地时间转换为UTC)

因此,将纪元时间转换为本地时间是正确的,但反过来却不是。这也是在CF8上运行的,所以如果你将纪元时间转换为本地时间,似乎它会做得正确。

试一下。

<script>
var jsEpoch = Math.round(new Date().getTime()/1000.0);
document.write(jsEpoch + ' - Javascript time <br>');
</script>


<cfset TheDate = now()>
<cfoutput>
#DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), TheDate)# - Epoch seconds (convert Epoch to local time)<br>
#DateDiff("s", "January 1 1970 00:00", DateConvert("Local2utc", TheDate))# - Epoch seconds (convert local time to UTC)
</cfoutput>

1
Gavin是正确的。这绝对是正确的方法。您可以轻松地使用一行代码创建可重用的函数: function getEpoch(){return dateDiff('s', dateConvert('utc2Local', createDateTime(1970, 1, 1, 0, 0, 0)), now());} - imthepitts

3
ColdFusion 8比较陈旧,所以您应该检查JVM的版本。您可能会运行过时的版本,不符合新的DST规则。请参考此Adobe论坛了解更多信息。
引用:“自那个ColdFusion版本和它的基础JRE发布以来,美国夏令时规则已经更改。 您需要更新JRE至少1.6.12才能获得新规则。”
更新:经过进一步测试,JVM不是问题所在。我在CF9上也得到了与上述相同的结果,并且我们已经超过了旧规则和新规则返回不同结果的时间范围。但是,这里有几种方法可以获得正确的结果(感谢Gavin的答案)。
function getEpoch(date localDate=now()){
    return dateDiff('s', dateConvert('utc2Local', createDateTime(1970, 1, 1, 0, 0, 0)), localDate);
}

或者,您可以访问底层的Java方法(将结果包装在int()中以删除小数部分):

int(createObject('java', 'java.lang.System').currentTimeMillis()/1000);

0
这是时区的地狱。Unix时间应该是从1970年以来的UTC时间的秒数。但是Coldfusion和railo的方式是需要添加服务器时间而不是UTC的秒数。将1970年转换为“localServer时间”,然后添加秒数,然后再转换回UTC。似乎在转换为UTC时只是移动了小时,而没有应用UTC DST规则。这是正确的:
从UNIX到UTC:
CreateODBCDateTime(DateConvert("local2Utc", DateAdd("s", #UNIXTIME#, DateConvert("utc2Local", "January 1 1970 00:00"))) )

UNIX来自没有服务器本地时间:

DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), dateAdd('h',-timezone_hours_local_to_server, #LOCALTIME#))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接