Uploaded image for project: 'Apache Cordova'
  1. Apache Cordova
  2. CB-6132

Globalization plugin method getDatePattern always returns short date style on iOS.

    XMLWordPrintableJSON

Details

    Description

      Here are a few examples to demonstrate the problem:

      navigator.globalization.getDatePattern(function(properties) {
          console.log('pattern: ' + properties.pattern); // prints "M/d/yy"
      }, function() {}, { formatLength: 'short', selector: 'date' });
      
      navigator.globalization.getDatePattern(function(properties) {
          console.log('pattern: ' + properties.pattern); // prints "M/d/yy"
      }, function() {}, { formatLength: 'medium', selector: 'date' });
      
      navigator.globalization.getDatePattern(function(properties) {
          console.log('pattern: ' + properties.pattern); // prints "M/d/yy"
      }, function() {}, { formatLength: 'long', selector: 'date' });
      
      navigator.globalization.getDatePattern(function(properties) {
          console.log('pattern: ' + properties.pattern); // prints "M/d/yy"
      }, function() {}, { formatLength: 'full', selector: 'date' });
      

      As you can see, the pattern is the same for all format lengths. This is happening because in the iOS plugin code it's iterating over the options dictionary keys, but because order matters, the logic inside the loop is flawed. Here's the block I'm referring to:

      if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
          NSEnumerator* enumerator = [items keyEnumerator];
          id key;
      
          // iterate through all the options
          while ((key = [enumerator nextObject])) {
              id item = [items valueForKey:key];
      
              // make sure that only string values are present
              if ([item isKindOfClass:[NSString class]]) {
                  // get the desired format length
                  if ([key isEqualToString:@"formatLength"]) {
                      if ([item isEqualToString:@"short"]) {
                          style = kCFDateFormatterShortStyle;
                      } else if ([item isEqualToString:@"medium"]) {
                          style = kCFDateFormatterMediumStyle;
                      } else if ([item isEqualToString:@"long"]) {
                          style = kCFDateFormatterLongStyle;
                      } else if ([item isEqualToString:@"full"]) {
                          style = kCFDateFormatterFullStyle;
                      }
                  }
                  // get the type of date and time to generate
                  else if ([key isEqualToString:@"selector"]) {
                      if ([item isEqualToString:@"date"]) {
                          dateStyle = style;
                          timeStyle = kCFDateFormatterNoStyle;
                      } else if ([item isEqualToString:@"time"]) {
                          dateStyle = kCFDateFormatterNoStyle;
                          timeStyle = style;
                      } else if ([item isEqualToString:@"date and time"]) {
                          dateStyle = style;
                          timeStyle = style;
                      }
                  }
              }
          }
      }
      

      The selector key runs first, which relies on the style variable being set correctly, but this doesn't get set until the 2nd iteration of the loop when the formatLength key is evaluated.

      Attachments

        Activity

          People

            Unassigned Unassigned
            arahlf Alan Rahlf
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: