• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Are ColdFusion datetimes stored with a UTC offset?

Explorer ,
Apr 15, 2024 Apr 15, 2024

Copy link to clipboard

Copied

We're currently observing Daylight Saving Time in the UK, so local time is UTC +01:00 (as opposed to UTC +00:00). When a ColdFusion datetime is output to the page, no UTC offset is displayed, leading me to assume it didn't account for them.

 

The code below shows local time and UTC as being 1 hour apart (18:10 and 17:10 respectively), but DateCompare() insists both datetimes are the same, which is only true if each datetime's UTC offset is considered in the comparison.

 

Are ColdFusion datetimes stored with a UTC offset? If so, is there any way to access it? Thanks.

 

P.S. No ColdFusion option in Insert Code Sample. Seriously?!?

 

 

<cfset now = now()>
<cfset utcNow = dateConvert("local2utc", now)>

<cfoutput>
now: #now#<br>
utcNow: #utcNow#<br>
dateCompare(now, utcNow): #dateCompare(now, utcNow)#<br>
</cfoutput>

<cfdump var="#GetTimeZoneInfo()#">

 

 

now: {ts '2024-04-15 18:10:24'}
utcNow: {ts '2024-04-15 17:10:24'}
dateCompare(now, utcNow): 0

 

isDSTonYES
timezoneEurope/London
utcHourOffset-1
utcMinuteOffset0
utcTotalOffset-3600

Views

187

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Apr 15, 2024 Apr 15, 2024

Aiden, a few clarifications (and a possible workaround):

 

1) The time CF uses is actually controlled by the Java underlying CF. And by default the JVM uses the system's time (that can be changed, with a timezone JVM arg used in CF's jvm configuration. I can share more, if interested.)

 

You say, "When a ColdFusion datetime is output to the page, no UTC offset is displayed", and that is true. I just shows the time on the server, without ny indication of offset. You add that this leads you "to as

...

Votes

Translate

Translate
Community Expert ,
Apr 15, 2024 Apr 15, 2024

Copy link to clipboard

Copied

Aiden, a few clarifications (and a possible workaround):

 

1) The time CF uses is actually controlled by the Java underlying CF. And by default the JVM uses the system's time (that can be changed, with a timezone JVM arg used in CF's jvm configuration. I can share more, if interested.)

 

You say, "When a ColdFusion datetime is output to the page, no UTC offset is displayed", and that is true. I just shows the time on the server, without ny indication of offset. You add that this leads you "to assume it didn't account for" the offset, and that's true insofaras the datetime object as displayed: it's just the datetime in question...except for a couple of things...

 

2)  The dateConvert() is indeed an odd animal. Its purpose IS to give you what the time would be in DST, as you have shown.

 

The problem is that if you use it in a date/time comparison, it acts as if it's the same date/time from which it was converted....and that's because it IS the same date and time (under the covers), it's just presented differently in terms of reflecting that UTC offset--for better or worse.  That's why your datecompare showed a result of 0 (they are the "same time", at least internally.)

 

And technically, they're also NOT the same TYPE of underlying java objects. You can view that with code like this (within your existing CFOUTPUT), at least assuming that the CF Admin feature to "Disable access to internal ColdFusion Java components" is off:

 

 

now classtype: #Now.getClass().getName()#<br>
utcnow classtype: #utcnow.getClass().getName()#"<br>

 

 

The former shows to be a coldfusion.runtime.OleDateTime, while the latter shows to be a coldfusion.runtime.UTCOleDateTime. Subtle difference, but it seems related to the issue you observe.

 

And the fact that dateconvert returns that object (and leads to the problem you are reporting) seems new behavior since CF11 (in 2014), when the observation was raised in a tracker ticket CF-3777192. There was never any resolution, nor even any acknowledgement from Adobe of there being a change in behavior then. And clearly it's not changed. 

 

Nor was any workaround offered by anyone. But I think I can offer one.

 

3) First, you ask "is there any way to access" the timezone offset, and indeed there is--using that very dump of the GetTimeZoneInfo that you offered at the bottom, you can know the offset amount (though that's for CF as a whole rather than for any given datetime, as you asked about above).

 

But second, you could USE that info to get what the more correct comparison you want (using those variables). More specifically, I suspect you were using the dateconvert just to get the time AS IF it was UTC. You CAN get that.

 

It just entails adding that offset back to the time in question (like when using now()). Again, this example is written in tags (as you had done), and presuming to still be within the CFOUTPUT pair you were using. Note that I create a new utcnow2 variable:

 

 

<cfset utcNow2 = dateadd("h",GetTimeZoneInfo().utcHourOffset,Now())>

utcNow2: #utcNow2#<br>
datediff(now, utcNow2): #datediff("h", utcNow2, now)# (number of hours difference between now and utcnow2)<br>
dateCompare(now, utcNow2): #dateCompare(now, utcNow2)# (a -1 result means now is earlier than utcnow2, while 1 means the opposite, and 0 means they are equal)<br>

 

 

Note how utcnow2 does now have the current time, as UTC time, and I show how you can use THAT in both a comparison which DOES reflect the correct time difference--which of course it should, as we simply subtracted or added the offset from the current time. And same with the datediff I offer. (And all this is assuming, as you say, you run this code on a server where the java/cf time is indeed not currently on UTC time--otherwise there's no time difference but the code still works.)

 

You might consider adding a vote to that tracker ticket, but if so I'd suggest you open a new ticket (since that one is marked "closed"). Still, I'll go ahead and add a link to this discussion there (on that old ticket), in case someone else comes across it and wants to hear a more recent discussion (and might perhaps benefit from the workaround I've offered).

 

Let us know if this helps. And again if you want to get Adobe's attention on the matter, they may not respond here but eventually should see the ticket. If you do file one, please add a link for it here (or the number) so that others can consider adding votes and get notified of changes regarding it.

 

PS Oh, and you point out, "No ColdFusion option in Insert Code Sample. Seriously?!?" I'll note that I've never even noticed that drop down. I just always added my code in the popup, and of course CFML works fine in the default html/xml option. I guess you looked for another value in case it could make a difference, and fair enough. But I've also never seen anyone else ask about it. Sadly, many folks just plunk code into a message without even noticing that UI element to present it distinctively, which is indeed very helpful.


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 15, 2024 Apr 15, 2024

Copy link to clipboard

Copied

Agh, after I posted that I realized my workaround was wrong. My apologies. I have edited the above to indicate where I'd made a mistake (and removed that code), and I am working to make a correction. Will update the post when I have that, and I'll add a new reply here also (for those getting email notifications of new replies, who wouldn't necessarily know about the edit to my first reply).


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 15, 2024 Apr 15, 2024

Copy link to clipboard

Copied

OK, corrected the mistake (just one line, really), but I've also offered why the datecompare shows either a 1 or -1 (as it should, if a CF server is not on UTC time) as well as datediff to show the time difference in hours via a compare (which further shows this new utcnow2 is the kind of "real utc time" you may seek) . 

 

And of course, I show using it with now() like you had, but one could use this technique with any datetime in CFML, including one coming from a database. Then again, it's with databases where some argue strongly for storing time as utc. It's a long-debated subject. 


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 15, 2024 Apr 15, 2024

Copy link to clipboard

Copied

Hmm. I tried to add a link to this post in that old bug report, but it wouldn't take (nor would a vote)--which is all the more reason for you to consider raising a new one, Aiden. If nothing else, it could get Adobe's attention to better document the change.  And if that old bug report is somehow "too old", then a newer one would also be able to be voted up by others interested in the problem.


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

Charlie, you're an absolute star. I had a sneaking suspicion the cause was (the perennial) one of ColdFusion hiding complexity from the developer, only to find it leaks out elsewhere to bite you.

 

It's frustrating Adobe have marked that ticket as Won't Fix, but perhaps unsurprising. Yes, there's a workaround, but as a developer you don't want to discover DateCompare() not behaving as expected after the fact, and questioning your sanity. I've wasted countless hours checking and rechecking code, and now to have refactor an application to eliminate the possibility of this behaviour of having an impact, due to liberal use of DateConvert() and DateCompare(). Good job ColdFusion is now less than 5% of my time!

 

WRT the original requirement, I'd simply wanted the most elegant way of being able to determine the current time in UTC, regardless of host's time zone. DateConvert() appeared to provide that, but its counter-intuitive behaviour when fed into DateCompare() means it's not a viable solution. (It's causing incorrect comparisons against UTC datetime values retrieved from the database.) Am electing to use your suggestion of GetTimeZoneInfo(), albeit adjusting by seconds in utcTotalOffset rather than hours. At least it looks as though the resulting datetime can be fed into DateCompare() without surprises.

 

The issue with regards the editor was because posting CFML using the HTML/XML option resulted in a red warning saying (from memory) "Invalid code detected and fixed" (or was it removed?). I'd have expected Adobe to implement something that supported CFML, given it's their language... *shrug*

 

Thank you once again for confirming the observation, explaining the background and offering a good workaround. Hopefully other developers find this post and save themselves time. All the best!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

Thanks for the update and the kind regards. If you could mark my first reply as the answer, that could help future readers. It also is considered by Adobe with regard to the "community expert" designation Adobe offers here.

 

(As for bkbk's reply below, it seems he was writing it at the same time as yours, as his is 3 mins later--suggesting he'd not yet seen yours.)


/Charlie (troubleshooter, carehart.org)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

quote

... as a developer you don't want to discover DateCompare() not behaving as expected ...

 

By @Aidan Whitehall


To be clear, your sample code shows that dateCompare() behaves as expected. Both now() and utcNow represent the same datetime, taking into account the JVM's offset. The key here is casting.

 

quote

WRT the original requirement, I'd simply wanted the most elegant way of being able to determine the current time in UTC, regardless of host's time zone.


By @Aidan Whitehall

You've already found the most elegant way I can think of! Namely,

dateConvert("local2utc", now())

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

quote

Are ColdFusion datetimes stored with a UTC offset? 

 

By @Aidan Whitehall


Yes, ColdFusion date-times are stored with a UTC offset. Charlie's first answer tells you how they are stored. 

The UTC offset that ColdFusion stores date-times with is implicit, and a default. As ColdFusion is a Java application, its date-times are stored, by default, using the offset of the local timezone of the Java Virtual Machine (JVM) on which ColdFusion is running. That timezone is set in the JVM by means of the flag  -Duser.timezone . For example, the following setting ensures that the JVM has UTC timezone:

 

-Duser.timezone=GMT

 

If you don't explicitly set the timezone, the JVM will default to using the system timezone of the host operating system on which the JVM is running. This means that the JVM inherits the timezone settings from the environment in which it is executed, rather than defaulting to a specific timezone like UTC.

The code samples you have provided suggest that,

  • you have applied the JVM setting -Duser.timezone=Europe/London, or else,
  • you have applied no -Duser.timezone setting, which makes the JVM to default to the timezone of your host operating system, which is, presumably, Europe/London.
quote

..., is there any way to access it?


By @Aidan Whitehall

Yes. As you yourself have discovered, ColdFusion stores the current offset as the key utcTotalOffset of the struct getTimeZoneInfo(). In the JVM of your ColdFusion application, the offset is that of the Europe/London timezone.

 

Now, on to the reason why dateCompare(now, utcNow) produced 0. I don't think this is an error. In fact, I bet that, if you were to run the following code,

 

dateCompare(now(),current_datetime_in_Los_Angeles_USA)

 

the result would also be 0, irrespective of where on the planet your ColdFusion server is located.

 

The reason is simple. I think that, before doing the comparison, ColdFusion casts arguments, where necessary, into date-times having the same offset, namely the offset of the JVM's timezone. That enables ColdFusion to compare like with like. 

 

Long story short: the moral is to explicitly set -Duser.timezone in the JVM on which ColdFusion is running.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

Just to confirm what I said earlier about

 

dateCompare(now(),current_datetime_in_Los_Angeles_USA)

 

When I run the following code (with a timezone of "Europe/Amsterdam" in ColdFusion's JVM settings), the result is:

    Current local datetime (JVM timezone: 'Europe/Amsterdam'): {ts '2024-04-16 21:52:05'}

    Current datetime in Los Angeles, USA: 2024-04-16T12:52:05.464829700-07:00[America/Los_Angeles]

    dateCompare(now(), current_datetime_in_Los_Angeles_USA): 0

 

<cfscript>
zoneId=createobject("java","java.time.ZoneId");
zonedDateTime=createobject("java","java.time.ZonedDateTime");

// Local datetime 
writeOutput("<p>Current local datetime (JVM timezone: 'Europe/Amsterdam'): " & now() & "</p>");

// Los Angeles timezone and datetime
zoneIdLosAngeles = ZoneId.of("America/Los_Angeles");
zdtNowLosAngeles = ZonedDateTime.now(zoneIdLosAngeles);

// Current datetime in LA
current_datetime_in_Los_Angeles_USA=zdtNowLosAngeles.toString();
writeOutput("<p>Current date-time in Los Angeles, USA: " & zdtNowLosAngeles.toString() & "</p>");
 
//DateCompare with now()
comparison_now_and_LA_datetime=dateCompare(now(), current_datetime_in_Los_Angeles_USA);
writeoutput("dateCompare(now(), current_datetime_in_Los_Angeles_USA): " & comparison_now_and_LA_datetime);
</cfscript>

 

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

@Aidan Whitehall I've had to deal with similar issues while working on a web application for a country-wide air race event. The application uses datetime values stored as both local/server & UTC time and then has to display it as multiple time zones. We experienced oddities when using DateDiff, DateCompare & DateAdd with CF's date objects, as well as watched millisecond accuracy disappear entirely when some built-in CF operations were performed.

I blogged about the shortcomings that I encountered using dateConvert, dateTimeFormat & setTimezone and finally ended up writing a createIsoString() CFC.  I'm not sure if this will solve the issue you are encountering, but it at least it returns a standardized ISO string instead of a "UTC or local-formatted time object" which may behave differently than what you'd expect.
https://dev.to/gamesover/createisostring-a-coldfusion-user-defined-function-udf-to-replace-datetimef...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 17, 2024 Apr 17, 2024

Copy link to clipboard

Copied

LATEST

Thank you James, that CFC looks very useful. Perhaps not the solution for this situation, but handy to have in future, nonetheless. And it's always gratifying to hear that one's not alone when coming up against issues like this!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation