text: var pad = require('../number/pad');
  var i18n = require('./i18n_');
  var dayOfTheYear = require('./dayOfTheYear');
  var timezoneOffset = require('./timezoneOffset');
  var timezoneAbbr = require('./timezoneAbbr');
  var weekOfTheYear = require('./weekOfTheYear');
  
  var _combinations = {
      'D': '%m/%d/%y',
      'F': '%Y-%m-%d',
      'r': '%I:%M:%S %p',
      'R': '%H:%M',
      'T': '%H:%M:%S',
      'x': 'locale',
      'X': 'locale',
      'c': 'locale'
  };
  
  /**
   * format date based on strftime format
   */
  function strftime(date, format, localeData) {
      localeData = localeData || i18n;
      var reToken = /%([a-z%])/gi;
  
      function makeIterator(fn) {
          return function (match, token) {
              return fn(date, token, localeData);
          };
      }
  
      return format
      .replace(reToken, makeIterator(expandCombinations))
      .replace(reToken, makeIterator(convertToken));
  }
  
  function expandCombinations(date, token, l10n) {
      if (token in _combinations) {
          var expanded = _combinations[token];
          return expanded === 'locale' ? l10n[token] : expanded;
      } else {
          return '%' + token;
      }
  }
  
  function convertToken(date, token, l10n) {
      switch (token) {
          case 'a':
              return l10n.days_abbr[date.getDay()];
          case 'A':
              return l10n.days[date.getDay()];
          case 'h':
          case 'b':
              return l10n.months_abbr[date.getMonth()];
          case 'B':
              return l10n.months[date.getMonth()];
          case 'C':
              return pad(Math.floor(date.getFullYear() / 100), 2);
          case 'd':
              return pad(date.getDate(), 2);
          case 'e':
              return pad(date.getDate(), 2, ' ');
          case 'H':
              return pad(date.getHours(), 2);
          case 'I':
              return pad(date.getHours() % 12, 2);
          case 'j':
              return pad(dayOfTheYear(date), 3);
          case 'L':
              return pad(date.getMilliseconds(), 3);
          case 'm':
              return pad(date.getMonth() + 1, 2);
          case 'M':
              return pad(date.getMinutes(), 2);
          case 'n':
              return '\n';
          case 'p':
              return date.getHours() >= 12 ? l10n.pm : l10n.am;
          case 'P':
              return convertToken(date, 'p', l10n).toLowerCase();
          case 's':
              return date.getTime() / 1000;
          case 'S':
              return pad(date.getSeconds(), 2);
          case 't':
              return '\t';
          case 'u':
              var day = date.getDay();
              return day === 0 ? 7 : day;
          case 'U':
              return pad(weekOfTheYear(date), 2);
          case 'w':
              return date.getDay();
          case 'W':
              return pad(weekOfTheYear(date, 1), 2);
          case 'y':
              return pad(date.getFullYear() % 100, 2);
          case 'Y':
              return pad(date.getFullYear(), 4);
          case 'z':
              return timezoneOffset(date);
          case 'Z':
              return timezoneAbbr(date);
          case '%':
              return '%';
          default:
              // keep unrecognized tokens
              return '%' + token;
      }
  }
  
  module.exports = strftime;
  
  
  