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

Coldfusion 2021 Date value passed to date function createDateTime is unspecified or invalid - Specify a valid date in createDateTime function

<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]

如有任何帮助,我们将不胜感激。谢谢

Can this issue be associated with the daylight saving in Pakistan?

否,此问题与巴基斯坦的夏令时无关。

更新: 正如 Adam Camaron 正确提到的...

The problem is entirely down to the daylight savings issue the original poster mentioned.

我最初的发现是不正确的。请阅读 Adam Cameron 对这个问题的非常有趣的回答,以获得更深入的解释。他的回答应该是被接受的。

我会保持我的回答 post 有效以供进一步参考,因为它可能有助于更好地概述在 CFML 中处理 dateTime 对象的类似问题。

=============================

原答案:

根据关于 CreateODBCDateTime() 的 cfml 文档,您需要将 dateTime-Object 作为参数传递给 CreateODBCDateTime()。您的变量 mydate = 'June 01, 2008' 只是一个表示日期的字符串,但它不是 dateTime 对象。

July 01, 2008 (okay), May 15, 2009 (okay) etc. But shows error with June 01, 2008 (error) and April 07, 2002 (error)

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,并使用 TimeZone 函数相应地输出它。

旁注...因为这通常会被误解,所以我 post 在这里只是为了 posterity:“locales”使字符串适应典型的可读(翻译)字符串,因为它们通常被各自的文化阅读和识别,但它们不会改变时区。

想多了解一点,可以热烈推荐watching this video about timeZones from Lucee。它不是来自 ColdFusion,但它解释了很多关于 CFML 中的时间国际化和时区以及其中的一些陷阱。

恐怕(最初~)接受的答案是不正确的。问题 完全 归结为发帖人提到的夏令时问题。

原代码是这样的:

<cfset mydate = 'June 01, 2008'> 
<cfset JobStartDate=CreateODBCDateTime(mydate)>

如前所述,CreateODBCDateTime需要一个date/time对象,而不是字符串,所以CF首先要做的是将'June 01, 2008'转换为date/time,所以相当于:

<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 会出现相同的错误:那是当年夏令时开始的时间。

这说明了为什么 servers 应始终设置为 UTC。时间上很少有“意外”的间隙(尽管有奇怪的修正 leap-second),所以这些问题根本不会出现。如果您使用 UTC,然后在必要时调整时区以供人类显示,CF 将始终正确。


还有一点。说代码在旧版本的 CF 中运行良好是不正确的(这出现在对早期答案的评论中)。 SetTimeZone 仅在 ColdFusion for CF2021 的 CFML 中添加,问题中的代码在早期版本中出错。因此,无论您在旧版本的 CF 上经历或未经历/测试都不是这个问题。