Consider the following date entries. I want DD/MM/YYYY
format for both input strings and output strings
<cfset SetLocale('indonesian') /> <!--- also set in Railo Admin --->
<cfdump var="#GetLocale()#" />
<cfdump var="#LSDateFormat('01/07/2014', 'dd/mm/yyy')#" />
<cfdump var="#LSDateFormat('31/07/2014', 'dd/mm/yyy')#" />
<cfdump var="#LSDateFormat(Now())#" />
Output:
string in <--- correct for 'indonesian'?
string 07/01/2014 <--- wrong
string 31/07/2014 <--- correct... maybe
string 31/07/2014 <--- correct... maybe
Indonesia uses DD/MM/YYYY
format but Railo seems to treat the date input string as a U.S. date unless it's "invalid" (U.S. month higher than 12).
The OS locale is: LC_TIME="en_AU.UTF-8"
(Australian). This locale also uses DD/MM/YYYY
So given that nothing I can see specifies a US date format and I'm using the LS
variant of the function why are my date input strings being interpreted as U.S. dates?
Actually I really don't like the DD/MM changing locale based on the MM value. I'm looking for an answer that actually validates the date is DD/MM/YYYY
as well (preferably using something built-in rather than a UDF).
The issue is that the date passed to lsDateFormat function is expected to be a date object. If you pass in a string coldfusion will try to convert the string into a date object for you. This automatic conversion will do this assuming the american date format.
You can test this by creating your date with the createDate function. You could quickly build your own date parsing function a sample I hacked together is found below:
NOTE: In a complete solution you will have to check if the response from the function is a unknown date and act accordingly.
<cfset SetLocale('indonesian') /> <!--- also set in Railo Admin --->
<cfdump var="#GetLocale()#" />
<cfdump var="#LSDateFormat('01/07/2014', 'dd/mm/yyy')#" />
<cfdump var="#LSDateFormat('31/07/2014', 'dd/mm/yyy')#" />
<cfdump var="#LSDateFormat(Now())#" />
<!--- Now with creating date objects--->
<cfdump var="#LSDateFormat(createDate(2014,07,01), 'dd/mm/yyy')#" />
<!--- Using our own date parser--->
<cfdump var="#LSDateFormat(udf_parseDate('01/07/2014'), 'dd/mm/yyyy')#" />
<cfdump var="#LSDateFormat(udf_parseDate('31/07/2014'), 'dd/mm/yyyy')#" />
<cffunction name="udf_parseDate" output="false" returntype="date">
<cfargument name="value" required="true" type="string">
<cfset var UNKNOWN_DATE = createDate(1900,1,1)>
<cfset var DELIMITER = "/">
<cfset var iDay = 0>
<cfset var iMonth = 0>
<cfset var iYear = 0>
<cftry>
<cfset iDay = getToken(arguments.value,1,DELIMITER)>
<cfset iMonth = getToken(arguments.value,2,DELIMITER)>
<cfset iYear = getToken(arguments.value,3,DELIMITER)>
<cfset tmp = createDate(iYear,iMonth,iDay)>
<cfcatch type="any">
<cfreturn UNKNOWN_DATE>
</cfcatch>
</cftry>
<cfreturn tmp>
</cffunction>
My advice would be to stay away from all the inbuild localisation features they more often then not don't work the way that one needs them to work in a fully localised application. especially if you need to support multiple locales at the same time. e.g. Time Zones.
UPDATE:
For the sake of completeness and technically more correct.
The locale you are setting is invalid. For a complete list of available locales do this:
<cfdump var="#Server.coldfusion.supportedlocales#">
You will then see the correct locale should be:
<cfset SetLocale('indonesian (indonesia)') />