<cfscript>
SetTimeZone("Asia/Karachi"); //same as our windows server timezone
</cfscript>
<cfoutput>
<cfset mydate = 'June 01, 2008'>
<cfset JobStartDate=CreateODBCDateTime(mydate)>
#JobStartDate#
</cfoutput>
错误:传递给日期函数createDateTime的日期值未指定或无效。在createDateTime函数中指定有效日期。
我正在windows服务器上使用ColdFusion 2021(更新4)。在JVM详细信息下,Java默认区域设置为en_US。
错误可以在:cffiddle.org 上重现
适用于其他日期,例如2008年7月1日(好)、2009年5月15日(好的)等。但显示2008年6月1日和2002年4月7日有错误不确定是否还有其他日期
附加说明:这个问题是否与巴基斯坦的夏令时有关?
夏令时复兴
2008年,巴基斯坦自2002年以来首次使用夏令时来应对能源危机。2008年5月31日至6月1日午夜,时钟提前了一小时(至UTC+6)。巴基斯坦在夏季高峰期需要夏令时,因为该国正在努力解决大约4000兆瓦的电力短缺问题。(参考)[https://www.timeanddate.com/news/time/pakistan-extends-dst-2008.html]
如有任何帮助,我们将不胜感激。感谢
恐怕(最初~)接受的答案是不正确的。问题完全在于海报上提到的夏令时问题。
原始代码是这样的:
<cfset mydate = 'June 01, 2008'>
<cfset JobStartDate=CreateODBCDateTime(mydate)>
如上所述,CreateODBCDateTime
期望的是日期/时间对象,而不是字符串,因此CF需要做的第一件事是将'June 01, 2008'
转换为日期/时间,因此等效于:
<cfset mydate = createDateTime(2008,6,1,0,0,0)>
我在那里添加了小时、分钟和秒部分,因为它们是创建日期/时间对象所必需的。你没有给它时间部分,所以CF必须假设零。
你猜怎么着?2008年6月1日,根据巴基斯坦的夏令时规则,没有像00:00:00
这样的东西。午夜钟声敲响时,时间向前拨到01:00:00
。因此出现错误:
Date value passed to date function createDateTime is unspecified or invalid
它准确地告诉你问题出在哪里。当人们试图使用由于夏令时的变幻莫测而不存在的时间时,总会遇到这种情况。这与试图将日期部分指定为";2月32日";或者更明显无效的东西。
出于同样的原因,2009-04-15
上也会出现同样的错误:那是当年夏令时开始的时候。
这说明了服务器应始终设置为UTC的原因。很少有";出乎意料的";时间上的差距(尽管有奇怪的纠正闰秒),所以这些问题根本不会出现。如果您使用UTC,然后在必要时调整时区以供人类显示,CF将始终正确无误。
另一点。说代码在旧版本的CF中运行良好是不正确的(这出现在对早期答案的评论中)。SetTimeZone
仅在CF2021的ColdFusion上添加到CFML中,问题中的代码在早期版本中出现错误。因此,无论你在旧版本的CF上经历或没有经历/测试,都不是这个问题。
这个问题是否与巴基斯坦的夏令时有关?
不,这个问题与巴基斯坦的夏令时无关
更新:正如Adam Camaron正确提到的。。。
问题完全在于原始海报提到的夏令时问题。
我最初的发现是不正确的。请阅读Adam Camerons对这个问题非常有趣的回答,以便进一步深入解释。他的答案应该是公认的。
我将保持我的回答帖子处于活动状态以供进一步参考,因为它可能有助于更好地概述CFML中处理dateTime对象的类似问题。
=============================
原始答案:
根据关于CreateODBCDateTime()的cfml文档,您需要将dateTime对象作为参数传递给CreateODBCDate Time()。变量mydate = 'June 01, 2008'
只是一个表示日期的字符串,但它不是dateTime对象。
2008年7月1日(正常)、2009年5月15日(正常
cfml引擎会尝试以某种方式处理提交的字符串,并将其转换为正确的数据类型,但这可能有效,也可能无效:它根本不受官方支持,所以我宁愿不这样做。
要创建dateTimeObject,您需要首先将该字符串解析为dateObject,例如使用lsParseDateTime(),并且像@sos正确评论的那样,如果您使用不同的语言环境,最好始终传递字符串内容表示为属性的正确语言环境:
<cfoutput>
<cfset mydate = 'June 01, 2008'>
<cfset JobStartDate=CreateODBCDateTime( lsParseDateTime( mydate, "en_US" ))>
#JobStartDate#
</cfoutput>
如果您的dateTime数据合适,另一种选择是首先使用createDateTime()函数从头开始创建dateTimeObject,例如:
<cfoutput>
<cfset mydate = createDateTime(2008,5,1,0,0,0)>
<cfset JobStartDate=CreateODBCDateTime( mydate )>
#JobStartDate#
</cfoutput>
关于世界各地的分时度假,这取决于你如何获取和保存时间数据,以及你将数据发送给世界上的谁。在全球环境中,我通常会将日期保存到UTC,并使用时区功能相应地输出。
旁注。。。因为这通常被误解了,所以我把它贴在这里只是为了子孙后代:";地方";将字符串调整为典型的可读(传统)字符串,因为它们通常由各自的文化读取和识别,但它们不会更改时区。
为了进一步了解这一点,我可以热烈推荐观看这段来自Lucee的关于时区的视频。它不是来自ColdFusion,但它解释了很多关于CFML中的时间国际化和时区以及其中的一些陷阱。