]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/datatype/datatype-date.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / datatype / datatype-date.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('datatype-date-parse', function(Y) {
9
10 /**
11  * Parse number submodule.
12  *
13  * @module datatype
14  * @submodule datatype-date-parse
15  * @for DataType.Date
16  */
17 var LANG = Y.Lang;
18
19 Y.mix(Y.namespace("DataType.Date"), {
20     /**
21      * Converts data to type Date.
22      *
23      * @method parse
24      * @param data {String | Number} Data to convert. Values supported by the Date constructor are supported.
25      * @return {Date} A Date, or null.
26      */
27     parse: function(data) {
28         var date = null;
29
30         //Convert to date
31         if(!(LANG.isDate(data))) {
32             date = new Date(data);
33         }
34         else {
35             return date;
36         }
37
38         // Validate
39         if(LANG.isDate(date) && (date != "Invalid Date") && !isNaN(date)) { // Workaround for bug 2527965
40             return date;
41         }
42         else {
43             return null;
44         }
45     }
46 });
47
48 // Add Parsers shortcut
49 Y.namespace("Parsers").date = Y.DataType.Date.parse;
50
51
52 }, '3.3.0' ,{requires:['yui-base']});
53 YUI.add('datatype-date-format', function(Y) {
54
55 /**
56  * The DataType Utility provides type-conversion and string-formatting
57  * convenience methods for various JavaScript object types.
58  *
59  * @module datatype
60  */
61
62 /**
63  * Date submodule.
64  *
65  * @module datatype
66  * @submodule datatype-date
67  */
68
69 /**
70  * Format date submodule implements strftime formatters for javascript based on the
71  * Open Group specification defined at
72  * http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
73  * This implementation does not include modified conversion specifiers (i.e., Ex and Ox)
74  *
75  * @module datatype
76  * @submodule datatype-date-format
77  */
78
79 /**
80  * DataType.Date provides a set of utility functions to operate against Date objects.
81  *
82  * @class DataType.Date
83  * @static
84  */
85
86 /**
87  * Pad a number with leading spaces, zeroes or something else
88  * @method xPad
89  * @param x {Number}    The number to be padded
90  * @param pad {String}  The character to pad the number with
91  * @param r {Number}    (optional) The base of the pad, eg, 10 implies to two digits, 100 implies to 3 digits.
92  * @private
93  */
94 var xPad=function (x, pad, r)
95 {
96         if(typeof r === "undefined")
97         {
98                 r=10;
99         }
100         pad = pad.toString();
101         for( ; parseInt(x, 10)<r && r>1; r/=10) {
102                 x = pad + x;
103         }
104         return x.toString();
105 };
106
107 var Dt = {
108         formats: {
109                 a: function (d, l) { return l.a[d.getDay()]; },
110                 A: function (d, l) { return l.A[d.getDay()]; },
111                 b: function (d, l) { return l.b[d.getMonth()]; },
112                 B: function (d, l) { return l.B[d.getMonth()]; },
113                 C: function (d) { return xPad(parseInt(d.getFullYear()/100, 10), 0); },
114                 d: ["getDate", "0"],
115                 e: ["getDate", " "],
116                 g: function (d) { return xPad(parseInt(Dt.formats.G(d)%100, 10), 0); },
117                 G: function (d) {
118                                 var y = d.getFullYear();
119                                 var V = parseInt(Dt.formats.V(d), 10);
120                                 var W = parseInt(Dt.formats.W(d), 10);
121         
122                                 if(W > V) {
123                                         y++;
124                                 } else if(W===0 && V>=52) {
125                                         y--;
126                                 }
127         
128                                 return y;
129                         },
130                 H: ["getHours", "0"],
131                 I: function (d) { var I=d.getHours()%12; return xPad(I===0?12:I, 0); },
132                 j: function (d) {
133                                 var gmd_1 = new Date("" + d.getFullYear() + "/1/1 GMT");
134                                 var gmdate = new Date("" + d.getFullYear() + "/" + (d.getMonth()+1) + "/" + d.getDate() + " GMT");
135                                 var ms = gmdate - gmd_1;
136                                 var doy = parseInt(ms/60000/60/24, 10)+1;
137                                 return xPad(doy, 0, 100);
138                         },
139                 k: ["getHours", " "],
140                 l: function (d) { var I=d.getHours()%12; return xPad(I===0?12:I, " "); },
141                 m: function (d) { return xPad(d.getMonth()+1, 0); },
142                 M: ["getMinutes", "0"],
143                 p: function (d, l) { return l.p[d.getHours() >= 12 ? 1 : 0 ]; },
144                 P: function (d, l) { return l.P[d.getHours() >= 12 ? 1 : 0 ]; },
145                 s: function (d, l) { return parseInt(d.getTime()/1000, 10); },
146                 S: ["getSeconds", "0"],
147                 u: function (d) { var dow = d.getDay(); return dow===0?7:dow; },
148                 U: function (d) {
149                                 var doy = parseInt(Dt.formats.j(d), 10);
150                                 var rdow = 6-d.getDay();
151                                 var woy = parseInt((doy+rdow)/7, 10);
152                                 return xPad(woy, 0);
153                         },
154                 V: function (d) {
155                                 var woy = parseInt(Dt.formats.W(d), 10);
156                                 var dow1_1 = (new Date("" + d.getFullYear() + "/1/1")).getDay();
157                                 // First week is 01 and not 00 as in the case of %U and %W,
158                                 // so we add 1 to the final result except if day 1 of the year
159                                 // is a Monday (then %W returns 01).
160                                 // We also need to subtract 1 if the day 1 of the year is 
161                                 // Friday-Sunday, so the resulting equation becomes:
162                                 var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1);
163                                 if(idow === 53 && (new Date("" + d.getFullYear() + "/12/31")).getDay() < 4)
164                                 {
165                                         idow = 1;
166                                 }
167                                 else if(idow === 0)
168                                 {
169                                         idow = Dt.formats.V(new Date("" + (d.getFullYear()-1) + "/12/31"));
170                                 }
171         
172                                 return xPad(idow, 0);
173                         },
174                 w: "getDay",
175                 W: function (d) {
176                                 var doy = parseInt(Dt.formats.j(d), 10);
177                                 var rdow = 7-Dt.formats.u(d);
178                                 var woy = parseInt((doy+rdow)/7, 10);
179                                 return xPad(woy, 0, 10);
180                         },
181                 y: function (d) { return xPad(d.getFullYear()%100, 0); },
182                 Y: "getFullYear",
183                 z: function (d) {
184                                 var o = d.getTimezoneOffset();
185                                 var H = xPad(parseInt(Math.abs(o/60), 10), 0);
186                                 var M = xPad(Math.abs(o%60), 0);
187                                 return (o>0?"-":"+") + H + M;
188                         },
189                 Z: function (d) {
190                         var tz = d.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/, "$2").replace(/[a-z ]/g, "");
191                         if(tz.length > 4) {
192                                 tz = Dt.formats.z(d);
193                         }
194                         return tz;
195                 },
196                 "%": function (d) { return "%"; }
197         },
198
199         aggregates: {
200                 c: "locale",
201                 D: "%m/%d/%y",
202                 F: "%Y-%m-%d",
203                 h: "%b",
204                 n: "\n",
205                 r: "%I:%M:%S %p",
206                 R: "%H:%M",
207                 t: "\t",
208                 T: "%H:%M:%S",
209                 x: "locale",
210                 X: "locale"
211                 //"+": "%a %b %e %T %Z %Y"
212         },
213
214          /**
215          * Takes a native JavaScript Date and formats it as a string for display to user.
216          *
217          * @for DataType.Date
218          * @method format
219          * @param oDate {Date} Date.
220          * @param oConfig {Object} (Optional) Object literal of configuration values:
221          *  <dl>
222          *   <dt>format {String} (Optional)</dt>
223          *   <dd>
224          *   <p>
225          *   Any strftime string is supported, such as "%I:%M:%S %p". strftime has several format specifiers defined by the Open group at 
226          *   <a href="http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html">http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html</a>
227          *   PHP added a few of its own, defined at <a href="http://www.php.net/strftime">http://www.php.net/strftime</a>
228          *   </p>
229          *   <p>
230          *   This javascript implementation supports all the PHP specifiers and a few more.  The full list is below.
231          *   </p>
232          *   <p>
233          *   If not specified, it defaults to the ISO 8601 standard date format: %Y-%m-%d.
234      *   This may be overridden by the deprecated Y.config.dateFormat property.
235          *   </p>
236          *   <dl>
237          *      <dt>%a</dt> <dd>abbreviated weekday name according to the current locale</dd>
238          *      <dt>%A</dt> <dd>full weekday name according to the current locale</dd>
239          *      <dt>%b</dt> <dd>abbreviated month name according to the current locale</dd>
240          *      <dt>%B</dt> <dd>full month name according to the current locale</dd>
241          *      <dt>%c</dt> <dd>preferred date and time representation for the current locale</dd>
242          *      <dt>%C</dt> <dd>century number (the year divided by 100 and truncated to an integer, range 00 to 99)</dd>
243          *      <dt>%d</dt> <dd>day of the month as a decimal number (range 01 to 31)</dd>
244          *      <dt>%D</dt> <dd>same as %m/%d/%y</dd>
245          *      <dt>%e</dt> <dd>day of the month as a decimal number, a single digit is preceded by a space (range " 1" to "31")</dd>
246          *      <dt>%F</dt> <dd>same as %Y-%m-%d (ISO 8601 date format)</dd>
247          *      <dt>%g</dt> <dd>like %G, but without the century</dd>
248          *      <dt>%G</dt> <dd>The 4-digit year corresponding to the ISO week number</dd>
249          *      <dt>%h</dt> <dd>same as %b</dd>
250          *      <dt>%H</dt> <dd>hour as a decimal number using a 24-hour clock (range 00 to 23)</dd>
251          *      <dt>%I</dt> <dd>hour as a decimal number using a 12-hour clock (range 01 to 12)</dd>
252          *      <dt>%j</dt> <dd>day of the year as a decimal number (range 001 to 366)</dd>
253          *      <dt>%k</dt> <dd>hour as a decimal number using a 24-hour clock (range 0 to 23); single digits are preceded by a blank. (See also %H.)</dd>
254          *      <dt>%l</dt> <dd>hour as a decimal number using a 12-hour clock (range 1 to 12); single digits are preceded by a blank. (See also %I.) </dd>
255          *      <dt>%m</dt> <dd>month as a decimal number (range 01 to 12)</dd>
256          *      <dt>%M</dt> <dd>minute as a decimal number</dd>
257          *      <dt>%n</dt> <dd>newline character</dd>
258          *      <dt>%p</dt> <dd>either "AM" or "PM" according to the given time value, or the corresponding strings for the current locale</dd>
259          *      <dt>%P</dt> <dd>like %p, but lower case</dd>
260          *      <dt>%r</dt> <dd>time in a.m. and p.m. notation equal to %I:%M:%S %p</dd>
261          *      <dt>%R</dt> <dd>time in 24 hour notation equal to %H:%M</dd>
262          *      <dt>%s</dt> <dd>number of seconds since the Epoch, ie, since 1970-01-01 00:00:00 UTC</dd>
263          *      <dt>%S</dt> <dd>second as a decimal number</dd>
264          *      <dt>%t</dt> <dd>tab character</dd>
265          *      <dt>%T</dt> <dd>current time, equal to %H:%M:%S</dd>
266          *      <dt>%u</dt> <dd>weekday as a decimal number [1,7], with 1 representing Monday</dd>
267          *      <dt>%U</dt> <dd>week number of the current year as a decimal number, starting with the
268          *                      first Sunday as the first day of the first week</dd>
269          *      <dt>%V</dt> <dd>The ISO 8601:1988 week number of the current year as a decimal number,
270          *                      range 01 to 53, where week 1 is the first week that has at least 4 days
271          *                      in the current year, and with Monday as the first day of the week.</dd>
272          *      <dt>%w</dt> <dd>day of the week as a decimal, Sunday being 0</dd>
273          *      <dt>%W</dt> <dd>week number of the current year as a decimal number, starting with the
274          *                      first Monday as the first day of the first week</dd>
275          *      <dt>%x</dt> <dd>preferred date representation for the current locale without the time</dd>
276          *      <dt>%X</dt> <dd>preferred time representation for the current locale without the date</dd>
277          *      <dt>%y</dt> <dd>year as a decimal number without a century (range 00 to 99)</dd>
278          *      <dt>%Y</dt> <dd>year as a decimal number including the century</dd>
279          *      <dt>%z</dt> <dd>numerical time zone representation</dd>
280          *      <dt>%Z</dt> <dd>time zone name or abbreviation</dd>
281          *      <dt>%%</dt> <dd>a literal "%" character</dd>
282          *   </dl>
283          *  </dd>
284          *  <dt>locale {String} (Deprecated, optional)</dt>
285          *  <dd>
286      *   <b>Deprecated - use Y.config.lang instead, which provides access to a much larger set of built-in languages.</b>
287          *   The locale to use when displaying days of week, months of the year, and other locale specific
288          *   strings. If not specified, this defaults to "en" (though this may be overridden by the deprecated Y.config.locale).
289          *   The following locales are built in:
290          *   <dl>
291          *    <dt>en</dt>
292          *    <dd>English</dd>
293          *    <dt>en-US</dt>
294          *    <dd>US English</dd>
295          *    <dt>en-GB</dt>
296          *    <dd>British English</dd>
297          *    <dt>en-AU</dt>
298          *    <dd>Australian English (identical to British English)</dd>
299          *   </dl>
300          *   More locales may be added by subclassing of the deprecated Y.DataType.Date.Locale["en"].
301          *   See Y.DataType.Date.Locale for more information.
302          *  </dd>
303          * </dl>
304          * @return {String} Formatted date for display.
305          */
306         format : function (oDate, oConfig) {
307                 oConfig = oConfig || {};
308                 
309                 if(!Y.Lang.isDate(oDate)) {
310                         return Y.Lang.isValue(oDate) ? oDate : "";
311                 }
312
313                 var format, resources, compatMode, sLocale, LOCALE;
314
315         // Y.config.dateFormat is deprecated - remove from YUI 3.2
316         format = oConfig.format || Y.config.dateFormat  || "%Y-%m-%d";
317         // compatMode supports deprecated features - remove from YUI 3.2
318         compatMode = Y.Lang.isUndefined(Y.config.lang) && (Y.Lang.isValue(oConfig.locale) || Y.Lang.isValue(Y.config.locale));
319         if (compatMode) {
320                         sLocale = oConfig.locale || Y.config.locale;
321                         LOCALE = Y.DataType.Date.Locale;
322             sLocale = sLocale.replace(/_/g, "-");
323             
324             // Make sure we have a definition for the requested locale, or default to en.
325             if(!LOCALE[sLocale]) {
326                 var tmpLocale = sLocale.replace(/-[a-zA-Z]+$/, "");
327                 if(tmpLocale in LOCALE) {
328                     sLocale = tmpLocale;
329                 } else if(Y.config.locale in LOCALE) {
330                     sLocale = Y.config.locale;
331                 } else {
332                     sLocale = "en";
333                 }
334             }
335     
336             resources = LOCALE[sLocale];
337         } else {
338             resources = Y.Intl.get('datatype-date-format');
339         }
340
341                 var replace_aggs = function (m0, m1) {
342                         if (compatMode && m1 === "r") {
343                             return resources[m1];
344                         }
345                         var f = Dt.aggregates[m1];
346                         return (f === "locale" ? resources[m1] : f);
347                 };
348
349                 var replace_formats = function (m0, m1) {
350                         var f = Dt.formats[m1];
351                         switch(Y.Lang.type(f)) {
352                                 case "string":                                  // string => built in date function
353                                         return oDate[f]();
354                                 case "function":                                // function => our own function
355                                         return f.call(oDate, oDate, resources);
356                                 case "array":                                   // built in function with padding
357                                         if(Y.Lang.type(f[0]) === "string") {
358                                                 return xPad(oDate[f[0]](), f[1]);
359                                         } // no break; (fall through to default:)
360                                 default:
361                     // Y.config.dateFormat is deprecated - remove from YUI 3.2
362                                         return m1;
363                         }
364                 };
365
366                 // First replace aggregates (run in a loop because an agg may be made up of other aggs)
367                 while(format.match(/%[cDFhnrRtTxX]/)) {
368                         format = format.replace(/%([cDFhnrRtTxX])/g, replace_aggs);
369                 }
370
371                 // Now replace formats (do not run in a loop otherwise %%a will be replace with the value of %a)
372                 var str = format.replace(/%([aAbBCdegGHIjklmMpPsSuUVwWyYzZ%])/g, replace_formats);
373
374                 replace_aggs = replace_formats = undefined;
375
376                 return str;
377         }
378 };
379
380 Y.mix(Y.namespace("DataType.Date"), Dt);
381 /**
382  * @module datatype
383 */
384
385 /**
386  * The Date.Locale class is a container for all localised date strings
387  * used by Y.DataType.Date. It is used internally, but may be extended
388  * to provide new date localisations.
389  *
390  * To create your own Locale, follow these steps:
391  * <ol>
392  *  <li>Find an existing locale that matches closely with your needs</li>
393  *  <li>Use this as your base class.  Use Y.DataType.Date.Locale["en"] if nothing
394  *   matches.</li>
395  *  <li>Create your own class as an extension of the base class using
396  *   Y.merge, and add your own localisations where needed.</li>
397  * </ol>
398  * See the Y.DataType.Date.Locale["en-US"] and Y.DataType.Date.Locale["en-GB"]
399  * classes which extend Y.DataType.Date.Locale["en"].
400  *
401  * For example, to implement locales for French french and Canadian french,
402  * we would do the following:
403  * <ol>
404  *  <li>For French french, we have no existing similar locale, so use
405  *   Y.DataType.Date.Locale["en"] as the base, and extend it:
406  *   <pre>
407  *      Y.DataType.Date.Locale["fr"] = Y.merge(Y.DataType.Date.Locale, {
408  *          a: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"],
409  *          A: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
410  *          b: ["jan", "f&eacute;v", "mar", "avr", "mai", "jun", "jui", "ao&ucirc;", "sep", "oct", "nov", "d&eacute;c"],
411  *          B: ["janvier", "f&eacute;vrier", "mars", "avril", "mai", "juin", "juillet", "ao&ucirc;t", "septembre", "octobre", "novembre", "d&eacute;cembre"],
412  *          c: "%a %d %b %Y %T %Z",
413  *          p: ["", ""],
414  *          P: ["", ""],
415  *          x: "%d.%m.%Y",
416  *          X: "%T"
417  *      });
418  *   </pre>
419  *  </li>
420  *  <li>For Canadian french, we start with French french and change the meaning of \%x:
421  *   <pre>
422  *      Y.DataType.Date.Locale["fr-CA"] = Y.merge(Y.DataType.Date.Locale["fr"], {
423  *          x: "%Y-%m-%d"
424  *      });
425  *   </pre>
426  *  </li>
427  * </ol>
428  *
429  * With that, you can use your new locales:
430  * <pre>
431  *    var d = new Date("2008/04/22");
432  *    Y.DataType.Date.format(d, { format: "%A, %d %B == %x", locale: "fr" });
433  * </pre>
434  * will return:
435  * <pre>
436  *    mardi, 22 avril == 22.04.2008
437  * </pre>
438  * And
439  * <pre>
440  *    Y.DataType.Date.format(d, {format: "%A, %d %B == %x", locale: "fr-CA" });
441  * </pre>
442  * Will return:
443  * <pre>
444  *   mardi, 22 avril == 2008-04-22
445  * </pre>
446  * @requires oop
447  * @class DataType.Date.Locale
448  * @static
449  * @deprecated - use Y.config.lang to request one of many built-in languages instead.
450  */
451 var YDateEn = {
452         a: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
453         A: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
454         b: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
455         B: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
456         c: "%a %d %b %Y %T %Z",
457         p: ["AM", "PM"],
458         P: ["am", "pm"],
459         r: "%I:%M:%S %p",
460         x: "%d/%m/%y",
461         X: "%T"
462 };
463
464 Y.namespace("DataType.Date.Locale");
465
466 Y.DataType.Date.Locale["en"] = YDateEn;
467
468 Y.DataType.Date.Locale["en-US"] = Y.merge(YDateEn, {
469         c: "%a %d %b %Y %I:%M:%S %p %Z",
470         x: "%m/%d/%Y",
471         X: "%I:%M:%S %p"
472 });
473
474 Y.DataType.Date.Locale["en-GB"] = Y.merge(YDateEn, {
475         r: "%l:%M:%S %P %Z"
476 });
477 Y.DataType.Date.Locale["en-AU"] = Y.merge(YDateEn);
478
479
480
481
482 }, '3.3.0' ,{requires:['yui-base'], lang:['ar','ar-JO','ca','ca-ES','da','da-DK','de','de-AT','de-DE','el','el-GR','en','en-AU','en-CA','en-GB','en-IE','en-IN','en-JO','en-MY','en-NZ','en-PH','en-SG','en-US','es','es-AR','es-BO','es-CL','es-CO','es-EC','es-ES','es-MX','es-PE','es-PY','es-US','es-UY','es-VE','fi','fi-FI','fr','fr-BE','fr-CA','fr-FR','hi','hi-IN','id','id-ID','it','it-IT','ja','ja-JP','ko','ko-KR','ms','ms-MY','nb','nb-NO','nl','nl-BE','nl-NL','pl','pl-PL','pt','pt-BR','ro','ro-RO','ru','ru-RU','sv','sv-SE','th','th-TH','tr','tr-TR','vi','vi-VN','zh-Hans','zh-Hans-CN','zh-Hant','zh-Hant-HK','zh-Hant-TW']});
483
484
485 YUI.add('datatype-date', function(Y){}, '3.3.0' ,{use:['datatype-date-parse', 'datatype-date-format']});
486