【问题标题】:why does ColdFusion's DateDiff return strange/negative values?为什么 ColdFusion 的 DateDiff 返回奇怪/负值?
【发布时间】:2012-10-02 14:14:32
【问题描述】:

又把我的头发拉出来了……

我需要以天为单位计算两个日期之间的差异。我正在这样做:

 <cfset d = DateDiff("d", Dateformat( active_apps.app_base_coupon_start, "dd.mm.yyyy"), Dateformat( variables.useDate, "dd.mm.yyyy") )>

active_apps.app_base_coupon_start = 27.07.2012variables.useDate = 今天 = 02.10.2012

我转储了这两个值,它们都可以。然而,dateDiff 在我寻找时返回-168(7 月 4 天,8 月 31 天,9 月 30 天,10 月 2 天)67 天。

问题:
有人可以阻止我失去剩余的头发并告诉我我在这里做错了什么,或者是否有更简单的方法可以在几天内获得差异?

编辑:
好的,它也可以这样工作:

<cfif DateAdd("d", active_apps.app_grace_time, Dateformat( active_apps.app_base_coupon_start, "dd.mm.yyyy") ) GT now()>
     <cfdump output="e:\s\page\t\dump.txt" label="catch" var="YUP"> 
<cfelse>
    <cfdump output="e:\s\page\t\dump.txt" label="catch" var="NOPE"> 
</cfif>

但我还是想知道,为什么 dateDiff 返回奇怪的值。

【问题讨论】:

  • 复制了您的代码,将您的日期变量替换为字符串“27.07.2012”和“02.10.2012”并得到 67。您的变量是否包含不同的值或不同类型的值?
  • 嗯。等一下。我的转储说:27.07.201202.10.2012
  • 让我再检查一次。必须是带有变量的东西。
  • 我认为您的日期掩码混淆了 02.10.2012 的月份和日期。 27.07.2012 和 10.02.2012 之间的差异是 -168 天
  • ColdFusion 将 27.07.2012 解释为 2012 年 7 月 27 日,但 02.10.2012 很可能会解释为 2 月 10 日 - 我猜这取决于您的语言环境。

标签: date coldfusion datediff


【解决方案1】:

DateDiff("datepart", date1, date2) 接受一个日期部分和两个日期对象作为参数。

DateFormat() as Adam Cameron already said 返回一个字符串而不是日期对象。
ColdFusion 试图通过尝试应用一些已知的日期格式来将“27.07.2012”和“02.10.2012”读取为日期对象。这就是为什么“02.10.2012”被解释为“2012 年 2 月 10 日”的原因。

我不会让 ColdFusion 猜测您的字符串的日期格式。相反,您应该使用 CreateDate(year, month, day) 创建日期对象。

now() 也是一个 ColdFusion 日期对象。

【讨论】:

    【解决方案2】:

    首先,dateAdd() 将 DATES 作为参数,而不是 dateFormat()-ed 字符串。 dateFormat() 用于输出,不用于计算。

    您需要了解,仅仅因为“02.10.2012”在您(和我)看来是一个日期,就计算机而言,它不是一个日期:它是一个字符串。

    永远不要使用字符串来计算日期。

    在您的情况下,CF 正在勇敢地尝试找出“02.10.2012”作为日期可能意味着什么,并确定它是“mm.dd.yyyy”格式,即 2 月 10 日,而您的意思是 10 月 2 日。

    【讨论】:

    • 此外,虽然 CF 可以将字符串隐式转换为日期,但标准日期函数始终使用美国日期格式约定,即 mm/dd/yyyy。所以02/10/2012 将始终被解释为 2 月 2 日。如果您需要对区域设置敏感的解析,请使用 LS 日期函数。
    • 是的。从来没有去过美国(好吧:反正从来没有在那里写过代码),这对我来说从来没有考虑过。我总是认为,当遇到一个圆孔时,不要试图通过它来砸一个椭圆形钉子,即:如果函数想要一个日期,给它一个日期,不要给它字符串并强制 CF 转换它。
    • @AdamCameron 只是为了吹毛求疵,ColdFusion 是一种(据说)无类型语言,所以如果字符串被格式化,那么字符串就是日期。 IsDate("2012-10-02") 将返回 true。
    • @AdamCameron:好的DateFormat。因此,当添加两个可能不同的日期时,我不必担心。我正在重做一个页面,我*我只得到像 02 几个月和 2012 几年的东西,然后需要添加第一天/最后一天并将这个日期与其他日期进行比较......男孩我希望我刚刚拥有一个纸质日历,可以从...中剪下东西
    • Adam - 同意,我认为使用日期对象几乎总是更好。更少的歧义和问题的余地。但我使用过使用所有字符串的旧版应用程序,这只是因为它们都是“mm/dd/yyyy”。
    【解决方案3】:

    您使用的日期格式不明确。每当您进行日期计算时,将 DateFormat 更改为国际日期格式 (ISO 8601),事情会更加可预测。请注意,CF 并不支持 ISO 格式的所有变体,但在大多数情况下,您只需要受支持的 yyyy-mm-dd

    <cfset d = DateDiff("d", Dateformat( active_apps.app_base_coupon_start, "yyyy-mm-dd"), Dateformat( variables.useDate, "yyyy-mm-dd") )>
    

    【讨论】:

    • 同意明确的格式。但是您不想使用DateFormat。这只是将字符串转换为日期 - 并再次转换回字符串。然后DateDiff 将其转换回日期。最好先传入一个日期object
    • @Leigh 我不同意,尤其是在您以字符串开头的情况下。当语言的关键特性之一意味着它已为您处理时,自己解析它以消除歧义是没有意义的。 active_apps.app_base_coupon_start 是字符串、日期对象还是 ODBC 日期等?谁在乎呢,DateFormat 来救援。
    • 同意@Leigh,不同意@nosilleg。如果要使用函数将字符串转换为日期,请使用parseDateTime(),而不是dateFormat()。圆孔,圆钉。
    • @AdamCameron 如果您想从一天的开始到另一天的结束进行时间跨度比较,如果您不使用DateFormat,您将再次为自己做更多的工作。
    • @nosilleg - 不,ParseDateTime 用于解析。 DateFormat 用于将 日期对象 转换为用户友好的字符串。如果您只是将字符串传递给DateDiff,则无需使用DateFormat,因为DateDiff 执行相同的转换,除了一(1)步而不是三(3)步。但在这种特定情况下,结果仍然是错误的,因为02.10.2012 仍被解释为二月。这个问题出现的事实是一个很好的例子,说明为什么使用日期对象而不是字符串更好:) 它们不会受到这种歧义的影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多