[FIX] python strftime to moment.js format conversion
authorFabien Meghazi <fme@openerp.com>
Wed, 5 Nov 2014 12:42:06 +0000 (13:42 +0100)
committerFabien Meghazi <fme@openerp.com>
Wed, 5 Nov 2014 14:28:00 +0000 (15:28 +0100)
addons/web/static/src/js/formats.js
addons/web/static/test/formats.js
openerp/addons/base/res/res_lang_view.xml

index f98e7ca..0ec366d 100644 (file)
@@ -114,7 +114,7 @@ instance.web.human_size = function(size) {
 instance.web.format_value = function (value, descriptor, value_if_empty) {
     var l10n = _t.database.parameters;
     var date_format = instance.web.normalize_format(l10n.date_format);
-    var time_format = instance.web.normalize_format(l10n.time_format)
+    var time_format = instance.web.normalize_format(l10n.time_format);
     // If NaN value, display as with a `false` (empty cell)
     if (typeof value === 'number' && isNaN(value)) {
         value = false;
@@ -331,54 +331,63 @@ instance.web.round_decimals = function(value, decimals){
 };
 
 /**
-+ * 
-+ * convert python.strftime format into moment.js format
-+ * inspired from : https://github.com/uruz/moment-datetime/blob/master/moment-datetime.js
-+*/
-instance.web.normalize_format = function(format){
-    if (!format)
-        return false;
-    var replacements = {
-            'a': 'ddd',
-            'A': 'dddd',
-            'b': 'MMM',
-            'B': 'MMMM',
-            //'c': //%c is defined too vaguely
-            'd': 'DD',
-            //'f': JS have no support for microseconds and moment.js have no support for milliseconds
-            'H': 'HH',
-            'I': 'hh',
-            'j': 'DDDD',
-            'm': 'MM',
-            'M': 'mm',
-            'p': 'A',
-            'S': 'ss',
-            'U': 'ww',//ww is for Sunday-based week
-            'w': 'd',
-            //'W': 'ww',//%W is weeknumber for weeks starting from Monday and it is not implemented in moment.js
-            //'x':
-            //'X': //%x and %X are defined too vaguely to be implemented 
-            'y': 'YY',
-            'Y': 'YYYY',
-            'z': 'ZZ',
-            //'Z': 'z', - moment.js does not support timezone names
-            '%': '%'
-    }
-    var moment_format = '', directive_index = 0, replacement, unformatted;
-    while (format.indexOf('%') !== -1){
-        directive_index = format.indexOf('%') + 1;
-        replacement = replacements[format[directive_index]];
-        unformatted = format.substr(0, directive_index-1);
-        if (unformatted.length){
-                unformatted = '[' + unformatted.replace(/(\[|\])/g, '\\$&') +']';
+ * Convert Python strftime to escaped moment.js format.
+ *
+ * @param {String} value original format
+ */
+instance.web.normalize_format = function (value) {
+    if (_normalize_format_cache[value] === undefined) {
+        var isletter = /[a-zA-Z]/,
+            output = [],
+            inToken = false,
+            table = instance.web.normalize_format_table;
+
+        for (var index=0; index < value.length; ++index) {
+            var character = value[index];
+            if (character === '%' && !inToken) {
+                inToken = true;
+                continue;
+            }
+            if (isletter.test(character)) {
+                if (inToken && table[character] !== undefined) {
+                    character = table[character];
+                } else {
+                    character = '[' + character + ']'; // moment.js escape
+                }
+            }
+            output.push(character);
+            inToken = false;
         }
-        moment_format += unformatted + (replacement ? replacement : format[directive_index]);
-        format = format.substr(directive_index+1);
+        _normalize_format_cache[value] = output.join('');
     }
-    if (format.length){
-        moment_format += '['+format+']';
-    }
-    return moment_format;
+    return _normalize_format_cache[value];
+};
+instance.web.normalize_format_table = {
+    // Python strftime to moment.js conversion table
+    // See openerp/addons/base/res/res_lang_view.xml
+    // for details about supported directives
+    'a': 'ddd',
+    'A': 'dddd',
+    'b': 'MMM',
+    'B': 'MMMM',
+    'd': 'DD',
+    'H': 'HH',
+    'I': 'hh',
+    'j': 'DDDD',
+    'm': 'MM',
+    'M': 'mm',
+    'p': 'A',
+    'S': 'ss',
+    'U': 'ww',
+    'W': 'WW',
+    'w': 'd',
+    'y': 'YY',
+    'Y': 'YYYY',
+    // unsupported directives
+    'c': 'ddd MMM D HH:mm:ss YYYY',
+    'x': 'MM/DD/YY',
+    'X': 'HH:mm:ss'
 };
+var _normalize_format_cache = {};
 
 })();
index 2d0504c..0f594c4 100644 (file)
@@ -167,22 +167,24 @@ openerp.testing.section('web-formats', {
     dependencies: ['web.formats']
 }, function (test) {
     test('ES date format', function (instance) {
+        var old_format = instance.web._t.database.parameters.date_format;
         instance.web._t.database.parameters.date_format = '%a, %Y %b %d';
         var date = instance.web.str_to_date("2009-05-04");
         strictEqual(instance.web.format_value(date, {type:"date"}),
                     'Mon, 2009 May 04');
         strictEqual(instance.web.parse_value('Mon, 2009 May 04', {type: 'date'}),
                     '2009-05-04');
-        instance.web._t.database.parameters.date_format = '%m/%d/%Y';
+        instance.web._t.database.parameters.date_format = old_format;
     });
     test('extended ES date format', function (instance) {
-        instance.web._t.database.parameters.date_format = '%a, %Y.eko %b ren %da';
+        var old_format = instance.web._t.database.parameters.date_format;
+        instance.web._t.database.parameters.date_format = '%a, %Y.eko %b %da';
         var date = instance.web.str_to_date("2009-05-04");
         strictEqual(instance.web.format_value(date, {type:"date"}),
-                    'Mon, 2009.eko May ren 04');
-        strictEqual(instance.web.parse_value('Mon, 2009.eko May ren 04', {type: 'date'}),
+                    'Mon, 2009.eko May 04a');
+        strictEqual(instance.web.parse_value('Mon, 2009.eko May 04a', {type: 'date'}),
                     '2009-05-04');
-        instance.web._t.database.parameters.date_format = '%m/%d/%Y';
+        instance.web._t.database.parameters.date_format = old_format;
     });
 
 });
index 7757562..6b3b0e3 100644 (file)
@@ -39,7 +39,7 @@
                         <field name="active" />
                         <field name="translatable"/>
                     </group>
-                    <separator colspan="4" string="Legends for Date and Time Formats"/>
+                    <separator colspan="4" string="Legends for supported Date and Time Formats"/>
                     <group col="4" colspan="4">
                          <label align="0.0" string="%%a - Abbreviated weekday name."/>
                          <label align="0.0" string="%%A - Full weekday name."/>
                          <label align="0.0" string="%%b - Abbreviated month name."/>
                          <label align="0.0" string="%%B - Full month name." />
                          <newline/>
-                         <label align="0.0" string="%%c - Appropriate date and time representation." />
                          <label align="0.0" string="%%d - Day of the month [01,31]." />
+                         <label align="0.0" string="%%j - Day of the year [001,366]." />
                          <newline/>
                          <label align="0.0" string="%%H - Hour (24-hour clock) [00,23]." />
                          <label align="0.0" string="%%I - Hour (12-hour clock) [01,12]." />
                          <newline/>
-                         <label align="0.0" string="%%j - Day of the year [001,366]." />
-                         <label align="0.0" string="%%m - Month number [01,12]." />
-                         <newline/>
                          <label align="0.0" string="%%M - Minute [00,59]." />
                          <label align="0.0" string="%%p - Equivalent of either AM or PM." />
                          <newline/>
                          <label align="0.0" string="%%S - Seconds [00,61]." />
                          <label align="0.0" string="%%w - Weekday number [0(Sunday),6]." />
                          <newline/>
-                         <label align="0.0" string="%%x - Appropriate date representation." />
-                         <label align="0.0" string="%%X - Appropriate time representation." />
-                         <newline/>
                          <label align="0.0" string="%%y - Year without century [00,99]." />
                          <label align="0.0" string="%%Y - Year with century." />
                          <newline/>
-                         <label align="0.0" string="%%U - Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0." />
-                         <label align="0.0" string="%%W - Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0." />
-                         <newline/>
-                         <label align="0.0" string="======================================================" />
+                         <label align="0.0" string="%%m - Month number [01,12]." />
                     </group>
                     <newline/>
                     <group colspan="4" col="4">
                         <separator string="Examples" colspan="4"/>
                         <newline/>
-                        <label align="0.0" string="1.  %%c              ==> Fri Dec  5 18:25:20 2008"/>
+                        <label align="0.0" string="1.  %%b, %%B         ==> Dec, December"/>
                         <label align="0.0" string="2.  %%a ,%%A         ==> Fri, Friday"/>
                         <newline/>
-                        <label align="0.0" string="3.  %%x ,%%X         ==> 12/05/08, 18:25:20"/>
-                        <label align="0.0" string="4.  %%b, %%B         ==> Dec, December"/>
-                        <newline/>
-                        <label align="0.0" string="5.  %%y, %%Y         ==> 08, 2008"/>
-                        <label align="0.0" string="6.  %%d, %%m         ==> 05, 12"/>
+                        <label align="0.0" string="3.  %%y, %%Y         ==> 08, 2008"/>
+                        <label align="0.0" string="4.  %%d, %%m         ==> 05, 12"/>
                         <newline/>
-                        <label align="0.0" string="7.  %%H:%%M:%%S      ==> 18:25:20"/>
-                        <label align="0.0" string="8.  %%I:%%M:%%S %%p  ==> 06:25:20 PM"/>
+                        <label align="0.0" string="5.  %%H:%%M:%%S      ==> 18:25:20"/>
+                        <label align="0.0" string="6.  %%I:%%M:%%S %%p  ==> 06:25:20 PM"/>
                         <newline/>
-                        <label align="0.0" string="9.  %%j              ==> 340"/>
-                        <label align="0.0" string="10. %%S              ==> 20"/>
+                        <label align="0.0" string="7.  %%j              ==> 340"/>
+                        <label align="0.0" string="8. %%S              ==> 20"/>
                         <newline/>
-                        <label align="0.0" string="11. %%U or %%W       ==> 48 (49th week)"/>
-                        <label align="0.0" string="12. %%w              ==> 5 ( Friday is the 6th day)"/>
+                        <label align="0.0" string="9. %%w              ==> 5 ( Friday is the 6th day)"/>
                         <newline/>
                     </group>
                   </sheet>