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 添加到它生成的纪元值上,但我宁愿不这样做,因为我不知道为什么我一开始就得到了不正确的值。有人看到我在这里缺少什么吗?

4

3 回答 3

10

写一个小脚本你可能会注意到一些很奇怪的东西。

这就是它为我输出的。

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

因此,将纪元转换为当地时间是正确的,但反之则不然。这也在 CF8 上运行,所以如果你将 Epoch 转换为本地时间,它似乎是正确的。

试试看。

<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>
于 2013-04-30T22:24:08.500 回答
3

ColdFusion 8 已经很老了,所以你应该检查你的 JVM 版本。您可能正在运行不符合新 DST 规则的过时版本。有关更多信息,请参阅此 Adob​​e 论坛:

“自该版本的 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);
于 2013-04-30T22:08:13.967 回答
0

这是时区地狱。Unix 时间应该是 UTC 时间从 1970 年开始的秒数。但是他们以 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 FROM 无服务器本地时间:

DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), dateAdd('h',-timezone_hours_local_to_server, #LOCALTIME#))
于 2017-09-12T18:26:46.653 回答