为啥 ColdFusion 纪元时间比 javascript 纪元时间晚一小时?
Posted
技术标签:
【中文标题】为啥 ColdFusion 纪元时间比 javascript 纪元时间晚一小时?【英文标题】:Why is the ColdFusion epoch time one hour behind the javascript epoch time?为什么 ColdFusion 纪元时间比 javascript 纪元时间晚一小时? 【发布时间】:2013-04-24 22:46:32 【问题描述】:我正在编写一个应用程序,我需要使用在 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 添加到它生成的 epoch 值,但我宁愿在不知道为什么我首先得到不正确的值的情况下不这样做。有人看到我在这里缺少什么吗?
【问题讨论】:
你的 JVM 版本是多少?你在哪个TZ? 【参考方案1】:编写一个小脚本你可能会发现一些很奇怪的东西。
这是它为我输出的。
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>
【讨论】:
加文是对的。这绝对是要走的路。你可以用一行轻松地创建一个可重用的函数:function getEpoch()return dateDiff('s', dateConvert('utc2Local', createDateTime(1970, 1, 1, 0, 0, 0)), now());
【参考方案2】:
ColdFusion 8 已经很老了,所以你应该检查你的 JVM 版本。您可能正在运行不符合新 DST 规则的过时版本。 See this Adobe forum for more:
“自该版本以来,美国夏令时规则发生了变化 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);
【讨论】:
【参考方案3】:这是时区地狱。 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#))
【讨论】:
以上是关于为啥 ColdFusion 纪元时间比 javascript 纪元时间晚一小时?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ColdFusion 认为值“7+”是一个有效的整数值,我如何验证它不是?
为啥 tzinfo 会在 python 中打破创建纪元时间?