Coldfusion Time Zone US->UK GMT - datetime

I am updating some code as we are now on a US server but we are based in the UK so our timezones need to be changed with both dates and times.
I created this script.
<cfset tztemp = GetTimeZoneInfo()>
<cfset isDST = tztemp.isDSTOn >
<cfif isDST eq "Yes">
<cfset dtGMT = #CreateODBCDateTime(DateAdd("s",tztemp.utcTotalOffset+3600,now()))#>
<cfelse>
<cfset dtGMT = #CreateODBCDateTime(DateAdd("s",tztemp.utcTotalOffset,now()))#>
</cfif>
My question is how would I change the value #dtGMT# into the formats below?
#DateFormat(Now(), "YYMMDD")#
#TimeFormat(Now(), "HHMM")#
Thankyou

#DateFormat(dtGMT, "YYMMDD")#
#TimeFormat(dtGMT "HHMM")#

Related

Closure compiler: variable define is undeclared

I'm trying to write a Coldfusion script that compresses JavaScript files using a recent version of Google's closure compiler.
This program ends with two errors:
JSC_UNDEFINED_VARIABLE. variable module is undeclared at jquery-3.1.1.js line 9767 : 12
JSC_UNDEFINED_VARIABLE. variable define is undeclared at jquery-3.1.1.js line 9784 : 13
I wonder what's the magic. module and define are common JS variables; I trust Closure knows them. What setting am I missing? Is there an extern missing? Do I have to set a certain CompilerOption?
<cfset options = createObject( "java", "com.google.javascript.jscomp.CompilerOptions" ).init()>
<cfset cl = createObject( "java", "com.google.javascript.jscomp.CompilationLevel" )>
<cfset wl = createObject( "java", "com.google.javascript.jscomp.WarningLevel" )>
<cfset cl.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options)>
<cfset cl.SIMPLE_OPTIMIZATIONS.setDebugOptionsForCompilationLevel(options)>
<cfset lm = createobject( "java", "com.google.javascript.jscomp.CompilerOptions$LanguageMode" )>
<cfset options.setEnvironment(options.Environment.BROWSER)>
<cfset schar = createobject( "java", "java.nio.charset.StandardCharsets")>
<cfset options.setOutputCharset( schar.UTF_8 )>
<cfset wl.VERBOSE.setOptionsForWarningLevel(options)>
<cfset comp = createObject( "java", "com.google.javascript.jscomp.Compiler" ).init()>
<cfset clr = createObject( "java", "com.google.javascript.jscomp.CommandLineRunner" )>
<cfset sourceFile = createObject( "java", "com.google.javascript.jscomp.SourceFile" )>
<cfset arrInputs = createObject( "java", "java.util.ArrayList" ).init()>
<cfset arrExterns = createObject( "java", "java.util.ArrayList" ).init()>
<cfset arrInputs.add(
sourceFile.fromCode(
javaCast( "string", "jquery-3.1.1.js" ),
javaCast( "string", fileRead( expandPath( "../advanced/js/jquery-3.1.1.js" ), "utf-8" ) )
)
)>
<cfset arrExterns.addAll( clr.getBuiltinExterns(options.Environment) )>
<cfset result = comp.compile( arrExterns, arrInputs , options )>
<cfoutput>
|#result.success#|
<cfloop from="1" to="#arrayLen( result.errors )#" index="i">
err: #result.errors[i]#<br>
</cfloop>
</cfoutput>
module and define are common JS variables
module is typically an indicator of the CommonJS module system. define is used by the AMD module system. Neither are default JS variables or known to browsers.
jQuery is using a Universal Module Definition pattern to export the jQuery object either as a module (CommonJS or AMD as appropriate), or if none are found, as a global variable. Closure-compiler can recognize this pattern and remove the module specific parts when the --process_common_js_modules flag is specified.

Coldfusion invalid date format [duplicate]

I'm working with a script that displays the date and time in ISO 8601 format like so: 2012-05-17T17:35:44.000Z.
but I would like it to display in the normal ColdFusion timestamp format when using the #Now()# notation
... so in this format: {ts '2012-05-17 17:35:44'}
How can I do this?
As of CF 10, ISO-8601 is supported directly by parseDateTime.
<cfset string = "1997-07-16T19:20:30+01:00">
<cfset date = parseDateTime(string, "yyyy-MM-dd'T'HH:mm:ssX")>
Runnable Example on TryCF.com
Pretty sure just a parse and then output will give it to you in the format you want :
#parseDateTime(REReplace("2012-05-17T17:35:44.000Z", "(\d{4})-?(\d{2})-?(\d{2})T([\d:]+).*", "\1-\2-\3 \4"))#
Edit: Fixed and tested. ;)
I think this is a more complete solution and elegant solution :
<cffunction name="ConvertISOToDateTime" access="private" returntype="date">
<cfargument name="ISODateString" required="yes" type="string" hint="Properly formed ISO-8601 dateTime String">
<cfscript>
// time formats have 2 ways of showing themselves: 1994-11-05T13:15:30Z UTC format OR 1994-11-05T08:15:30-05:00
local.initial_date = parseDateTime(REReplace(ISODateString, "(\d{4})-?(\d{2})-?(\d{2})T([\d:]+).*", "\1-\2-\3 \4"));
// If not in UTC format then we need to
if (right(arguments.ISODateString, 1) neq "Z") {
local.timeModifier = "";
//Now we determine if we are adding or deleting the the time modifier.
if (ISODateString contains '+' and listlen(listrest(ISODateString,"+"),":") eq 2){
local.timeModifier = listrest(ISODateString,"+");
local.multiplier = 1; // Add
} else if (listlen(listlast(ISODateString,"-"),":") eq 2) {
local.timeModifier = listlast(ISODateString,"-");
local.multiplier = -1; // Delete
}
if (len(local.timeModifier)){
local.initial_date = dateAdd("h", val(listfirst(local.timeModifier,":"))*local.multiplier,local.initial_date);
local.initial_date = dateAdd("m", val(listlast(local.timeModifier,":"))*local.multiplier,local.initial_date);
}
}
return local.initial_date;
</cfscript>
</cffunction>
Starting with CF2016, Tim Sylvester's answer becomes :
<cfset string = "1997-07-16T19:20:30+01:00">
<cfset date = parseDateTime(string, "yyyy-MM-dd'T'HH:nn:ssX")>
The mm mask has been deprecated and replaced with nn, which was not available with CF10 and CF11.
Warning : the mm mask behaviour also changed with CF2016 (+ 2018 & 2021), and the previous example would output {ts '1998-08-16 18:00:30'}.
That date string is in ISO format, there is a good example of how to convert it to a CF date object here:
...
<cfreturn ARGUMENTS.Date.ReplaceFirst(
"^.*?(\d{4})-?(\d{2})-?(\d{2})T([\d:]+).*$",
"$1-$2-$3 $4"
) />
Use createOdbcDate function. It is best to compare in query.
<cfquery name="GetVisits" >
SELECT v.ExecutiveID, eu.firstname, eu.lastname from Visits where
v.visitDate between #CreateODBCDate(DateFrom)#
AND #CreateODBCDate(DateTo)#
</cfquery>

CF 8 Decrypt function returning value enclosed with <pre> </pre>

I am using the following code to encrypt user password.
<cfset "EncryptedNewPass" = Encrypt(#HTMLCodeFormat(NewPass)#, Request.PasswordKey)>
Then compare it to the value stored in the database and it works fine. However, if i get the value from the database and use decrypt as follows
<cfset DecryptedPass = Decrypt(#getOrigPassFP.pass#, Request.PasswordKey)>
and do cfout, the value is wrapped with <pre> </pre> tag. The issue that I am having is since we also use the password to open a PDF document, it is throwing an error. I tried using replace to strip the tag but when it is displayed or passed to a variable, it still contains the <pre> tag.
You are putting the <pre> tags in there yourself!! What do you think HTMLCodeFormat() does??!
From the comments: I understand what you are saying but my issue is how do I remove the pre tags once it is decrypted before encrypting it back?
The following code is one example of how to remove the <PRE> and </PRE> tags from your decrypted values. (I am outputting all of the values so you can follow along when you execute this code.)
<cfset NewPass = "this_is_the_password">
<cfset PasswordKey = "this_is_the_really_weak_key">
<cfset EncryptedNewPass = Encrypt(HTMLCodeFormat(NewPass), PasswordKey)>
<cfset DecryptedPass = Decrypt(EncryptedNewPass, PasswordKey)>
<cfoutput>
<p>NewPass = #NewPass#</p>
<p>PasswordKey = #PasswordKey#</p>
<p>EncryptedNewPass = #EncryptedNewPass#</p>
<p>DecryptedPass = #HTMLEditFormat(DecryptedPass)#</p>
<cfif Left(DecryptedPass,5) EQ "<PRE>">
<cfset DecryptedPass = Right(DecryptedPass,(Len(DecryptedPass)-5))>
<p>Found and removed <PRE> tag = #HTMLEditFormat(DecryptedPass)#</p>
</cfif>
<cfif Right(DecryptedPass,6) EQ "</PRE>">
<cfset DecryptedPass = Left(DecryptedPass,(Len(DecryptedPass)-6))>
<p>Found and removed </PRE> tag = #HTMLEditFormat(DecryptedPass)#</p>
</cfif>
</cfoutput>
Looking at that code, this block will remove the <PRE> from the beginning of the string:
<cfif Left(DecryptedPass,5) EQ "<PRE>">
<cfset DecryptedPass = Right(DecryptedPass,(Len(DecryptedPass)-5))>
<p>Found and removed <PRE> tag = #HTMLEditFormat(DecryptedPass)#</p>
</cfif>
And this block will remove the </PRE> from the end of the string:
<cfif Right(DecryptedPass,6) EQ "</PRE>">
<cfset DecryptedPass = Left(DecryptedPass,(Len(DecryptedPass)-6))>
<p>Found and removed </PRE> tag = #HTMLEditFormat(DecryptedPass)#</p>
</cfif>
I only used HTMLEditFormat() to output the values for you to see in the browser. Do NOT use these functions when encrypting or decrypting your values.
You also need to be aware that the HTMLCodeFormat() function does more than just wrap the given string in <PRE> tags. That function also changes the characters: <, >, &, and " to their HTML character entity equivalent. If any of your users used those characters in their password then your decryption of them will fail (will not be equal to their actual password).
This function converts the following characters to HTML character entities:
Text character Encoding
< <
> >
& &
" "

Coldfusion Log Files and Timezone/Locales

We have an application that records information into a database and if there is an erorr, we are logging it in a log file. We have users spread across the globe. If something does happen, we'd like to record the timestamp of the issue but we need the timestamp to be uniformed meaning someone in Hong Kong vs California, should have the same timestamp with appropriate timezone offset. I dont know how to do this in CF.
Dealing with dates has always been a week skill set of mine and would appreciate some help figuring this one out.
Here is the code which writes out the log file
<cftry>
... insert into db here ...
<cfcatch type="any">
<cfset error_msg = '#createodbcdatetime(now())#|#cfcatch.Message#|#cfcatch.Detail#|#cgi.HTTP_REFERER#|#cgi.SERVER_NAME#|#cgi.SCRIPT_NAME#|#cgi.QUERY_STRING#'>
<cftry>
<cfif FileExists(ExpandPath(#log_name#))>
<cflock name="WebSiteErrorLog_Lock" type="exclusive" timeout="30">
<cffile action="append" addnewline="yes" file="#currentDirectory##log_name#" mode="777" output="#error_msg#">
</cflock>
<cfelse>
<cflock name="WebSiteErrorLog_Lock" type="exclusive" timeout="30">
<cffile action="write" addnewline="yes" file="#currentDirectory##log_name#" mode="777" output="#error_msg#">
</cflock>
</cfif>
<cfcatch type="any"></cfcatch>
</cftry>
</cfcatch>
but this line is probablly all that is really needed for this SO question:
<cfset error_msg = '#createodbcdatetime(now())#|#cfcatch.Message#|#cfcatch.Detail#|#cgi.HTTP_REFERER#|#cgi.SER
TIA
I am curious, are you using ColdFusion 9? Because you may want to look into implementing the OnError function in your Application.cfc. It may be a bit more convenient than this constant Try-Catch approach.
That being said, the following function will return formatted UTC time. I think I stole it from someone else's answer previously on this site.
<cffunction name="getUTCTime" access="public">
<cfscript>
var serverTime=now();
var utcTime=GetTimeZoneInfo();
var utcStruct=structNew();
utcStruct.Hour=DatePart("h", serverTime);
utcStruct.Minute=DatePart("n", serverTime);
utcStruct.Hour=utcStruct.Hour + utcTime.utcHourOffSet;
utcStruct.Minute=utcStruct.Minute + utcTime.utcMinuteOffSet;
if (utcStruct.Minute LT 10) utcStruct.Minute = "0" & utcStruct.Minute;
</cfscript>
<cfreturn utcStruct.Hour & ":" & utcStruct.Minute>
</cffunction>
Update:
As mentioned in the comments, the above code is unnecessary and buggy. Its preferable to use the built-in dateConvert() function (available since at least MX7):
<cfset timeString = timeFormat( dateConvert("local2utc", now()), "HH:mm")>

Use cfdirectory to find unmatched files in two directories and perform function

In my application the user uploads a photos and the cfc resizes the photo, creates a new image and resizes that new image to a thumbnail. Trouble is, this function wasn't available earlier on in the game. I want to now look at the images directory and figure out which images don't have thumbnails.
I'm thinking that I could use cfdirectory to output a struct of both directories then loop over the files that only exist in the images and not in the thumbnails directory and run a function to resize the images and send them to the thumbnails directory.
Is this flawed thinking? Is there an easier way?
That's a perfectly reasonable approach, and you don't even have to use recursive code. Just use the recursive option in CFDirectory to get a list of all files and use both the file name and path combined as the key, which guarantees a unique file you're checking. You may have to modify the result a bit so you know exactly where to put the new thumbnail, but this should get you pretty close.
<cfset originals_path = expandPath('originals') />
<cfset thumbs_path = expandPath('thumbs') />
<cfset no_thumbs = find_missing_thumbs(originals_path, thumbs_path) />
<cfdump var="#no_thumbs#" />
<cffunction name="find_missing_thumbs">
<cfargument name="o" />
<cfargument name="t" />
<cfset var originals = 0 />
<cfset var thumbs = 0 />
<cfset var missing_thumbs = [] />
<cfset var massaged_originals = 0 />
<cfset var massaged_thumbs = 0 />
<cfset var qSearch = 0 />
<cfdirectory action="list" directory="#arguments.o#" name="originals" recurse="true" />
<cfdirectory action="list" directory="#arguments.t#" name="thumbs" recurse="true" />
<cfquery name="massaged_originals" dbtype="query">
select name, directory + name as fullpath from originals
</cfquery>
<cfquery name="massaged_thumbs" dbtype="query">
select name, directory + name as fullpath from thumbs
</cfquery>
<cfloop query="massaged_originals">
<cfquery name="qSearch" dbtype="query">
select massaged_thumbs.name from massaged_thumbs where massaged_thumbs.fullpath = '#massaged_originals.fullpath#'
</cfquery>
<cfif qSearch.recordCount eq 0>
<cfset arrayAppend(missing_thumbs, massaged_originals.name) />
</cfif>
</cfloop>
<cfreturn missing_thumbs />
</cffunction>

Resources