为啥 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 纪元时间晚一小时?的主要内容,如果未能解决你的问题,请参考以下文章

为啥Django时区设置会影响纪元时间?

为啥 1/1/1970 是“纪元时间”?

为啥 ColdFusion 认为值“7+”是一个有效的整数值,我如何验证它不是?

为啥 tzinfo 会在 python 中打破创建纪元时间?

为啥微秒时间戳使用(私有)gettimeoftheday()重复,即纪元

如何在 shell 脚本中找到比当前时间早 30 天的纪元时间?