Changeset 98

Show
Ignore:
Timestamp:
08/23/06 23:08:34 (7 years ago)
Author:
luis
Message:

Full i18n support thanks to the new cfc's by Paul Hastings, using core java.

Location:
coldbox/trunk/src/system
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • coldbox/trunk/src/system/eventhandler.cfc

    r66 r98  
    6666                <cfargument name="resource" type="string" hint="The resource to retrieve from the bundle."> 
    6767                <!--- ************************************************************* ---> 
    68                 <cfreturn getPlugin("i18n").getResource("#arguments.resource#")> 
     68                <cfreturn getPlugin("resourceBundle").getResource("#arguments.resource#")> 
    6969        </cffunction> 
    7070        <!--- ************************************************************* ---> 
  • coldbox/trunk/src/system/plugin.cfc

    r67 r98  
    4949                <cfargument name="resource" type="string" hint="The resource to retrieve from the bundle."> 
    5050                <!--- ************************************************************* ---> 
    51                 <cfreturn getPlugin("i18n").getResource("#arguments.resource#")> 
     51                <cfreturn getPlugin("resourceBundle").getResource("#arguments.resource#")> 
    5252        </cffunction> 
    5353        <!--- ************************************************************* ---> 
  • coldbox/trunk/src/system/plugins/i18n.cfc

    r58 r98  
    11<!----------------------------------------------------------------------- 
    2 Author: Paul Hastings, Raymond Camden, Luis Majano 
    3 Date: June 20, 2006 
    4 Purpose :       Locale utils. Lots of help from Paul Hastings. Basically, since CF's locale funcs 
    5                         don't accept Java locales, I wrote these functions instead. 
    6                         Most of these methods operate on the current locale. 
    7                         To Do - handle converting from UTC to local time, modded by user pref TZ 
    8 Description: 
    9 This is a resource bundles plugin which uses the standard Java locale names. 
    10 The storage mechanism is via the application scope: 
    11 application.ColdBox_ConfigStruct.RBundles["#arguments.rbLocale#"] 
    12  
    13 It makes use of the application scope and Paul Hastings cfc. 
    14 http://www.sustainablegis.com/unicode/resourceBundle/rb.cfm 
    15  
    16 For ISO Language Code information look at: 
    17 http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt 
    18  
    19 For ISO Country Code information look at: 
    20 http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html 
    21  
    22 For local information look at 
    23 http://java.sun.com/j2se/1.4.2/docs/guide/intl/locale.doc.html 
    24  
    25 Modifications: 
    26 Updated for ColdBox. 
     2 
     3author:         paul hastings <paul@sustainableGIS.com> 
     4date:           1-April-2004 
     5revisions:      25-jun-2004 added locale number formating 
     6                       7-jul-2004      added localized digit parsing 
     7                       11-jul-2004     added to/from Arabic-Indic digit functions 
     8                       12-jul-2004 added metadata function, getDecimalSymbols 
     9                       13-jul-2004 added localized country and language display functions, showLocaleCountry & showLocaleLanguage 
     10                       16-jul-2004 added method to return namepart for filtering/sorting on per locale basis 
     11                       16-aug-2004     added method to delete unicode named files/dirs 
     12                       3-feb-2005 swapped to ulocales 
     13                       20-feb-2005 added getCurrencySymbol method 
     14                       9-jul-2005 added i18nBigDecimalFormat 
     15                       30-may-2006 swapped to using java epoch offsets from datetimes 
     16                       16-jun-2006 added date math methods 
     17                       8-jul-2006 version for coldbox 
     18notes: 
     19this CFC contains a several util I18N functions. all valid java locales are supported. it requires the use 
     20of cfobject. 
     21 
     22methods in this CFC: 
     23       - getLocales returns LIST of java style locales (en_US,etc.) available on this server. PUBLIC 
     24       - getLocaleNames returns LIST of java style locale names available on this server. PUBLIC 
     25       - isBIDI returns boolean indicating whether given locale uses lrt to rtl writing sysem direction. 
     26       required argument is thisLocale. PUBLIC 
     27       - isValidLocale returns BOOLEAN indicating whether a given locale is valid on this server. should 
     28       be used for locale validation prior to passing to this CFC. takes one required argument, thisLocale, 
     29       string such as "en_US", "th_TH", etc. PUBLIC 
     30       - showCountry: returns country display name in english from given locale, takes 
     31       one required argument, thisLocale. returns string. PUBLIC 
     32       - showLanguage: returns language display name in english from given locale, takes 
     33       one required argument, thisLocale. returns string. PUBLIC 
     34       - showLocaleCountry: returns localized country display name from given locale, takes 
     35       one required argument, thisLocale. returns string. PUBLIC 
     36       - showLocaleLanguage: returns localized language display name from given locale, takes 
     37       one required argument, thisLocale. returns string. PUBLIC 
     38       - getDecimalSymbols METADATA function, returns structure holding various decimal format symbols for 
     39       given locale. required argument is thisLocale, valid java style locale. PUBLIC 
     40       - getCurrencySymbol METADATA function, returns international (USD, THB, 
     41       etc.) or localized  currency symbol for given locale. required argument is thisLocale, 
     42       valid java style locale. optional boolean argument is localized to return localized or 
     43       international currency symbol. defaults to true (localized). PUBLIC 
     44 
     45Modifications 
     46 
     4708/20/2006 Luis Majano - Modified for ColdBox 
    2748-----------------------------------------------------------------------> 
    2849<cfcomponent name="i18n" 
     
    3455        <!--- ************************************************************* ---> 
    3556        <cffunction name="init" access="public" returntype="any" hint="Constructor" output="false"> 
    36                 <cfset super.Init() /> 
    37                 <cfset variables.instance.pluginName = "i18N and Resource Bundles"> 
    38                 <cfset variables.instance.pluginVersion = "1.0"> 
    39                 <cfset variables.instance.pluginDescription = "Internationalization and Bundles plugin, based on Paul Hastings Brain."> 
    40                 <!--- This plugin's properties ---> 
    41                 <cfset variables.instance.thisLocale = ""> 
    42                 <cfset variables.instance.lang = ""> 
    43                 <cfset variables.instance.country = ""> 
    44                 <cfset variables.instance.BIDIlanguages= ""> 
    45                 <cfset variables.instance.localeName= ""> 
    46                 <cfset variables.instance.aDateFormat= ""> 
    47                 <cfset variables.instance.sDateFormat= ""> 
    48                 <cfset variables.instance.aCalendar= ""> 
    49                 <cfset variables.instance.dateSymbols= ""> 
    50                 <cfreturn this> 
    51         </cffunction> 
    52         <!--- ************************************************************* ---> 
    53  
    54 <!------------------------------------------- PUBLIC -------------------------------------------> 
    55  
    56         <!--- ************************************************************* ---> 
    57         <cffunction name="initBundle" access="public" output="No" hint="Reads,parses and saves the resource bundle per locale in internal ColdBox structures." returntype="void"> 
     57                <cfscript> 
     58                super.Init(); 
     59                variables.instance.pluginName = "Internationalization (i18N)"; 
     60                variables.instance.pluginVersion = "1.0.0 coldbox core java"; 
     61                variables.instance.pluginDescription = "Internationalization and Bundles plugin based on Paul Hastings Brain."; 
     62                //<!--- This plugin's properties ---> 
     63                variables.instance.aDFSymbol=createObject("java","java.text.DecimalFormatSymbols"); 
     64                variables.instance.aDateFormat=createObject("java","java.text.DateFormat"); 
     65                variables.instance.aLocale=createObject("java","java.util.Locale"); 
     66                variables.instance.timeZone=createObject("java","java.util.TimeZone"); 
     67                variables.instance.thisLocale = ""; //Setup by the loadLocale() method. 
     68                loadLocale(); 
     69                variables.instance.aCalendar=createObject("java","java.util.GregorianCalendar").init(variables.instance.thisLocale); 
     70                variables.instance.dateSymbols = createObject("java","java.text.DateFormatSymbols").init(variables.instance.thisLocale); 
     71                variables.instance.I18NUtilDate="23-aug-2006"; //should be date of latest change 
     72                return this; 
     73                </cfscript> 
     74        </cffunction> 
     75        <!--- ************************************************************* ---> 
     76 
     77        <!--- ************************************************************* ---> 
     78        <cffunction name="init_i18N" access="public" output="No" hint="Reads,parses,saves the locale and resource bundles defined in the config.xml. Called only internally by the framework. Use at your own risk" returntype="void"> 
    5879                <!--- ************************************************************* ---> 
    5980                <cfargument name="rbFile"   required="Yes" type="string" hint="This must be the path + filename UP to but NOT including the locale. We auto-add .properties to the end."> 
     
    6182                <!--- ************************************************************* ---> 
    6283                <!--- Load the default Bundle ---> 
    63                 <cfset loadBundle(arguments.rbFile, arguments.rbLocale)> 
     84                <cfset getPlugin("resourceBundle").loadBundle(arguments.rbFile, arguments.rbLocale)> 
    6485                <!--- Set the default Locale ---> 
    6586                <cfset setfwLocale(arguments.rbLocale,true)> 
    6687        </cffunction> 
    6788        <!--- ************************************************************* ---> 
    68  
    69         <!--- ************************************************************* ---> 
    70         <cffunction name="loadBundle" access="public" output="No" hint="Reads,parses and saves the resource bundle per locale in internal ColdBox structures." returntype="void"> 
    71                 <!--- ************************************************************* ---> 
    72                 <cfargument name="rbFile"   required="Yes" type="string" hint="This must be the path + filename UP to but NOT including the locale. We auto-add .properties to the end."> 
    73                 <cfargument name="rbLocale" required="No"  type="string" default="en_US"> 
    74                 <!--- ************************************************************* ---> 
    75                 <cfset var resourceBundle=structNew()> 
    76                 <cfset var fallbackLocale="en_US"> <!--- might change to reflect your locale ---> 
    77                 <cfset var resourceBundleFile = ""> 
    78                 <cfset var rbIndx = ""> 
    79  
    80                 <!--- Translate rbFile ---> 
    81                 <cfset arguments.rbFile = arguments.rbFile & "_#arguments.rbLocale#.properties"> 
    82                 <cfif NOT fileExists(arguments.rbFile)> 
    83                         <cfthrow type="Framework.plugins.i18N.FileNotFoundException" message="Fatal error: resource bundle #arguments.rbFile# not found."> 
     89         
     90<!------------------------------------------- PUBLIC -------------------------------------------> 
     91         
     92        <!--- ************************************************************* ---> 
     93        <cffunction name="setfwLocale" access="public" output="false" returnType="any" hint="Set the default locale to use in the framework."> 
     94                <!--- ************************************************************* ---> 
     95                <cfargument name="locale"     type="string"  required="false"  default="#getSetting("DefaultLocale")#"   hint="The locale to change and set. Must be Java Style: en_US"> 
     96                <cfargument name="loadRBFlag" type="boolean" required="false"  default="false" hint="Flag to load the resource bundle for the specified locale (If not already loaded) or just change the framework's locale."> 
     97                <!--- ************************************************************* ---> 
     98                 
     99                <!--- Resource Bundle Loading Check ---> 
     100                <cfif not arguments.loadRBFlag and not structKeyExists(getSetting("RBundles"),arguments.locale)> 
     101                        <cfset getPlugin("resourceBundle").loadBundle(getSetting("DefaultResourceBundle"),arguments.locale)> 
    84102                </cfif> 
    85  
    86                 <!--- Read RB File Contents ---> 
    87                 <cffile action="read" file="#arguments.rbFile#" variable="resourceBundleFile" charset="utf-8"> 
    88  
    89                 <!--- Create Key Structure ---> 
    90                 <cfloop index="rbIndx" list="#resourceBundleFile#" delimiters="#chr(10)#"> 
    91                         <cfif len(trim(rbIndx)) and left(rbIndx,1) NEQ "##"> 
    92                                 <cfset resourceBundle[trim(listFirst(rbIndx,"="))] = trim(listRest(rbIndx,"="))> 
    93                         </cfif> 
    94                 </cfloop> 
    95                 <!--- Place resource bundle in ColdBox's Storage ---> 
    96                 <cfset setSetting("RBundles.#arguments.rbLocale#",resourceBundle)> 
    97         </cffunction> 
    98         <!--- ************************************************************* ---> 
    99  
    100         <!--- ************************************************************* ---> 
    101         <cffunction name="getResource" access="public" output="false" returnType="any" hint="Returns bundle.X, if it exists, according to locale"> 
    102                 <!--- ************************************************************* ---> 
    103                 <cfargument name="resource" type="string" required="true" hint="The resource to retrieve from the bundle."> 
    104                 <!--- ************************************************************* ---> 
    105                 <cfset var val = ""> 
    106                 <cfset var Bundle = ""> 
    107                 <!--- Check For Bundle ---> 
    108                 <cfif not structKeyExists(getSetting("RBundles"),getfwLocale())> 
    109                         <cfthrow type="Framework.plugins.i18N.BundleNotLoadedException" message="Fatal error: resource bundle for locale: #getfwLocale()# has not been loaded."> 
    110                 </cfif> 
    111                 <cfset Bundle = getSetting("RBundles.#getfwLocale()#")> 
    112                 <!--- Check for Key ---> 
    113                 <cfif not structKeyExists(Bundle, arguments.resource)> 
    114                         <cfset val = "_UNKNOWNTRANSLATION_"> 
    115                 <cfelse> 
    116                         <cfset val = Bundle[arguments.resource]> 
    117                 </cfif> 
    118                 <cfreturn val> 
    119         </cffunction> 
    120         <!--- ************************************************************* ---> 
    121  
    122         <!--- ************************************************************* ---> 
    123         <cffunction name="setfwLocale" access="public" output="false" returnType="void" hint="Set the default locale to use."> 
    124                 <!--- ************************************************************* ---> 
    125                 <cfargument name="locale"     type="string" required="true"   hint="The locale to retrieve the key from."> 
    126                 <cfargument name="onLoadFlag" type="boolean" required="false" default="false" hint="Flag to skip bundle loading check, locale already set."> 
    127                 <!--- ************************************************************* ---> 
    128                 <!--- Setup fw Locale ---> 
    129                 <cfif not arguments.onLoadFlag and not structKeyExists(getSetting("RBundles"),arguments.locale)> 
    130                         <cfset loadBundle(getSetting("DefaultResourceBundle"),arguments.locale)> 
    131                 </cfif> 
     103                 
     104                <!--- Storage of the Locale ---> 
    132105                <cfif getSetting("LocaleStorage") eq "session"> 
    133106                        <cfset session.DefaultLocale = arguments.locale> 
     
    135108                        <cfset client.DefaultLocale = arguments.locale> 
    136109                </cfif> 
    137                 <!--- The following are to setup the cfc for instantiation usage. Only used if this plugin is placed on a sccope ---> 
    138                 <cfif not listLen(arguments.locale,"_") is 2 or 
    139                           not len(listFirst(arguments.locale,"_")) is 2 or 
    140                           not len(listLast(arguments.locale,"_")) is 2> 
    141                         <cfthrow type="Framework.plugins.i18N.InvalidLocalSyntaxException" message="Specified locale: #arguments.locale# must be of the form language_country where language and country are 2 characters each, en_US, fr_FR, etc."> 
    142                 </cfif> 
    143                 <cfset instance.lang = listFirst(arguments.locale,"_")> 
    144                 <cfset instance.country = listLast(arguments.locale,"_")> 
    145                 <cfset instance.BIDIlanguages="ar,he,fa,ps"><!--- couple more BIDI writing systems ---> 
    146                 <cfset instance.thisLocale=createObject("java","java.util.Locale").init(instance.lang, instance.country)> 
    147                 <cfset instance.localeName=instance.thisLocale.getDisplayName(instance.thisLocale)> 
    148                 <cfset instance.aDateFormat=createObject("java","java.text.DateFormat")> 
    149                 <cfset instance.sDateFormat=createObject("java","java.text.SimpleDateFormat")> 
    150                 <cfset instance.aCalendar=createObject("java","java.util.GregorianCalendar").init(instance.thisLocale)> 
    151                 <cfset instance.dateSymbols=createObject("java","java.text.DateFormatSymbols").init(instance.thisLocale)> 
    152         </cffunction> 
    153         <!--- ************************************************************* ---> 
    154  
    155         <!--- ************************************************************* ---> 
    156         <cffunction name="getAvailableLocales" access="public" returnType="any" output="false" 
    157                                 hint="Returns an array of locales."> 
    158                 <cfscript> 
    159                 var i=0; 
    160                 var orgLocales=createObject("java","java.util.Locale").getAvailableLocales(); 
    161                 var theseLocales=arrayNew(1); 
    162                 // we skip plain languages, en, fr, ar, etc. 
    163                 for (i=1; i LTE arrayLen(orgLocales); i=i+1) { 
    164                         if (listLen(orgLocales[i],"_") GT 1) { 
    165                         arrayAppend(theseLocales,orgLocales[i]); 
    166                         } // if 
    167                 } //for 
    168                 return theseLocales; 
    169                 </cfscript> 
    170         </cffunction> 
    171         <!--- ************************************************************* ---> 
    172  
    173         <!--- ************************************************************* ---> 
    174         <cffunction name="getfwLocale" access="public" output="false" returnType="any" hint="Get the default locale."> 
     110                 
     111                <!--- Locale Instance Setup ---> 
     112                <cfset loadLocale(arguments.locale)> 
     113                 
     114                <cfreturn this> 
     115        </cffunction> 
     116        <!--- ************************************************************* ---> 
     117         
     118        <!--- ************************************************************* ---> 
     119        <cffunction name="getfwLocale" access="public" output="false" returnType="string" hint="Get the default locale string used in the framework."> 
    175120                <cfswitch expression="#getSetting("LocaleStorage")#"> 
    176121                        <cfcase value="session" > 
     
    192137        </cffunction> 
    193138        <!--- ************************************************************* ---> 
    194  
    195         <!--- ************************************************************* ---> 
    196         <cffunction name="instanceCheck" access="public" returnType="void" output="false" hint="Check if the plugin is called as instance or method."> 
    197                 <cfif instance.thisLocale eq ""> 
    198                         <cfthrow type="Framework.plugins.i18N.NoInstanceException" message="This method was called directly. This method only works if you have placed this plugin in a scope."> 
     139         
     140        <!--- ************************************************************* ---> 
     141        <cffunction name="loadLocale" access="public" returnType="void" output="false"  hint="Loads a locale."> 
     142                <!--- ************************************************************* ---> 
     143                <cfargument name="locale" type="string" required="false" default="en_US" /> 
     144            <!--- ************************************************************* ---> 
     145                <cfif not isValidLocale(arguments.locale)> 
     146                        <cfthrow message="Specified locale must be of the form language_COUNTRY_VARIANT where language, country and variant are 2 characters each, ISO 3166 standard." type="Framework.plugins.i18n.InvalidLocaleException" /> 
    199147                </cfif> 
    200         </cffunction> 
    201         <!--- ************************************************************* ---> 
    202  
    203         <!--- ************************************************************* ---> 
    204         <cffunction name="isBIDI" access="public" returnType="any" output="false" hint="Needs object instantiation. That is your job not mine."> 
    205                 <cfset instanceCheck()> 
    206                 <cfreturn listFind(instance.BIDILanguages,instance.lang)> 
    207         </cffunction> 
    208         <!--- ************************************************************* ---> 
    209  
    210         <!--- ************************************************************* ---> 
    211         <cffunction name="dateLocaleFormat" access="public" returnType="any" output="false" 
    212                                 hint="locale version of dateFormat. Needs object instantiation. That is your job not mine."> 
    213                 <!--- ************************************************************* ---> 
    214                 <cfargument name="date" type="date" required="true"> 
    215                 <cfargument name="style" type="string" required="false" default="LONG"> 
    216                 <!--- ************************************************************* ---> 
    217                 <cfscript> 
    218                 //Instance Check 
    219                 instanceCheck(); 
    220                 // hack to trap & fix varchar mystery goop coming out of mysql datetimes 
    221                 try { 
    222                         return instance.aDateFormat.getDateInstance(instance.aDateFormat[arguments.style],instance.thisLocale).format(arguments.date); 
    223                 } 
    224                 catch(Any e) { 
    225                         instance.aCalendar.setTime(arguments.date); 
    226                         return instance.aDateFormat.getDateInstance(instance.aDateFormat[arguments.style],instance.thisLocale).format(instance.aCalendar.getTime()); 
    227                 } 
    228                 </cfscript> 
    229         </cffunction> 
    230         <!--- ************************************************************* ---> 
    231  
    232         <!--- ************************************************************* ---> 
    233         <cffunction name="getLocalizedDays" access="public" returnType="any" output="false" 
    234                                 hint="Returns localized days. Needs object instantiation. That is your job not mine."> 
    235                 <cfscript> 
    236                 var localizedShortDays=""; 
    237                 var i=0; 
    238                 var tmp=""; 
    239                 //Instance Check 
    240                 instanceCheck(); 
    241                 tmp = instance.dateSymbols.getShortWeekdays(); 
    242                 // kludge java returns NULL first element in array so can't use arrayDeleteAt 
    243                 tmp=listToArray(arrayToList(tmp)); 
    244                 // more kludge, fixup days to match week start 
    245                 switch (weekStarts()) { 
    246                         case 1:  //starts on sunday, just return day names 
    247                                 localizedShortDays=tmp; 
    248                         break; 
    249  
    250                         case 2: // euro dates, starts on monday needs kludge 
    251                                 localizedShortDays=arrayNew(1); 
    252                                 localizedShortDays[7]=tmp[1]; //move sunday to last 
    253                                 for (i=1; i LTE 6; i=i+1) { 
    254                                         localizedShortDays[i]=tmp[i+1]; 
    255                                 } 
    256                         break; 
    257  
    258                         case 7: // starts saturday, usually arabic, needs kludge 
    259                                 localizedShortDays=arrayNew(1); 
    260                                 localizedShortDays[1]=tmp[7]; //move saturday to first 
    261                                 for (i=1; i LTE 6; i=i+1) { 
    262                                         localizedShortDays[i+1]=tmp[i]; 
    263                                 } 
    264                         break; 
    265                 } 
    266                 return localizedShortDays; 
    267                 </cfscript> 
    268         </cffunction> 
    269         <!--- ************************************************************* ---> 
    270  
    271         <!--- ************************************************************* ---> 
    272         <cffunction name="getLocalizedMonth" access="public" returnType="any" output="false" 
    273                                 hint="Returns localized month.  Needs object instantiation. That is your job not mine."> 
    274                 <!--- ************************************************************* ---> 
    275                 <cfargument name="month" type="numeric" required="true"> 
    276                 <!--- ************************************************************* ---> 
    277                 <cfscript> 
    278                 instanceCheck(); 
    279                 instance.sDateFormat.init("MMMM",instance.thisLocale); 
    280                 return instance.sDateFormat.format(createDate(1999,arguments.month,1)); 
    281                 </cfscript> 
    282         </cffunction> 
    283         <!--- ************************************************************* ---> 
    284  
    285         <!--- ************************************************************* ---> 
    286         <cffunction name="getLocalizedYear" access="public" returnType="any" output="false" 
    287                                 hint="Returns localized year, probably only useful for BE calendars like in thailand, etc. Needs object instantiation. That is your job not mine."> 
    288                 <!--- ************************************************************* ---> 
    289                 <cfargument name="thisYear" type="numeric" required="true"> 
    290                 <!--- ************************************************************* ---> 
    291                 <cfscript> 
    292                 instanceCheck(); 
    293                 instance.sDateFormat.init("yyyy",instance.thisLocale); 
    294                 return instance.sDateFormat.init("yyyy",instance.thisLocale).format(createDate(arguments.thisYear,1,1)); 
    295                 </cfscript> 
    296         </cffunction> 
    297         <!--- ************************************************************* ---> 
    298  
     148                <cfset instance.thisLocale = buildLocale(arguments.locale) /> 
     149        </cffunction> 
     150        <!--- ************************************************************* ---> 
     151         
     152        <!--- ************************************************************* ---> 
     153        <cffunction name="isValidLocale"  access="public" output="false" returntype="boolean" hint="Validate a locale"> 
     154                <!--- ************************************************************* ---> 
     155                <cfargument name="thisLocale" required="yes" type="string" hint="Locale to validate"> 
     156                <!--- ************************************************************* ---> 
     157                <cfif listFind(arrayToList(getLocales()),arguments.thisLocale)> 
     158                        <cfreturn true> 
     159                <cfelse> 
     160                        <cfreturn false> 
     161                </cfif> 
     162        </cffunction> 
     163        <!--- ************************************************************* ---> 
     164         
     165        <!--- ************************************************************* ---> 
     166        <cffunction name="getLocales" access="public" output="false" returntype="array" hint="returns array of locales"> 
     167        <cfreturn instance.aLocale.getAvailableLocales()> 
     168        </cffunction> 
     169        <!--- ************************************************************* ---> 
     170         
     171        <!--- ************************************************************* ---> 
     172        <cffunction access="public" name="getLocaleNames" output="false" returntype="string" hint="returns list of locale names, UNICODE direction char (LRE/RLE) added as required"> 
     173        <cfscript> 
     174               var orgLocales=getLocales(); 
     175               var theseLocales=""; 
     176               var thisName=""; 
     177               var i=0; 
     178               for (i=1; i LTE arrayLen(orgLocales); i=i+1) { 
     179                       if (listLen(orgLocales[i],"_") EQ 2) { 
     180                               if (left(orgLocales[i],2) EQ "ar" or left(orgLocales[i],2) EQ "iw") 
     181                                       thisName=chr(8235)&orgLocales[i].getDisplayName(orgLocales[i])&chr(8234); 
     182                               else 
     183                                       thisName=orgLocales[i].getDisplayName(orgLocales[i]); 
     184                               theseLocales=listAppend(theseLocales,thisName); 
     185                       } // if locale more than language 
     186               } //for 
     187               return theseLocales; 
     188        </cfscript> 
     189        </cffunction> 
     190        <!--- ************************************************************* ---> 
     191         
     192        <!--- ************************************************************* ---> 
     193        <cffunction name="getISOlanguages"  access="public" output="false" returntype="array" hint="returns array of 2 letter ISO languages"> 
     194        <cfreturn instance.aLocale.getISOLanguages()> 
     195        </cffunction> 
     196        <!--- ************************************************************* ---> 
     197         
     198        <!--- ************************************************************* ---> 
     199        <cffunction name="getISOcountries" access="public"  output="false" returntype="array" hint="returns array of 2 letter ISO countries"> 
     200        <cfreturn instance.aLocale.getISOCountries()> 
     201        </cffunction> 
     202        <!--- ************************************************************* ---> 
     203         
     204        <!--- ************************************************************* ---> 
     205        <cffunction name="showCountry" access="public" output="false" returntype="string" hint="returns display country name for given locale"> 
     206       <cfreturn instance.thisLocale.getDisplayCountry()> 
     207        </cffunction> 
     208        <!--- ************************************************************* ---> 
     209         
     210        <!--- ************************************************************* ---> 
     211        <cffunction name="showISOCountry" access="public" output="false" returntype="string" hint="returns 2-letter ISO country name for given locale"> 
     212                <cfreturn instance.thisLocale.getCountry()> 
     213        </cffunction> 
     214        <!--- ************************************************************* ---> 
     215         
     216        <!--- ************************************************************* ---> 
     217        <cffunction name="showLanguage" access="public" output="false" returntype="string" hint="returns display country name for given locale"> 
     218                <cfreturn instance.thisLocale.getDisplayLanguage()> 
     219        </cffunction> 
     220        <!--- ************************************************************* ---> 
     221         
     222        <!--- ************************************************************* ---> 
     223        <cffunction name="showLocaleCountry" access="public" output="false" returntype="string" hint="returns display country name for given locale"> 
     224                <cfreturn instance.thisLocale.getDisplayCountry(variables.thisLocale)> 
     225        </cffunction> 
     226        <!--- ************************************************************* ---> 
     227         
     228        <!--- ************************************************************* ---> 
     229        <cffunction name="showLocaleLanguage" access="public" output="false" returntype="string" hint="returns display country name for given locale"> 
     230                <cfreturn instance.thisLocale.getDisplayLanguage(variables.thisLocale)> 
     231        </cffunction> 
     232        <!--- ************************************************************* ---> 
     233 
     234        <!--- ************************************************************* ---> 
     235        <!--- core java uses 'iw' for hebrew, leaving 'he' just in case this is a version thing ---> 
     236        <cffunction name="isBidi" access="public" output="No" returntype="boolean" hint="determines if given locale is BIDI"> 
     237                <cfif listFind("ar,iw,fa,ps,he",left(instance.thisLocale.toString(),2))> 
     238                        <cfreturn true> 
     239                <cfelse> 
     240                        <cfreturn false> 
     241                </cfif> 
     242        </cffunction> 
     243        <!--- ************************************************************* ---> 
     244         
     245        <!--- ************************************************************* ---> 
     246        <cffunction name="getCurrencySymbol" access="public" returntype="string" output="false" hint="returns currency symbol for this locale"> 
     247                <!--- ************************************************************* ---> 
     248                <cfargument name="localized" required="no" type="boolean" default="true" hint="return international (USD, THB, etc.) or localized ($,etc.) symbol"> 
     249                <!--- ************************************************************* ---> 
     250                <cfset var aCurrency=createObject("java","com.ibm.icu.util.Currency")> 
     251                <cfset var tmp=arrayNew(1)> 
     252                <cfif arguments.localized> 
     253                        <cfset arrayAppend(tmp,true)> 
     254                    <cfreturn aCurrency.getInstance(instance.thisLocale).getName(instance.thisLocale,aCurrency.SYMBOL_NAME,tmp)> 
     255                <cfelse> 
     256                    <cfreturn aCurrency.getInstance(instance.thisLocale).getCurrencyCode()> 
     257                </cfif> 
     258        </cffunction> 
     259        <!--- ************************************************************* ---> 
     260         
     261        <!--- ************************************************************* ---> 
     262        <cffunction name="getDecimalSymbols"  access="public"  output="false" returntype="struct" hint="returns strucure holding decimal format symbols for this locale"> 
     263        <cfscript> 
     264               var dfSymbols=instance.aDFSymbol.init(instance.thisLocale); 
     265               var symbols=structNew(); 
     266               symbols.plusSign=dfSymbols.getPlusSign().toString(); 
     267               symbols.Percent=dfSymbols.getPercent().toString(); 
     268               symbols.minusSign=dfSymbols.getMinusSign().toString(); 
     269               symbols.currencySymbol=dfSymbols.getCurrencySymbol().toString(); 
     270               symbols.internationCurrencySymbol=dfSymbols.getInternationalCurrencySymbol().toString(); 
     271               symbols.monetaryDecimalSeparator=dfSymbols.getMonetaryDecimalSeparator().toString(); 
     272               symbols.exponentSeparator=dfSymbols.getExponentSeparator().toString(); 
     273               symbols.perMille=dfSymbols.getPerMill().toString(); 
     274               symbols.decimalSeparator=dfSymbols.getDecimalSeparator().toString(); 
     275               symbols.groupingSeparator=dfSymbols.getGroupingSeparator().toString(); 
     276               symbols.zeroDigit=dfSymbols.getZeroDigit().toString(); 
     277               return symbols; 
     278        </cfscript> 
     279        </cffunction> 
     280        <!--- ************************************************************* ---> 
     281         
     282        <!--- ************************************************************* ---> 
     283        <cffunction name="i18nDateTimeFormat" access="public" output="No" returntype="string"> 
     284                <!--- ************************************************************* ---> 
     285                <cfargument name="thisOffset" required="yes" type="numeric" hint="java epoch offset"> 
     286                <cfargument name="thisDateFormat" default="1" required="No" type="numeric"> 
     287                <cfargument name="thisTimeFormat" default="1" required="No" type="numeric"> 
     288                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     289                <!--- ************************************************************* ---> 
     290               <cfset var tDateFormat=javacast("int",arguments.thisDateFormat)> 
     291               <cfset var tTimeFormat=javacast("int",arguments.thisTimeFormat)> 
     292               <cfset var tDateFormatter=instance.aDateFormat.getDateTimeInstance(tDateFormat,tTimeFormat,instance.thisLocale)> 
     293               <cfset var tTZ=instance.timeZone.getTimezone(arguments.tz)> 
     294               <cfset tDateFormatter.setTimezone(tTZ)> 
     295               <cfreturn tDateFormatter.format(arguments.thisOffset)> 
     296        </cffunction> 
     297        <!--- ************************************************************* ---> 
     298         
     299        <!--- ************************************************************* ---> 
     300        <cffunction name="i18nDateFormat" access="public" output="No" returntype="string"> 
     301                <!--- ************************************************************* ---> 
     302                <cfargument name="thisOffset" required="yes" type="numeric" hint="java epoch offset"> 
     303                <cfargument name="thisDateFormat" default="1" required="No" type="numeric"> 
     304                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     305                <!--- ************************************************************* ---> 
     306                   <cfset var tDateFormat=javacast("int",arguments.thisDateFormat)> 
     307               <cfset var tDateFormatter=instance.aDateFormat.getDateInstance(tDateFormat,instance.thisLocale)> 
     308               <cfset var tTZ=instance.timeZone.getTimezone(arguments.tz)> 
     309               <cfset tDateFormatter.setTimezone(tTZ)> 
     310               <cfreturn tDateFormatter.format(arguments.thisOffset)> 
     311        </cffunction> 
     312        <!--- ************************************************************* ---> 
     313         
     314        <!--- ************************************************************* ---> 
     315        <cffunction name="i18nTimeFormat" access="public" output="No" returntype="string"> 
     316                <!--- ************************************************************* ---> 
     317                <cfargument name="thisOffset" required="yes" type="numeric" hint="java epoch offset"> 
     318                <cfargument name="thisTimeFormat" default="1" required="No" type="numeric"> 
     319                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     320            <!--- ************************************************************* ---> 
     321               <cfset var tTimeFormat=javacast("int",arguments.thisTimeFormat)> 
     322               <cfset var tTimeFormatter=instance.aDateFormat.getTimeInstance(tTimeFormat,instance.thisLocale)> 
     323               <cfset var tTZ=instance.timeZone.getTimezone(arguments.tz)> 
     324               <cfset tTimeFormatter.setTimezone(tTZ)> 
     325               <cfreturn tTimeFormatter.format(arguments.thisOffset)> 
     326        </cffunction> 
     327        <!--- ************************************************************* ---> 
     328         
    299329        <!--- ************************************************************* ---> 
    300330        <cffunction name="timeLocaleFormat" access="public" returnType="any" output="false" 
    301331                                hint="locale version of timeFormat. Needs object instantiation. That is your job not mine."> 
    302332                <!--- ************************************************************* ---> 
    303                 <cfargument name="date"  type="date" required="true"> 
    304                 <cfargument name="style" type="string" required="false" default="SHORT"> 
     333                <cfargument name="date"  type="date"    required="true"> 
     334                <cfargument name="style" type="string"  required="false" default="SHORT"> 
    305335                <!--- ************************************************************* ---> 
    306336                <cfscript> 
    307                 instanceCheck(); 
    308337                // hack to trap & fix varchar mystery goop coming out of mysql datetimes 
    309338                try { 
     
    317346        </cffunction> 
    318347        <!--- ************************************************************* ---> 
    319  
     348         
    320349        <!--- ************************************************************* ---> 
    321350        <cffunction name="datetimeLocaleFormat" access="public" returnType="any" output="false" 
     
    327356                <!--- ************************************************************* ---> 
    328357                <cfscript> 
    329                 instanceCheck(); 
    330358                // hack to trap & fix varchar mystery goop coming out of mysql datetimes 
    331359                try { 
     
    333361                } 
    334362                catch (Any e) { 
    335                         instance.aCalendar.setTime(arguments.date); 
     363                        variables.aCalendar.setTime(arguments.date); 
    336364                        return instance.aDateFormat.getDateTimeInstance(instance.aDateFormat[arguments.dateStyle],instance.aDateFormat[arguments.timeStyle],instance.thisLocale).format(instance.aCalendar.getTime()); 
    337365                } 
     
    339367        </cffunction> 
    340368        <!--- ************************************************************* ---> 
    341  
    342         <!--- ************************************************************* ---> 
    343         <cffunction name="weekStarts" access="public" returnType="any" output="false" 
    344                                 hint="Determines the first DOW. Needs object instantiation. That is your job not mine."> 
     369         
     370        <!--- ************************************************************* ---> 
     371        <cffunction name="i18nDateParse" access="public" output="No" returntype="numeric" hint="parses localized date string to datetime object or returns blank if it can't parse"> 
     372                <!--- ************************************************************* ---> 
     373                <cfargument name="thisDate" required="yes" type="string"> 
     374                <!--- ************************************************************* ---> 
     375                        <cfset var isOk=false> 
     376                        <cfset var i=0> 
     377                        <cfset var parsedDate=""> 
     378                        <cfset var tDateFormatter=""> 
     379                        <!--- holy cow batman, can't parse dates in an elegant way. bash! pow! socko! ---> 
     380                        <cfloop index="i" from="0" to="3"> 
     381                                <cfset isOK=true> 
     382                                <cfset tDateFormatter=instance.aDateFormat.getDateInstance(javacast("int",i),instance.thisLocale)> 
     383                                <cftry> 
     384                                        <cfset parsedDate=tDateFormatter.parse(arguments.thisDate)> 
     385                                        <cfcatch type="Any"> 
     386                                                <cfset isOK=false> 
     387                                        </cfcatch> 
     388                                </cftry> 
     389                                <cfif isOK> 
     390                                        <cfbreak> 
     391                                </cfif> 
     392                </cfloop> 
     393                <cfreturn parsedDate.getTime()> 
     394        </cffunction> 
     395        <!--- ************************************************************* ---> 
     396         
     397        <!--- ************************************************************* ---> 
     398        <cffunction name="i18nDateTimeParse" access="public" output="No" returntype="numeric" hint="parses localized datetime string to datetime object or returns blank if it can't parse"> 
     399                <!--- ************************************************************* ---> 
     400                <cfargument name="thisDate" required="yes" type="string"> 
     401                <!--- ************************************************************* ---> 
     402                        <cfset var isOk=false> 
     403                        <cfset var i=0> 
     404                        <cfset var j=0> 
     405                        <cfset var dStyle=0> 
     406                        <cfset var tStyle=0> 
     407                        <cfset var parsedDate=""> 
     408                        <cfset var tDateFormatter=""> 
     409                        <!--- holy cow batman, can't parse dates in an elegant way. bash! pow! socko! ---> 
     410                        <cfloop index="i" from="0" to="3"> 
     411                                <cfset dStyle=javacast("int",i)> 
     412                                <cfloop index="j" from="0" to="3"> 
     413                                        <cfset tStyle=javacast("int",j)> 
     414                                        <cfset isOK=true> 
     415                                        <cfset tDateFormatter=instance.aDateFormat.getDateTimeInstance(dStyle,tStyle,instance.thisLocale)> 
     416                                        <cftry> 
     417                                                <cfset parsedDate=tDateFormatter.parse(arguments.thisDate)> 
     418                                                <cfcatch type="Any"> 
     419                                                        <cfset isOK=false> 
     420                                                </cfcatch> 
     421                                        </cftry> 
     422                                        <cfif isOK> 
     423                                                <cfbreak> 
     424                                        </cfif> 
     425                                </cfloop> 
     426               </cfloop> 
     427               <cfreturn parsedDate.getTime()> 
     428        </cffunction> 
     429        <!--- ************************************************************* ---> 
     430         
     431        <!--- ************************************************************* ---> 
     432        <cffunction name="getDateTimePattern" access="public" output="No" returntype="string" hint="returns locale date/time pattern"> 
     433                <!--- ************************************************************* ---> 
     434                <cfargument name="thisDateFormat" required="no" type="numeric" default="1"> 
     435                <cfargument name="thisTimeFormat" required="no" type="numeric" default="3"> 
     436                <!--- ************************************************************* ---> 
     437               <cfset var tDateFormat=javacast("int",arguments.thisDateFormat)> 
     438               <cfset var tTimeFormat=javacast("int",arguments.thisTimeFormat)> 
     439               <cfset var tDateFormatter=instance.aDateFormat.getDateTimeInstance(tDateFormat,tTimeFormat,instance.thisLocale)> 
     440               <cfreturn tDateFormatter.toPattern()> 
     441        </cffunction> 
     442        <!--- ************************************************************* ---> 
     443         
     444        <!--- ************************************************************* ---> 
     445        <cffunction name="formatDateTime" access="public" output="No" returntype="string" hint="formats a date/time to given pattern"> 
     446                <!--- ************************************************************* ---> 
     447                <cfargument name="thisOffset" required="yes" type="numeric"> 
     448                <cfargument name="thisPattern" required="yes" type="string"> 
     449                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     450                <!--- ************************************************************* ---> 
     451               <cfset var tDateFormatter=instance.aDateFormat.getDateTimeInstance(instance.aDateFormat.LONG,instance.aDateFormat.LONG,instance.thisLocale)> 
     452               <cfset tDateFormatter.applyPattern(arguments.thisPattern)> 
     453               <cfreturn tDateFormatter.format(arguments.thisOffset)> 
     454        </cffunction> 
     455        <!--- ************************************************************* ---> 
     456         
     457        <!--- ************************************************************* ---> 
     458        <cffunction name="weekStarts" access="public" returnType="string" output="false" hint="Determines the first DOW."> 
     459               <cfreturn instance.aCalendar.getFirstDayOfWeek() /> 
     460        </cffunction> 
     461        <!--- ************************************************************* ---> 
     462         
     463        <!--- ************************************************************* ---> 
     464        <cffunction name="getLocalizedYear" access="public" returnType="string" output="false" hint="Returns localized year, probably only useful for BE calendars like in thailand, etc."> 
     465                <!--- ************************************************************* ---> 
     466                <cfargument name="thisYear"   type="numeric" required="true" /> 
     467                <!--- ************************************************************* ---> 
     468               <cfset var thisDF=instance.aDateFormat.init("yyyy", buildLocale(instance.thisLocale))> 
     469               <cfreturn thisDF.format(createDate(arguments.thisYear, 1, 1)) /> 
     470        </cffunction> 
     471        <!--- ************************************************************* ---> 
     472         
     473        <!--- ************************************************************* ---> 
     474        <cffunction name="getLocalizedMonth" access="public" returnType="string" output="false" hint="Returns localized month."> 
     475                <!--- ************************************************************* ---> 
     476                <cfargument name="month" type="numeric" required="true"> 
     477            <!--- ************************************************************* ---> 
     478               <cfset var thisDF=variables.aDateFormat.init("MMMM",buildLocale(instance.thisLocale))> 
     479               <cfreturn thisDF.format(createDate(1999,arguments.month,1))> 
     480        </cffunction> 
     481        <!--- ************************************************************* ---> 
     482         
     483        <!--- ************************************************************* ---> 
     484        <cffunction name="getLocalizedDays" access="public" returnType="any" output="false" 
     485                                hint="Facade to getShortWeedDays. For compatability"> 
    345486                <cfscript> 
    346                 instanceCheck(); 
    347                 return instance.aCalendar.getFirstDayOfWeek(); 
     487                return getShortWeekDays(); 
    348488                </cfscript> 
    349489        </cffunction> 
    350490        <!--- ************************************************************* ---> 
    351  
    352         <!--- ************************************************************* ---> 
    353         <cffunction name="getLocalizedName" access="public" returnType="any" output="false" 
    354                                 hint="Returns current locale name. Needs object instantiation. That is your job not mine."> 
    355                 <cfreturn instance.localeName> 
    356         </cffunction> 
    357         <!--- ************************************************************* ---> 
    358  
    359         <!--- ************************************************************* ---> 
    360         <cffunction name="getCurrentLocale" access="public" returnType="any" output="false" 
    361                                 hint="Returns current locale, Needs object instantiation. That is your job not mine."> 
    362                 <cfreturn instance.thisLocale> 
    363         </cffunction> 
    364         <!--- ************************************************************* ---> 
    365  
     491         
     492        <!--- ************************************************************* ---> 
     493        <cffunction name="getShortWeekDays" access="public" output="No" returntype="array" hint="returns short day names for this calendar"> 
     494                <!--- ************************************************************* ---> 
     495                <cfargument name="calendarOrder" required="no" type="boolean" default="true"> 
     496                <!--- ************************************************************* ---> 
     497               <cfset var theseDateSymbols= createObject("java","java.text.DateFormatSymbols").init(instance.thisLocale)> 
     498               <cfset var localeDays=""> 
     499               <cfset var i=0> 
     500               <cfset var tmp=listToArray(arrayToList(theseDateSymbols.getShortWeekDays()))> 
     501               <cfif NOT arguments.calendarOrder> 
     502                       <cfreturn tmp> 
     503               <cfelse> 
     504                       <cfswitch expression="#weekStarts(instance.thisLocale)#"> 
     505                               <cfcase value="1"> <!--- "standard" dates ---> 
     506                                       <cfreturn tmp> 
     507                               </cfcase> 
     508                               <cfcase value="2"> <!--- euro dates, starts on monday needs kludge ---> 
     509                                       <cfset localeDays=arrayNew(1)> 
     510                                       <cfset localeDays[7]=tmp[1]>; <!--- move sunday to last ---> 
     511                                       <cfloop index="i" from="1" to="6"> 
     512                                               <cfset localeDays[i]=tmp[i+1]> 
     513                                       </cfloop> 
     514                                       <cfreturn localeDays> 
     515                               </cfcase> 
     516                               <cfcase value="7"> <!--- starts saturday, usually arabic, needs kludge ---> 
     517                                       <cfset localeDays=arrayNew(1)> 
     518                                       <cfset localeDays[1]=tmp[7]> <!--- move saturday to first ---> 
     519                                       <cfloop index="i" from="1" to="6"> 
     520                                               <cfset localeDays[i+1]=tmp[i]> 
     521                                       </cfloop> 
     522                                       <cfreturn localeDays> 
     523                               </cfcase> 
     524                       </cfswitch> 
     525               </cfif> 
     526        </cffunction> 
     527        <!--- ************************************************************* ---> 
     528         
     529        <!--- ************************************************************* ---> 
     530        <cffunction name="getYear" output="No" access="public" returntype="numeric" hint="returns year from epoch offset"> 
     531                <!--- ************************************************************* ---> 
     532                <cfargument name="thisOffset"   required="Yes" hint="java epoch offset" type="numeric"> 
     533                <cfargument name="tz"                   required="no" default="#instance.timeZone.getDefault().getID()#"> 
     534                <!--- ************************************************************* ---> 
     535               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     536               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     537               <cfset instance.aCalendar.setTimeZone(thisTZ)> 
     538               <cfreturn instance.aCalendar.get(instance.aCalendar.YEAR)> 
     539        </cffunction> 
     540        <!--- ************************************************************* ---> 
     541 
     542        <!--- ************************************************************* ---> 
     543        <cffunction name="getMonth" output="No" access="public" returntype="numeric" hint="returns month from epoch offset"> 
     544                <!--- ************************************************************* ---> 
     545                <cfargument name="thisOffset" required="Yes" hint="java epoch offset" type="numeric"> 
     546                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     547                <!--- ************************************************************* ---> 
     548               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     549               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     550               <cfset instance.aCalendar.setTimeZone(thisTZ)> 
     551               <cfreturn instance.aCalendar.get(instance.aCalendar.MONTH)+1> <!--- java months start at 0 ---> 
     552        </cffunction> 
     553        <!--- ************************************************************* ---> 
     554         
     555        <!--- ************************************************************* ---> 
     556        <cffunction name="getDay" output="No" access="public" returntype="numeric" hint="returns day from epoch offset"> 
     557                <!--- ************************************************************* ---> 
     558                <cfargument name="thisOffset" required="Yes" hint="java epoch offset" type="numeric"> 
     559                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     560                <!--- ************************************************************* ---> 
     561               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     562               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     563               <cfset instance.aCalendar.setTimeZone(thisTZ)> 
     564               <cfreturn instance.aCalendar.get(instance.aCalendar.DATE)> 
     565        </cffunction> 
     566        <!--- ************************************************************* ---> 
     567 
     568        <!--- ************************************************************* ---> 
     569        <cffunction name="getHour" output="No" access="public" returntype="numeric" hint="returns hour of day, 24 hr format, from epoch offset"> 
     570                <!--- ************************************************************* ---> 
     571                <cfargument name="thisOffset" required="Yes" hint="java epoch offset" type="numeric"> 
     572                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     573                <!--- ************************************************************* ---> 
     574               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     575               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     576               <cfset instance.aCalendar.setTimeZone(thisTZ)> 
     577               <cfreturn instance.aCalendar.get(instance.aCalendar.HOUR_OF_DAY)> 
     578        </cffunction> 
     579        <!--- ************************************************************* ---> 
     580         
     581        <!--- ************************************************************* ---> 
     582        <cffunction name="getMinute" output="No" access="public" returntype="numeric" hint="returns minute from epoch offset"> 
     583                <!--- ************************************************************* ---> 
     584                <cfargument name="thisOffset" required="Yes" hint="java epoch offset" type="numeric"> 
     585                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     586                <!--- ************************************************************* ---> 
     587               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     588               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     589               <cfset instance.aCalendar.setTimeZone(thisTZ)> 
     590               <cfreturn instance.aCalendar.get(instance.aCalendar.MINUTE)> 
     591        </cffunction> 
     592        <!--- ************************************************************* ---> 
     593         
     594        <!--- ************************************************************* ---> 
     595        <cffunction name="getSecond" output="No" access="public" returntype="numeric" hint="returns second from epoch offset"> 
     596                <!--- ************************************************************* ---> 
     597                <cfargument name="thisOffset" required="Yes" hint="java epoch offset" type="numeric"> 
     598                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     599                <!--- ************************************************************* ---> 
     600               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     601               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     602               <cfset instance.aCalendar.setTimeZone(thisTZ)> 
     603               <cfreturn instance.aCalendar.get(instance.aCalendar.SECOND)> 
     604        </cffunction> 
     605        <!--- ************************************************************* ---> 
     606         
     607        <!--- ************************************************************* ---> 
     608        <cffunction name="toEpoch" access="public" output="no" returnType="numeric" hint="converts datetime to java epoch offset"> 
     609                <cfargument name="thisDate" required="Yes" hint="datetime to convert to java epoch" type="date"> 
     610               <cfreturn arguments.thisDate.getTime()> 
     611         </cffunction> 
     612        <!--- ************************************************************* ---> 
     613 
     614        <!--- ************************************************************* ---> 
     615        <cffunction name="fromEpoch" access="public" output="no" returnType="date" hint="converts java epoch offset to datetime"> 
     616                <cfargument name="thisOffset" required="Yes" hint="java epoch offset to convert to datetime" type="numeric"> 
     617               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     618               <cfreturn instance.aCalendar.getTime()> 
     619         </cffunction> 
     620        <!--- ************************************************************* ---> 
     621         
     622        <!--- ************************************************************* ---> 
     623        <cffunction name="getAvailableTZ" output="yes" returntype="array" access="public" hint="returns an array of timezones available on this server"> 
     624                <cfreturn instance.timeZone.getAvailableIDs()> 
     625        </cffunction> 
     626        <!--- ************************************************************* ---> 
     627 
     628        <!--- ************************************************************* ---> 
     629        <cffunction name="usesDST" output="No" returntype="boolean" access="public" hint="determines if a given timezone uses DST"> 
     630                <cfargument name="tz" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     631               <cfreturn instance.timeZone.getTimeZone(arguments.tz).useDaylightTime()> 
     632        </cffunction> 
     633        <!--- ************************************************************* ---> 
     634 
     635        <!--- ************************************************************* ---> 
     636        <cffunction name="getRawOffset" output="No" access="public" returntype="numeric" hint="returns rawoffset in hours"> 
     637                <cfargument name="tZ" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     638               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tZ)> 
     639               <cfreturn thisTZ.getRawOffset()/3600000> 
     640        </cffunction> 
     641        <!--- ************************************************************* ---> 
     642         
     643        <!--- ************************************************************* ---> 
     644        <cffunction name="getDST" output="No" access="public" returntype="numeric" hint="returns DST savings in hours"> 
     645                <cfargument name="thisTZ" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     646               <cfset var tZ=instance.timeZone.getTimeZone(arguments.thisTZ)> 
     647               <cfreturn tZ.getDSTSavings()/3600000> 
     648        </cffunction> 
     649        <!--- ************************************************************* ---> 
     650         
     651        <!--- ************************************************************* ---> 
     652        <cffunction name="getTZByOffset" output="No" returntype="array" access="public" hint="returns a list of timezones available on this server for a given raw offset"> 
     653                <cfargument name="thisOffset" required="Yes" type="numeric"> 
     654               <cfset var rawOffset=javacast("long",arguments.thisOffset * 3600000)> 
     655               <cfreturn instance.timeZone.getAvailableIDs(rawOffset)> 
     656        </cffunction> 
     657        <!--- ************************************************************* ---> 
     658 
     659        <!--- ************************************************************* ---> 
     660        <cffunction name="getServerTZ" output="No" access="public" returntype="any" hint="returns server TZ"> 
     661               <cfset var serverTZ=instance.timeZone.getDefault()> 
     662               <cfreturn serverTZ.getDisplayName(true,instance.timeZone.LONG)> 
     663        </cffunction> 
     664        <!--- ************************************************************* ---> 
     665 
     666        <!--- ************************************************************* ---> 
     667        <cffunction name="inDST" output="No" returntype="boolean" access="public" hint="determines if a given date in a given timezone is in DST"> 
     668                <!--- ************************************************************* ---> 
     669                <cfargument name="thisOffset" required="yes" type="numeric"> 
     670                <cfargument name="tzToTest" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     671                <!--- ************************************************************* ---> 
     672               <cfset var thisTZ=instance.timeZone.getTimeZone(arguments.tzToTest)> 
     673               <cfset instance.aCalendar.setTimeInMillis(arguments.thisOffset)> 
     674               <cfset instance.aCalendar.setTimezone(thisTZ)> 
     675               <cfreturn thisTZ.inDaylightTime(instance.aCalendar.getTime())> 
     676        </cffunction> 
     677        <!--- ************************************************************* ---> 
     678         
     679        <!--- ************************************************************* ---> 
     680        <cffunction name="getTZOffset" output="No" access="public" hint="returns offset in hours"> 
     681                <!--- ************************************************************* ---> 
     682                <cfargument name="thisOffset" required="yes" type="numeric"> 
     683                <cfargument name="thisTZ" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     684                <!--- ************************************************************* ---> 
     685               <cfset var tZ=instance.timeZone.getTimeZone(arguments.thisTZ)> 
     686               <cfreturn tZ.getOffset(arguments.thisOffset)/3600000> <!--- return hours ---> 
     687        </cffunction> 
     688        <!--- ************************************************************* ---> 
     689         
     690        <!--- ************************************************************* ---> 
     691        <cffunction name="i18nDateAdd" access="public" output="No" returntype="numeric"> 
     692                <!--- ************************************************************* ---> 
     693                <cfargument name="thisOffset" required="yes" type="numeric"> 
     694                <cfargument name="thisDatePart" required="yes" type="string"> 
     695                <cfargument name="dateUnits" required="yes" type="numeric"> 
     696                <cfargument name="thisTZ" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     697                <!--- ************************************************************* ---> 
     698               <cfscript> 
     699                       var dPart=""; 
     700                       var tZ=instance.timeZone.getTimeZone(arguments.thisTZ); 
     701                       switch (arguments.thisDatepart) { 
     702                               case "y" : 
     703                               case "yr" : 
     704                               case "yyyy" : 
     705                               case "year" : 
     706                                       dPart=instance.aCalendar.YEAR; 
     707                               break; 
     708                               case "m" : 
     709                               case "month" : 
     710                                       dPart=instance.aCalendar.MONTH; 
     711                               break; 
     712                               case "w" : 
     713                               case "week" : 
     714                                       dPart=instance.aCalendar.WEEK_OF_MONTH; 
     715                               break; 
     716                               case "d" : 
     717                               case "day" : 
     718                                       dPart=instance.aCalendar.DATE; 
     719                               break; 
     720                               case "h" : 
     721                               case "hr": 
     722                               case "hour" : 
     723                                       dPart=instance.aCalendar.HOUR; 
     724                               break; 
     725                               case "n" : 
     726                               case "minute" : 
     727                                       dPart=instance.aCalendar.MINUTE; 
     728                               break; 
     729                               case "s" : 
     730                               case "second" : 
     731                                       dPart=instance.aCalendar.SECOND; 
     732                               break; 
     733                       } 
     734                       instance.aCalendar.setTimeInMillis(arguments.thisOffset); 
     735                       instance.aCalendar.setTimezone(tZ); 
     736                       instance.aCalendar.add(dPart,javacast("int",arguments.dateUnits)); 
     737                       return instance.aCalendar.getTimeInMillis(); 
     738               </cfscript> 
     739        </cffunction> 
     740        <!--- ************************************************************* ---> 
     741         
     742        <!--- ************************************************************* ---> 
     743        <!--- oh my is this nasty in core java ---> 
     744        <cffunction name="i18nDateDiff"  access="public" output="No" returntype="numeric"> 
     745                <!--- ************************************************************* ---> 
     746                <cfargument name="thisOffset" required="yes" type="numeric"> 
     747                <cfargument name="thatOffset" required="yes" type="numeric"> 
     748                <cfargument name="thisDatePart" required="yes" type="string"> 
     749                <cfargument name="thisTZ" required="no" default="#instance.timeZone.getDefault().getID()#"> 
     750                <!--- ************************************************************* ---> 
     751                <cfscript> 
     752                       var dPart=""; 
     753                       var elapsed=0; 
     754                       var before=createObject("java","java.util.GregorianCalendar"); 
     755                       var after=createObject("java","java.util.GregorianCalendar"); 
     756                       var tZ=instance.timeZone.getTimeZone(arguments.thisTZ); 
     757                       var e=0; 
     758                       var s=0; 
     759                       var direction=1; 
     760                       // lets shortcut first 
     761                       if (arguments.thisOffset EQ arguments.thatOffset) 
     762                               return 0; 
     763                       else {  // setup calendars to test 
     764                               if (arguments.thisOffset LT arguments.thatOffset) { 
     765                                       before.setTimeInMillis(arguments.thisOffset); 
     766                                       after.setTimeInMillis(arguments.thatOffset); 
     767                                       before.setTimezone(tZ); 
     768                                       after.setTimezone(tZ); 
     769                               } else { 
     770                                       before.setTimeInMillis(arguments.thatOffset); 
     771                                       after.setTimeInMillis(arguments.thisOffset); 
     772                                       before.setTimezone(tZ); 
     773                                       after.setTimezone(tZ); 
     774                                       direction=-1; 
     775                               } // which offset came first 
     776                               switch (arguments.thisDatepart) { 
     777                                       case "y" : 
     778                                       case "yr" : 
     779                                       case "yyyy" : 
     780                                       case "year" : 
     781                                               dPart=instance.aCalendar.YEAR; 
     782                                               before.clear(instance.aCalendar.DATE); 
     783                                               after.clear(instance.aCalendar.DATE); 
     784                                               before.clear(instance.aCalendar.MONTH); 
     785                                               after.clear(instance.aCalendar.MONTH); 
     786                                       break; 
     787                                       case "m" : 
     788                                       case "month" : 
     789                                               dPart=instance.aCalendar.MONTH; 
     790                                               before.clear(instance.aCalendar.DATE); 
     791                                               after.clear(instance.aCalendar.DATE); 
     792                                       break; 
     793                                       case "w" : 
     794                                       case "week" : 
     795                                               dPart=instance.aCalendar.WEEK_OF_YEAR; 
     796                                               before.clear(instance.aCalendar.DATE); 
     797                                               after.clear(instance.aCalendar.DATE); 
     798                                       break; 
     799                                       case "d" : 
     800                                       case "day" : 
     801                                               // very much a special case 
     802                                               e=after.getTimeInMillis()+after.getTimeZone().getOffset(after.getTimeInMillis()); 
     803                                               s=before.getTimeInMillis()+before.getTimeZone().getOffset(before.getTimeInMillis()); 
     804                                               return int((e-s)/86400000)*direction; 
     805                                       break; 
     806                                       case "h" : 
     807                                       case "hr" : 
     808                                       case "hour" : 
     809                                               e=after.getTimeInMillis()+after.getTimeZone().getOffset(after.getTimeInMillis()); 
     810                                               s=before.getTimeInMillis()+before.getTimeZone().getOffset(before.getTimeInMillis()); 
     811                                               return int((e-s)/3600000)*direction; 
     812                                       break; 
     813                                       case "n" : 
     814                                       case "minute" : 
     815                                               e=after.getTimeInMillis()+after.getTimeZone().getOffset(after.getTimeInMillis()); 
     816                                               s=before.getTimeInMillis()+before.getTimeZone().getOffset(before.getTimeInMillis()); 
     817                                               return int((e-s)/60000)*direction; 
     818                                       break; 
     819                                       case "s" : 
     820                                       case "second" : 
     821                                               e=after.getTimeInMillis()+after.getTimeZone().getOffset(after.getTimeInMillis()); 
     822                                               s=before.getTimeInMillis()+before.getTimeZone().getOffset(before.getTimeInMillis()); 
     823                                               return int((e-s)/1000)*direction; 
     824                                       break; 
     825                               }// datepart switch 
     826                               while (before.before(after)){ 
     827                                       before.add(dPart,1); 
     828                                       elapsed=elapsed+1; 
     829                               } //count dateparts 
     830                               return elapsed * direction; 
     831                       } // if start & end times are the same 
     832                </cfscript> 
     833        </cffunction> 
     834        <!--- ************************************************************* ---> 
     835 
     836        <!--- ************************************************************* ---> 
     837        <cffunction name="getVersion" access="public" output="false" returntype="struct" hint=" returns version of this CFC and icu4j library it uses."> 
     838                <cfset var version=StructNew()> 
     839                <cfset var sys=createObject("java","java.lang.System")> 
     840                <cfset version.I18NUtilVersion=instance.pluginVersion> 
     841                <cfset version.I18NUtilDate=instance.I18NUtilDate> 
     842                <cfset version.javaRuntimeVersion=sys.getProperty("java.runtime.version")> 
     843                <cfset version.javaVersion=sys.getProperty("java.version")> 
     844                <cfreturn version> 
     845        </cffunction> 
     846        <!--- ************************************************************* ---> 
     847<!------------------------------------------- PRIVATE -------------------------------------------> 
     848 
     849        <!--- ************************************************************* ---> 
     850        <cffunction name="buildLocale"  access="private" output="false"hint="creates valid core java locale from java style locale ID"> 
     851                <!--- ************************************************************* ---> 
     852                <cfargument name="thisLocale" required="yes" type="string"> 
     853                <!--- ************************************************************* ---> 
     854                <cfscript> 
     855                       var l=listFirst(arguments.thisLocale,"_"); 
     856                       var c=""; 
     857                       var v=""; 
     858                       var tLocale=instance.aLocale.getDefault(); // if we fail fallback on server default 
     859                       switch (listLen(arguments.thisLocale,"_")) { 
     860                       case 1: 
     861                               tLocale=instance.aLocale.init(l); 
     862                       break; 
     863                       case 2: 
     864                               c=listLast(arguments.thisLocale,"_"); 
     865                               tLocale=instance.aLocale.init(l,c); 
     866                       break; 
     867                       case 3: 
     868                               c=listGetAt(arguments.thisLocale,2,"_"); 
     869                               v=listLast(arguments.thisLocale,"_"); 
     870                               tLocale=instance.aLocale.init(l,c,v); 
     871                       break; 
     872                       } 
     873                       return tLocale; 
     874                </cfscript> 
     875        </cffunction> 
     876        <!--- ************************************************************* ---> 
     877         
     878         
    366879</cfcomponent> 
  • coldbox/trunk/src/system/plugins/settings.cfc

    r87 r98  
    3939                <!---Load i18N if needed ---> 
    4040                <cfif getSetting("using_i18N")> 
    41                         <cfset getPlugin("i18n").initBundle(getSetting("DefaultResourceBundle"),getSetting("DefaultLocale"))> 
     41                        <cfset getPlugin("i18n").init_i18N(getSetting("DefaultResourceBundle"),getSetting("DefaultLocale"))> 
    4242                </cfif> 
    4343                <!--- Set Config DebugMode ---> 
  • coldbox/trunk/src/system/util/sharedlibrary.cfc

    r84 r98  
    9292        <!--- ************************************************************* ---> 
    9393         
    94          
    95          
    9694<!------------------------------------------- PRIVATE -------------------------------------------> 
    9795