且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何获取DateCompare()在ColdFusion 10中的行为?

更新时间:2023-09-11 23:24:52

(评论太长)



根据博客评论,我做了一些挖掘CF11。从我可以告诉,最初的比较失败的原因是,虽然前两个日期看起来类似:

  // code 
lastModifiedUTC:#DateTimeFormat(lastModifiedUTC,yyyy-mm-dd HH:nn:ss.L zzz)#
lastModifiedUTC2:#DateTimeFormat(lastModifiedUTC2,yyyy-mm-dd HH:nn:ss。 L zzz)#
// output
lastModifiedUTC:2015-09-13 19:51:46.219 UTC
lastModifiedUTC2:2015-09-13 19:51:46.219 PDT

...由于时区差异,内部对象表示不同的时间点。这就是为什么dateCompare()无法返回0.(第三个比较失败的原因相同。)

  // code 
lastModifiedUTC:#lastModifiedUTC.getTime()#
lastModifiedUTC2:#lastModifiedUTC2.getTime()#
// output
lastModifiedUTC:1442173906219
lastModifiedUTC2:1442199106219
请注意,如果您将 lastModifiedUTC 与原始(本地)日期比较,则会出现

,它如预期工作?尽管时区不同,但两个对象在内部仍然表示相同的时间点:

  // code 
dateCompare: #dateCompare(lastModifiedUTC,lastModified)#
lastModifiedUTC:#lastModifiedUTC.getTime()#
lastModified:#lastModified.getTime()#
lastModifiedUTC:#DateTimeFormat(lastModifiedUTC,yyyy-mm- dd HH:nn:ss.L zzz)#
lastModified:#DateTimeFormat(lastModified,yyyy-mm-dd HH:nn:ss.L zzz)#

输出
dateCompare:0
lastModifiedUTC:1442173906219
lastModified:1442173906219
lastModifiedUTC:2015-09-13 19:51:46.219 UTC
lastModified:2015-09-13 12:51:46.219 PDT

奇怪的是,第二个比较也不能返回0,事实上,两个对象似乎有相同的时间和时区。但是,如果您查看内部时间值,毫秒不同。 POP值的毫秒始终为零。 DatePart 报告相同的结果。 是有意义的,因为POP日期是通过解析不包含毫秒的字符串创建的。但这并不能解释为什么 DateTimeFormat 将毫秒显示为非零



第二个比较无法返回0,因为两个日期具有不同的毫秒值。与文件日期不同,POP日期是通过解析不包含毫秒的字符串创建的,因此日期部分始终为零。由于dateCompare()执行完全比较(包括毫秒),两个日期不相等。

  // code 
lastModifiedUTC:#DateTimeFormat(lastModifiedUTC,yyyy-mm-dd HH:nn:ss。 L zzz)#
parseLastModifiedHttpTimePOP:#DateTimeFormat(parseLastModifiedHttpTimePOP,yyyy-mm-dd HH:nn:ss.L zzz)#
lastModifiedUTC:#lastModifiedUTC.getTime()#
parseLastModifiedHttpTimePOP:#parseLastModifiedHttpTimePOP.getTime()#
datePart(lastModifiedUTC):#datePart(l,lastModifiedUTC)#
datePart(parseLastModifiedHttpTimePOP):#datePart(l,parseLastModifiedHttpTimePOP)#

// output
lastModifiedUTC:2015-09-13 19:51:46.219 UTC
parseLastModifiedHttpTimePOP:2015-09-13 19:51:46.0​​ UTC
lastModifiedUTC:1442173906219
parseLastModifiedHttpTimePOP:1442173906000
datePart(lastModifiedUTC):219
datePart(parseLastModifiedHttpTimePOP):0

但是,在一个好的注释,这意味着比较工作,如果你跳过毫秒,只比较到第二ie dateCompare(date1,date2,s)

  // code 
DateCompare(lastModifiedUTC,parseLastModifiedHttpTimePOP,s):#Date (lastModifiedUTC,parseLastModifiedHttpTimePOP,s)#
// output
DateCompare(lastModifiedUTC,parseLastModifiedHttpTimePOP,s):0

另外,我不知道为什么Adobe选择改变一些关键的UTC日期的行为。不幸的是,我不知道有很多你可以做的它不是博客评论中提到的选项a)更改jvm时区或b)创建您自己的版本的dateConvert并改用它。



男孩什么乱....


I'm using CF10 with latest update level on Windows in Pacific Standard Time. I need a datecompare() combination that returns 0 but I cannot get it to behave every since Adobe decided to change the behavior of DateConvert() and DateCompare()

<cfset filePath = getBaseTemplatePath()>
<cfset fileinfo = getFileInfo(filePath)>
<cfset lastModified = fileinfo.lastModified>
<cfset lastModifiedUTC = dateConvert("local2utc", lastModified)>
<cfset lastModifiedUTC2 = dateAdd("s", getTimezoneInfo().UtcTotalOffset, lastModified)>

<cfset lastModifiedHttpTime = getHttpTimeString(lastModified)>
<cfset parseLastModifiedHttpTimeSTD = parseDateTime(lastModifiedHttpTime)>
<cfset parseLastModifiedHttpTimePOP = parseDateTime(lastModifiedHttpTime, "pop")>

<cfoutput>
<pre>
lastModified  (local)        : #datetimeformat(lastModified, 'long')#

lastModifiedUTC              : #datetimeformat(lastModifiedUTC, 'long')#
lastModifiedUTC2             : #datetimeformat(lastModifiedUTC2, 'long')#
datecompareLmUTC             : #dateCompare(lastModifiedUTC, lastModifiedUTC2)#  //wtf

lastModifiedHttpTime         : #lastModifiedHttpTime#
parseLastModifiedHttpTimeSTD : #datetimeformat(parseLastModifiedHttpTimeSTD, 'long')#
parseLastModifiedHttpTimePOP : #datetimeformat(parseLastModifiedHttpTimePOP, 'long')#

I need a datecompare() combination that returns 0
------------------------------------------------
DateCompare(lastModifiedUTC, parseLastModifiedHttpTimePOP) : #DateCompare(lastModifiedUTC, parseLastModifiedHttpTimePOP)#
DateCompare(lastModifiedUTC2, parseLastModifiedHttpTimePOP) : #DateCompare(lastModifiedUTC2, parseLastModifiedHttpTimePOP)#

CF Version                : #server.coldfusion.productVersion#, update level: #server.coldfusion.updatelevel#
</pre>
</cfoutput>

OUTPUT:

lastModified  (local)        : September 11, 2015 7:10:23 PM PDT

lastModifiedUTC              : September 12, 2015 2:10:23 AM UTC
lastModifiedUTC2             : September 15, 2015 4:58:22 PM PDT
datecompareLmUTC             : -1  //wtf

lastModifiedHttpTime         : Sat, 12 Sep 2015 02:10:23 GMT
parseLastModifiedHttpTimeSTD : September 12, 2015 2:10:23 AM PDT
parseLastModifiedHttpTimePOP : September 12, 2015 2:10:23 AM UTC

I need a datecompare() combination that returns 0
------------------------------------------------
DateCompare(lastModifiedUTC, parseLastModifiedHttpTimePOP) : 1
DateCompare(lastModifiedUTC2, parseLastModifiedHttpTimePOP) : 1

CF Version                : 10,0,17,295085, update level: 17

I'm pulling my hair out.

(Too long for comments)

I did some digging with CF11, based on the blog comments. From what I could tell, the reason the initial comparison fails is that although the first two dates look similar:

// code
lastModifiedUTC    : #DateTimeFormat(lastModifiedUTC, "yyyy-mm-dd HH:nn:ss.L zzz")#
lastModifiedUTC2   : #DateTimeFormat(lastModifiedUTC2, "yyyy-mm-dd HH:nn:ss.L zzz")#
// output
lastModifiedUTC    : 2015-09-13 19:51:46.219 UTC
lastModifiedUTC2   : 2015-09-13 19:51:46.219 PDT

... due to time zone differences, internally the objects represent a different point in time. That is why dateCompare() fails to return 0. (The third comparison fails for the same reason.)

// code
lastModifiedUTC              : #lastModifiedUTC.getTime()#
lastModifiedUTC2             : #lastModifiedUTC2.getTime()#
// output
lastModifiedUTC              : 1442173906219
lastModifiedUTC2             : 1442199106219

Notice if you compare lastModifiedUTC to the original (local) date, it works as expected? Despite the different time zones, both objects still represent the same point in time internally:

// code
dateCompare             : #dateCompare(lastModifiedUTC, lastModified)#  
lastModifiedUTC         : #lastModifiedUTC.getTime()#
lastModified            : #lastModified.getTime()#
lastModifiedUTC         : #DateTimeFormat(lastModifiedUTC, "yyyy-mm-dd HH:nn:ss.L zzz")#
lastModified            : #DateTimeFormat(lastModified, "yyyy-mm-dd HH:nn:ss.L zzz")#

// output
dateCompare             : 0  
lastModifiedUTC         : 1442173906219
lastModified            : 1442173906219
lastModifiedUTC         : 2015-09-13 19:51:46.219 UTC
lastModified            : 2015-09-13 12:51:46.219 PDT

Curiously, the second comparison also fails to return 0, despite the fact that both objects seem to have the same time and time zone. However, if you look at the internal time values the milliseconds differ. The milliseconds of the POP value are always zero. DatePart reports the same result. That sort of makes sense, since the POP date was created by parsing a string which does not contain milliseconds. Yet that does not explain why DateTimeFormat shows the milliseconds as non-zero.

The second comparison fails to return 0 because the two dates have different millisecond values. Unlike the file date, the POP date was created by parsing a string that does not contain milliseconds, so that date part is always zero. Since dateCompare() performs a full comparison (including milliseconds) the two dates are not equal.

// code
lastModifiedUTC                         : #DateTimeFormat(lastModifiedUTC, "yyyy-mm-dd HH:nn:ss.L zzz")#
parseLastModifiedHttpTimePOP            : #DateTimeFormat(parseLastModifiedHttpTimePOP, "yyyy-mm-dd HH:nn:ss.L zzz")#
lastModifiedUTC                         : #lastModifiedUTC.getTime()#
parseLastModifiedHttpTimePOP            : #parseLastModifiedHttpTimePOP.getTime()#
datePart(lastModifiedUTC)               : #datePart("l", lastModifiedUTC)#
datePart(parseLastModifiedHttpTimePOP)  : #datePart("l", parseLastModifiedHttpTimePOP)#

// output
lastModifiedUTC                         : 2015-09-13 19:51:46.219 UTC
parseLastModifiedHttpTimePOP            : 2015-09-13 19:51:46.0   UTC
lastModifiedUTC                         : 1442173906219
parseLastModifiedHttpTimePOP            : 1442173906000
datePart(lastModifiedUTC)               : 219
datePart(parseLastModifiedHttpTimePOP)  : 0

However, on a good note, that means the comparison works if you skip the milliseconds and only compare down to the "second" ie dateCompare(date1, date2, "s"):

// code
DateCompare(lastModifiedUTC, parseLastModifiedHttpTimePOP, "s") : #DateCompare(lastModifiedUTC, parseLastModifiedHttpTimePOP, "s")#
// output
DateCompare(lastModifiedUTC, parseLastModifiedHttpTimePOP, "s") : 0

As an aside, I am not sure why Adobe chose to change the behavior of something as critical as UTC dates .. Unfortunately, I do not know that there is much you can do about it other than the options mentioned in the blog comments a) Change the jvm time zone or b) create your own version of dateConvert and use that instead.

Boy what a mess....