source: Dev/branches/rest-dojo-ui/client/dojox/date/buddhist/locale.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 12.2 KB
Line 
1define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/buddhist"],
2        function(dojo, dd, i18n, regexp, string, buddhistDate){
3
4        dojo.getObject("date.buddhist.locale", true, dojox);
5        dojo.experimental("dojox.date.buddhist.locale");
6
7        // Format a pattern without literals
8        function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
9
10                return pattern.replace(/([a-z])\1*/ig, function(match){
11                        var s, pad;
12                        var c = match.charAt(0);
13                        var l = match.length;
14                        var widthList = ["abbr", "wide", "narrow"];
15                       
16                        switch(c){
17                                case 'G':
18                                        s = bundle["eraAbbr"][0];
19                                        break;
20                                case 'y':
21                                        s = String(dateObject.getFullYear());
22                                        break;
23                                case 'M':
24                                        var m = dateObject.getMonth();
25                                        if(l<3){
26                                                s = m+1; pad = true;
27                                        }else{
28                                                var propM = ["months", "format", widthList[l-3]].join("-");
29                                                s = bundle[propM][m];
30                                        }
31                                        break;
32                                case 'd':
33                                        s = dateObject.getDate(true); pad = true;
34                                        break;
35                                case 'E':
36                                        var d = dateObject.getDay();
37                                        if(l<3){
38                                                s = d+1; pad = true;
39                                        }else{
40                                                var propD = ["days", "format", widthList[l-3]].join("-");
41                                                s = bundle[propD][d];
42                                        }
43                                        break;
44                                case 'a':
45                                        var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm';
46                                        s = bundle['dayPeriods-format-wide-' + timePeriod];
47                                        break;
48                                case 'h':
49                                case 'H':
50                                case 'K':
51                                case 'k':
52                                        var h = dateObject.getHours();
53                                        switch (c){
54                                                case 'h': // 1-12
55                                                        s = (h % 12) || 12;
56                                                        break;
57                                                case 'H': // 0-23
58                                                        s = h;
59                                                        break;
60                                                case 'K': // 0-11
61                                                        s = (h % 12);
62                                                        break;
63                                                case 'k': // 1-24
64                                                        s = h || 24;
65                                                        break;
66                                        }
67                                        pad = true;
68                                        break;
69                                case 'm':
70                                        s = dateObject.getMinutes(); pad = true;
71                                        break;
72                                case 's':
73                                        s = dateObject.getSeconds(); pad = true;
74                                        break;
75                                case 'S':
76                                        s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l-3)); pad = true;
77                                        break;
78                                case 'z':
79                                        // We only have one timezone to offer; the one from the browser
80                                        s = dojo.date.getTimezoneName(dateObject.toGregorian());
81                                        if(s){ break; }
82                                        l = 4;
83                                        // fallthrough... use GMT if tz not available
84                                case 'Z':
85                                        var offset = dateObject.toGregorian().getTimezoneOffset();
86                                        var tz = [
87                                                (offset <= 0 ? "+" : "-"),
88                                                string.pad(Math.floor(Math.abs(offset) / 60), 2),
89                                                string.pad(Math.abs(offset) % 60, 2)
90                                        ];
91                                        if(l == 4){
92                                                tz.splice(0, 0, "GMT");
93                                                tz.splice(3, 0, ":");
94                                        }
95                                        s = tz.join("");
96                                        break;
97                                default:
98                                        throw new Error("dojox.date.buddhist.locale.formatPattern: invalid pattern char: "+pattern);
99                        }
100                        if(pad){ s = string.pad(s, l); }
101                        return s;
102                });
103        }
104       
105        dojox.date.buddhist.locale.format = function(/*buddhist.Date*/dateObject, /*object?*/options){
106                // based on and similar to dojo.date.locale.format
107                // summary:
108                //              Format a Date object as a String, using  settings.
109                options = options || {};
110
111                var locale = i18n.normalizeLocale(options.locale);
112                var formatLength = options.formatLength || 'short';
113                var bundle = dojox.date.buddhist.locale._getBuddhistBundle(locale);
114                var str = [];
115
116                var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
117                if(options.selector == "year"){
118                        var year = dateObject.getFullYear();
119                        return year;
120                }
121                if(options.selector != "time"){
122                        var datePattern = options.datePattern || bundle["dateFormat-"+formatLength];
123                        if(datePattern){str.push(_processPattern(datePattern, sauce));}
124                }
125                if(options.selector != "date"){
126                        var timePattern = options.timePattern || bundle["timeFormat-"+formatLength];
127                        if(timePattern){str.push(_processPattern(timePattern, sauce));}
128                }
129                var result = str.join(" "); //TODO: use locale-specific pattern to assemble date + time
130
131                return result; // String
132        };
133
134        dojox.date.buddhist.locale.regexp = function(/*Object?*/options){
135                //      based on and similar to dojo.date.locale.regexp
136                // summary:
137                //              Builds the regular needed to parse a buddhist.Date
138                return dojox.date.buddhist.locale._parseInfo(options).regexp; // String
139        };
140
141        dojox.date.buddhist.locale._parseInfo = function(/*Object?*/options){
142        /* based on and similar to dojo.date.locale._parseInfo */
143
144                options = options || {};
145                var locale = i18n.normalizeLocale(options.locale);
146                var bundle = dojox.date.buddhist.locale._getBuddhistBundle(locale);
147                var formatLength = options.formatLength || 'short';
148                var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
149                var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
150
151                var pattern;
152                if(options.selector == 'date'){
153                        pattern = datePattern;
154                }else if(options.selector == 'time'){
155                        pattern = timePattern;
156                }else{
157                        pattern = (typeof (timePattern) == "undefined") ? datePattern : datePattern + ' ' + timePattern;
158                }
159
160                var tokens = [];
161       
162                var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
163                return {regexp: re, tokens: tokens, bundle: bundle};
164        };
165
166        dojox.date.buddhist.locale.parse = function(/*String*/value, /*Object?*/options){
167                // based on and similar to dojo.date.locale.parse
168                // summary: This function parses string date value according to options
169                value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
170       
171                if(!options){options={};}
172                var info = dojox.date.buddhist.locale._parseInfo(options);
173       
174                var tokens = info.tokens, bundle = info.bundle;
175                var re = new RegExp("^" + info.regexp + "$");
176       
177                var match = re.exec(value);
178
179                var locale = i18n.normalizeLocale(options.locale);
180
181                if(!match){
182                        console.debug("dojox.date.buddhist.locale.parse: value  "+value+" doesn't match pattern   " + re);
183                        return null;
184                } // null
185       
186                var date, date1;
187       
188                var result = [2513,0,1,0,0,0,0];  // buddhist date for [1970,0,1,0,0,0,0] used in gregorian locale
189                var amPm = "";
190                var mLength = 0;
191                var widthList = ["abbr", "wide", "narrow"];
192                var valid = dojo.every(match, function(v, i){
193                        if(!i){return true;}
194                        var token=tokens[i-1];
195                        var l=token.length;
196                        switch(token.charAt(0)){
197                                case 'y':
198                                        result[0] = Number(v);
199                                        break;
200                                case 'M':
201                                        if(l>2){
202                                                var months = bundle['months-format-' + widthList[l-3]].concat();
203                                                if(!options.strict){
204                                                        //Tolerate abbreviating period in month part
205                                                        //Case-insensitive comparison
206                                                        v = v.replace(".","").toLowerCase();
207                                                        months = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
208                                                }
209                                                v = dojo.indexOf(months, v);
210                                                if(v == -1){
211                                                        return false;
212                                                }
213                                                mLength = l;
214                                        }else{
215                                                v--;
216                                        }
217                                        result[1] = Number(v);
218                                        break;
219                                case 'D':
220                                        result[1] = 0;
221                                        // fallthrough...
222                                case 'd':
223                                                result[2] =  Number(v);
224                                        break;
225                                case 'a': //am/pm
226                                        var am = options.am || bundle['dayPeriods-format-wide-am'],
227                                                pm = options.pm || bundle['dayPeriods-format-wide-pm'];
228                                        if(!options.strict){
229                                                var period = /\./g;
230                                                v = v.replace(period,'').toLowerCase();
231                                                am = am.replace(period,'').toLowerCase();
232                                                pm = pm.replace(period,'').toLowerCase();
233                                        }
234                                        if(options.strict && v != am && v != pm){
235                                                return false;
236                                        }
237
238                                        // we might not have seen the hours field yet, so store the state and apply hour change later
239                                        amPm = (v == pm) ? 'p' : (v == am) ? 'a' : '';
240                                        break;
241                                case 'K': //hour (1-24)
242                                        if(v == 24){ v = 0; }
243                                        // fallthrough...
244                                case 'h': //hour (1-12)
245                                case 'H': //hour (0-23)
246                                case 'k': //hour (0-11)
247                                        //in the 12-hour case, adjusting for am/pm requires the 'a' part
248                                        //which could come before or after the hour, so we will adjust later
249                                        result[3] = Number(v);
250                                        break;
251                                case 'm': //minutes
252                                        result[4] = Number(v);
253                                        break;
254                                case 's': //seconds
255                                        result[5] = Number(v);
256                                        break;
257                                case 'S': //milliseconds
258                                        result[6] = Number(v);
259                        }
260                        return true;
261                });
262
263                var hours = +result[3];
264                if(amPm === 'p' && hours < 12){
265                        result[3] = hours + 12; //e.g., 3pm -> 15
266                }else if(amPm === 'a' && hours == 12){
267                        result[3] = 0; //12am -> 0
268                }
269                var dateObject = new buddhistDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
270                return dateObject;
271        };
272
273
274        function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
275                // summary: Process a pattern with literals in it
276
277                // Break up on single quotes, treat every other one as a literal, except '' which becomes '
278                var identity = function(x){return x;};
279                applyPattern = applyPattern || identity;
280                applyLiteral = applyLiteral || identity;
281                applyAll = applyAll || identity;
282
283                //split on single quotes (which escape literals in date format strings)
284                //but preserve escaped single quotes (e.g., o''clock)
285                var chunks = pattern.match(/(''|[^'])+/g);
286                var literal = pattern.charAt(0) == "'";
287
288                dojo.forEach(chunks, function(chunk, i){
289                        if(!chunk){
290                                chunks[i]='';
291                        }else{
292                                chunks[i]=(literal ? applyLiteral : applyPattern)(chunk);
293                                literal = !literal;
294                        }
295                });
296                return applyAll(chunks.join(''));
297        }
298
299        function _buildDateTimeRE  (tokens, bundle, options, pattern){
300                        // based on and similar to dojo.date.locale._buildDateTimeRE
301                        //
302       
303                pattern = regexp.escapeString(pattern);
304                var locale = i18n.normalizeLocale(options.locale);
305       
306                return pattern.replace(/([a-z])\1*/ig, function(match){
307
308                                // Build a simple regexp.  Avoid captures, which would ruin the tokens list
309                                var s;
310                                var c = match.charAt(0);
311                                var l = match.length;
312                                var p2 = '', p3 = '';
313                                if(options.strict){
314                                        if(l > 1){ p2 = '0' + '{'+(l-1)+'}'; }
315                                        if(l > 2){ p3 = '0' + '{'+(l-2)+'}'; }
316                                }else{
317                                        p2 = '0?'; p3 = '0{0,2}';
318                                }
319                                switch(c){
320                                        case 'y':
321                                                s = '\\d+';
322                                                break;
323                                        case 'M':
324                                                s = (l>2) ?  '\\S+' : p2+'[1-9]|1[0-2]';
325                                                break;
326                                        case 'd':
327                                                s = '[12]\\d|'+p2+'[1-9]|3[01]';
328                                                break;
329                                        case 'E':
330                                                s = '\\S+';
331                                                break;
332                                        case 'h': //hour (1-12)
333                                                s = p2+'[1-9]|1[0-2]';
334                                                break;
335                                        case 'k': //hour (0-11)
336                                                s = p2+'\\d|1[01]';
337                                                break;
338                                        case 'H': //hour (0-23)
339                                                s = p2+'\\d|1\\d|2[0-3]';
340                                                break;
341                                        case 'K': //hour (1-24)
342                                                s = p2+'[1-9]|1\\d|2[0-4]';
343                                                break;
344                                        case 'm':
345                                        case 's':
346                                                s = p2+'\\d|[0-5]\\d';
347                                                break;
348                                        case 'S':
349                                                s = '\\d{'+l+'}';
350                                                break;
351                                        case 'a':
352                                                var am = options.am || bundle['dayPeriods-format-wide-am'],
353                                                        pm = options.pm || bundle['dayPeriods-format-wide-pm'];
354                                                if(options.strict){
355                                                        s = am + '|' + pm;
356                                                }else{
357                                                        s = am + '|' + pm;
358                                                        if(am != am.toLowerCase()){ s += '|' + am.toLowerCase(); }
359                                                        if(pm != pm.toLowerCase()){ s += '|' + pm.toLowerCase(); }
360                                                }
361                                                break;
362                                        default:
363                                                s = ".*";
364                                }
365                                if(tokens){ tokens.push(match); }
366                                return "(" + s + ")"; // add capture
367                        }).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE. */
368        }
369
370        var _customFormats = [];
371        dojox.date.buddhist.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
372                // summary:
373                //              Add a reference to a bundle containing localized custom formats to be
374                //              used by date/time formatting and parsing routines.
375                _customFormats.push({pkg:packageName,name:bundleName});
376        };
377
378        dojox.date.buddhist.locale._getBuddhistBundle = function(/*String*/locale){
379                var buddhist = {};
380                dojo.forEach(_customFormats, function(desc){
381                        var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
382                        buddhist = dojo.mixin(buddhist, bundle);
383                }, this);
384                return buddhist; /*Object*/
385        };
386
387        dojox.date.buddhist.locale.addCustomFormats("dojo.cldr","buddhist");
388
389        dojox.date.buddhist.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*buddhist Date Object?*/date){
390                // summary:
391                //              Used to get localized strings from dojo.cldr for day or month names.
392                var label;
393                var lookup = dojox.date.buddhist.locale._getBuddhistBundle(locale);
394                var props = [item, context, type];
395                if(context == 'standAlone'){
396                        var key = props.join('-');
397                        label = lookup[key];
398                        // Fall back to 'format' flavor of name
399                        if(label[0] == 1){ label = undefined; } // kludge, in the absence of real aliasing support in dojo.cldr
400                }
401                props[1] = 'format';
402       
403                // return by copy so changes won't be made accidentally to the in-memory model
404                return (label || lookup[props.join('-')]).concat(); /*Array*/
405        };
406
407});
Note: See TracBrowser for help on using the repository browser.