传递给日期函数createDateTime的Coldfusion 2021日期值未指定或无效-请在createDateT


<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中的时间国际化和时区以及其中的一些陷阱。

最新更新