I'm just revisiting some utc to local date time co...
# cfml-general
d
I'm just revisiting some utc to local date time code and wondered if anyone can shed any light on the following:
Copy code
<cfscript>
    myutcdt = createDateTime("2024","7","1","12","00","00");
    writedump(myutcdt);
    setTimeZone("GB");
    mylocaldt = dateConvert("utc2Local", myutcdt);
    writedump(mylocaldt);
</cfscript>
Given a date that is in BST (British Summer Time) UTC+1. The code above shows my utc date/time as
{ts '2024-07-01 12:00:00'}
and the localdate shows as
{ts '2024-07-01 14:00:00'}
which is UTC+2 which is incorrect. Is this a bug or am I doing something daft. Both Lucee and ACF appear to do the same thing. I found a UDF
DateConvertNoBug
that produces the expected result
{ts '2024-07-01 13:00:00'}
. Why is the built-in dateConvert producing the wrong time?
p
Looks like a bug to me
But not sure how to list out all zones or where CF/Java pulls those offsets from
r
Yeah, playing with this, I have no idea what dateConvert() is doing. In this example, it appears to be doubling the offset from UTC:
Copy code
<cfscript>
javatz = CreateObject("java", "java.util.TimeZone"); 
tz_list = javatz.getAvailableIDs();
writedump(var = tz_list, expand = false);

writeDump(getTimezone());
n = Now();
writeDump(n);

setTimezone('Etc/UTC');
writeDump(getTimezone());
d = Now();
writeDump(d);

setTimezone('America/Boise');
writeDump(getTimezone());
l = dateConvert('utc2local', d);
writeDump(l);
</cfscript>
d
dateConvert should be avoided I think!
p
I am struggling even getting this to work in cfscript with java based code; sounds like something with the JDK possibly?
r
I've wrestled with this a bit more. There's obviously way more going on here than I expected and my head exploded a few minutes ago when I started to get a sense of what is going on here:
Copy code
<cfscript>
writeDump(getTimezone());
n = Now();
writeDump(n);
setTimezone('America/Boise');
writeDump(getTimezone());
writeDump(n);
</cfscript>
Note that when you dump
n
before and after the
setTimezone()
call, its value changes... How is that even possible that a call to a function like that could go rippling through variables with values already assigned?
This seems to work and does seem to account for the US's switching to/from standard time to daylight savings time based on the date (e.g., the offset is different for 01-Jan vs 01-Jul):
Copy code
<cfscript>
setTimezone('America/Boise');
writeDump(getTimezone());

// Now, locally:
n = createDateTime(2024, 1, 1, 12, 0, 0);
writeDump(n);

u = dateConvert('local2utc', n);
writeDump(u);

l = dateConvert('utc2local', u);
writeDump(l);
</cfscript>
... and it seems to work in the same manner if I use 'Europe/London' for the timezone. Not sure if that helps? Used in that context,
dateConvert()
makes sense but clearly calling
setTimezone()
has massive implications for any date-time variables laying around in your code before and after the call. There is some serious BFM going on under the JDK covers, it seems?
This also may be why Lucee's implementation of
getTimezoneInfo()
includes arguments so you can ask for information about a specific timezone in case you need to do your own version of timezone-math. Adobe's does not support those same arguments and you're limited to getting information about the server's current timezone, whatever that might be.
d
Wow! Looks like I opened a can of worms here. I'll need to take another look tomorrow.
r
Yeah, it's quite a rabbit-hole to fall down...
j
If your server has a time zone of UTC then your myutc date will be the UTC time. When you set the set the time zone to "GB" your myutc date is then treated as in DST, so has 1 hour added. When you do the Date Convert it expects the date you provide to be a UTC date but you are providing a date that already has been adjusted for DST, so you get 1 hour added to the DST date not the UTC date.
👏🏻 1
d
I think I see where I may have made an incorrect assumption. When I set
myutcdt = createDateTime("2024","7","1","12","00","00");
I assumed this to be in UTC. So July 1st 2024 12pm. However, I think that the createDateTime function is actually creating a local time which means that the above date in UTC is actually July 1st 2024 11am. Therefore the createDatetime has to be converted to utc as in @rstewart last code example. Then it all makes sense. As usual trying to solve a problem that I created! head wall
Exactly @JohnT! Because I am UK based I am currently in UTC (GMT). But will be in BST (UTC+1) at the end of March. A user will always select their local date/time when creating an event on our platform - I just need to convert that to utc before putting in the db. The date/time can then be output to the end user based on the event location using the correct local time. In the past I have just stored the time as a varchar in the database with the assumption that it was the local time (all UK based) - we now have some overseas users so need to support multiple timezones.
b
I don't think "GB" is the same time-zone as "GMT"
d
I think you are right, GB will probably change based on BST which we have just gone into and is 1 hour ahead of GMT.