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

DateDiff problem

Community Beginner ,
Jan 10, 2009 Jan 10, 2009
I'm trying to convert the current time, (or any time come to that), into an Epoch time or timestamp. The steps I use are first to convert to UTC, and then get the DateDiff in seconds from 1/1/1970 00:00:00. However, the result is off by exactly 3600/1 hour and I don't know why. If I do the conversion the other way, (epoch to date), I also get the hour difference problem. I don't see how DST could be the problem as I'm converting to UTC first, (and I've confirmed that the UTC is correct).

Here's my code:

<cfset info = GetTimeZoneInfo()>
<cfset utcDateTime = DateAdd("s", info.utcTotalOffset, Now())>
<cfset epochDate = CreateDate(1970, 1, 1)>
<cfset epochTime = DateDiff("s", epochDate, utcDateTime)>

When I confirm the output of epochTime with an online service such as www.epochconverter.com it's short by exactly 3600, even though the UTC date is correct. Can someone help, and maybe run the above code on a server in there locale to see if they experience the same issue?

Thanks!
1.1K
Translate
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
LEGEND ,
Jan 10, 2009 Jan 10, 2009
DaveH225 wrote:
> way, (epoch to date), I also get the hour difference problem. I don't see how
> DST could be the problem as I'm converting to UTC first, (and I've confirmed
> that the UTC is correct).

cf sees all datetimes as being in the server tz:

http://www.sustainablegis.com/blog/cfg11n/index.cfm?mode=entry&entry=77223B6A-20ED-7DEE-2AB7FBB1F37A...

so it really doesn't matter that you converted to UTC or whatever. as soon as
you touch that datetime, cf will convert to the server's tz.

> <cfset epochTime = DateDiff("s", epochDate, utcDateTime)>

you can short-cut all this by using the undocumented getTime() method on your
datetimes:

<cfscript>
n=now().getTime();
writeoutput("#n#");
</cfscript>

which will return the java epoch offset (in *ms*). divide by 1000 if you want
the unix epoch offset (seconds). again it's undocumented but hasn't seemed to
change in 3 or so versions.

Translate
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 Beginner ,
Jan 11, 2009 Jan 11, 2009
I've read that article before, (on a different site with different comments), and thought it applied to earlier versions of CF as it's dated 2006, but even if it's still a problem I still don't understand how it's effecting my result. Here's why:

My timezone is Alaska, which currently is 9 hours behind GMT, not 1 hour, so why is the server TZ overriding by an hour?

Standard time is in effect on my server, not Daylight Savings, so again there shouldn't be an adjustment of an hour, should there?

While I can easily convert to using the getTime method I'm trying to understand the underlying problem so that I can avoid any future issues, (when DST next comes into effect).

I'm new to ColdFusion and while I'm impressed overall, I find this problem rather disappointing and highly frustrating. When I'm learning a new programming language I don't want to have to be wasting my time trying to dig out workarounds to fundamental problems. UTC should work, because that's what it's there for!

Anyway, I'll try the getTime method and report back. :)
Translate
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 Beginner ,
Jan 11, 2009 Jan 11, 2009
OK Paul, can you confirm this for me please.

thisdate.getTime() returns milliseconds from midnight 1/1/1970 UTC, AFTER converting thisdate into UTC based on locale. i.e. I created a date as follows:

<cfset testDate = CreateDateTime(1989,2,25,10,37,56)>

and testDate.getTime() returned milliseconds for 2/25/1989 19:37:56 UTC

newdate.setTime() returns LOCAL date/time given an epoch in milliseconds. i.e. the code

newDate.setTime(testDate.getTime());

converts testDate to UTC, returns milliseconds, sets newDate as milliseconds from epoch BUT returns newDate as LOCALE date, not as UTC date. i.e. exactly the same format of date is returned in newDate as was supplied in testDate and any UTC conversion is transparent.

So if a user supplies an epoch time from a system they're monitoring, a date object created with setTime will correctly display the local time, or I can use toUTCString to display the UTC time. This is ultimately what I'm trying to achieve, but what if the date is from a few months ago when daylight savings was in effect, will it show the correct time, (i.e. the time the actual event being monitored occured)?

I'm pretty sure that getTime and setTime will do exactly what I want, but I've gone around this so many times I've lost faith in my powers of reasoning!!!! (And I don't know if anything I've written above makes sense!)
Translate
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
LEGEND ,
Jan 11, 2009 Jan 11, 2009
DaveH225 wrote:
> I've read that article before, (on a different site with different comments),

you did? somebody's plagiarizing my blog? geez.

> and thought it applied to earlier versions of CF as it's dated 2006, but even

no, it's still true. that is until, unless cf gets a setTimezone() method. vote
early, vote often:

http://www.adobe.com/cfusion/mmform/index.cfm?name=wishform&product=12&6213=6

> if it's still a problem I still don't understand how it's effecting my result.

you mentioned DST.

> My timezone is Alaska, which currently is 9 hours behind GMT, not 1 hour, so
> why is the server TZ overriding by an hour?

what tz is the server in? i don't know what "My timezone is Alaska" refers to.

> Standard time is in effect on my server, not Daylight Savings, so again there
> shouldn't be an adjustment of an hour, should there?

are these historic dates? if your server's tz has DST, even if it's not in it
right now and you feed it a datetime on a DST cusp, it will automagically flop
that datetime over.

of course it could be as simple as somebody's time being set wrong.

> I'm new to ColdFusion and while I'm impressed overall, I find this problem
> rather disappointing and highly frustrating. When I'm learning a new
> programming language I don't want to have to be wasting my time trying to dig
> out workarounds to fundamental problems. UTC should work, because that's what
> it's there for!

most folks don't deal w/tz issues so it's not a real "serious" problem. to those
that do have to handle tz, there *is* such a thing as "timezone hell" 😉 in any
case, my blog points out a few simple workarounds (which is something i think
you'll learn to like in cf, it's never that hard to fix pretty much anything).
also handling tz issues is a problem in java, etc. if you don't do it right.
it's not really cf-specific.
Translate
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 Beginner ,
Jan 11, 2009 Jan 11, 2009
http://cfg11n.blogspot.com/2006/05/there-is-such-thing-as-timezone-hell.html

But since it has your name as author and you've even posted a comment, I guess you're familiar with it. :)

I mentioned DST, because that would be one reason a time might be off an hour. However, I don't know, or understand, if that would be causing this particular problem.

The server is in Alaska, (on my desk as I'm just using the Developer's Edition right now), and we have our very own time zone, GMT -9.

I was using the current date and time to test my code. I start simple and understand what's going on before branching out. I've only been at ColdFusion for about a week. 🙂 I will be moving to historic dates, but wanted to understand the issue I have right now so I can have some degree of confidence my code will work under all circumstances, (well, at least that would be nice).

I have successfully implemented getTime() and setTime(), so I guess I had better add some Java knowledge to my skillset. :)

Thanks for your help!
Translate
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
LEGEND ,
Jan 11, 2009 Jan 11, 2009
DaveH225 wrote:
> thisdate.getTime() returns milliseconds from midnight 1/1/1970 UTC, AFTER
> converting thisdate into UTC based on locale. i.e. I created a date as follows:

small nitpick, tz has nothing to do w/locales. nor does have anything to do
w/physical location on the earth either, its entirely political (ie china has
just the one tz, UTC+8, even though it physically crosses at least 4 tz in other
countries to its south).

> converts testDate to UTC, returns milliseconds, sets newDate as milliseconds
> from epoch BUT returns newDate as LOCALE date, not as UTC date.

all datetimes in cf are in the server tz.

> So if a user supplies an epoch time from a system they're monitoring, a date
> object created with setTime will correctly display the local time, or I can use
> toUTCString to display the UTC time. This is ultimately what I'm trying to
> achieve, but what if the date is from a few months ago when daylight savings
> was in effect, will it show the correct time, (i.e. the time the actual event
> being monitored occured)?

it *is* the actual datetime, just expressed in the cf server's tz.

if possible, the simplest solution is to set the server's tz to UTC then all
your datetime interactions will be in that tz. if you need to show other tz, use
the timezoneCFC to "cast" to them. or if that JS function does the trick for
your app, sure (though again be careful manipulating any datetime objects in cf
if these are from different tz before sending down the wire to JS client side).

if you need the datetime string server side, something like this should do the
trick:

<cfscript>
now=now();
dateCF=dateFormat(now,"FULL"); //just to compare
timeCF=timeFormat(now,"FULL");
longFormat=javaCast("int",0); //change as needed, 0==long--->3==short format
tZ=createObject("java","java.util.TimeZone").getTimeZone("UTC");
dF=createObject("java","java.text.DateFormat").getDateTimeInstance(fullFormat,longFormat);
dF.setTimezone(tZ);
writeoutput("cf server:=#dateCF# #timeCF#<br>UTC:=#df.format(now.getTime())#");
</cfscript>

> gone around this so many times I've lost faith in my powers of reasoning!!!!
> (And I don't know if anything I've written above makes sense!)

classic symptom. yup, you've fallen into timezone hell.
Translate
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
LEGEND ,
Jan 11, 2009 Jan 11, 2009
LATEST
DaveH225 wrote:
> http://cfg11n.blogspot.com/2006/05/there-is-such-thing-as-timezone-hell.html
>
> But since it has your name as author and you've even posted a comment, I guess
> you're familiar with it. :)

oh yeah, forgot i have that. just keep it for sentimental reasons (my original
blog way back when blogspot was kind of horrible).

> I have successfully implemented getTime() and setTime(), so I guess I had
> better add some Java knowledge to my skillset. :)

as you probably know cf runs on java, dipping down into it to solve something is
almost trivial. also allows you access to some very nifty java libs.
Translate
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