text: #!/usr/bin/env node
  
  // Based on CoffeeScript by andrewschaaf on github
  //
  // TODO:
  // - past and future dates, especially < 1900 and > 2100
  // - locales
  // - look for edge cases
  
  var assert = require('assert')
    , lib = require('../lib')
  
      // Tue, 07 Jun 2011 18:51:45 GMT
    , Time = new Date(1307472705067)
  
  assert.fn = function(value, msg) {
    assert.equal('function', typeof value, msg)
  }
  
  assert.format = function(format, expected, expectedUTC, time) {
    time = time || Time
    function _assertFmt(expected, name) {
      name = name || 'strftime'
      var actual = lib[name](format, time)
      assert.equal(expected, actual,
                   name + '("' + format + '", ' + time + ') is ' + JSON.stringify(actual)
                   + ', expected ' + JSON.stringify(expected))
    }
  
    if (expected) _assertFmt(expected)
    _assertFmt(expectedUTC || expected, 'strftimeUTC')
  }
  
  /// check exports
  assert.fn(lib.strftime)
  assert.fn(lib.strftimeUTC)
  assert.fn(lib.localizedStrftime)
  ok('Exports')
  
  /// time zones
  if (!process.env.TZ || process.env.TZ == 'America/Vancouver') {
    testTimezone('P[DS]T')
    assert.format('%C', '01', '01', new Date(100, 0, 1))
    ok('Time zones (' + process.env.TZ + ')')
  }
  else if (process.env.TZ == 'CET') {
    testTimezone('CES?T')
    assert.format('%C', '01', '00', new Date(100, 0, 1))
    ok('Time zones (' + process.env.TZ + ')')
  }
  else {
    console.log('(Current timezone has no tests: ' + process.env.TZ + ')')
  }
  
  /// check all formats in GMT, most coverage
  assert.format('%A', 'Tuesday')
  assert.format('%a', 'Tue')
  assert.format('%B', 'June')
  assert.format('%b', 'Jun')
  assert.format('%C', '20')
  assert.format('%D', '06/07/11')
  assert.format('%d', '07')
  assert.format('%e', '7')
  assert.format('%F', '2011-06-07')
  assert.format('%H', null, '18')
  assert.format('%h', 'Jun')
  assert.format('%I', null, '06')
  assert.format('%j', null, '158')
  assert.format('%k', null, '18')
  assert.format('%L', '067')
  assert.format('%l', null, ' 6')
  assert.format('%M', null, '51')
  assert.format('%m', '06')
  assert.format('%n', '\n')
  assert.format('%P', null, 'pm')
  assert.format('%p', null, 'PM')
  assert.format('%R', null, '18:51')
  assert.format('%r', null, '06:51:45 PM')
  assert.format('%S', '45')
  assert.format('%s', '1307472705')
  assert.format('%T', null, '18:51:45')
  assert.format('%t', '\t')
  assert.format('%U', '23')
  assert.format('%U', '24', null, new Date(+Time + 5 * 86400000))
  assert.format('%u', '2')
  assert.format('%v', '7-Jun-2011')
  assert.format('%W', '23')
  assert.format('%W', '23', null, new Date(+Time + 5 * 86400000))
  assert.format('%w', '2')
  assert.format('%Y', '2011')
  assert.format('%y', '11')
  assert.format('%Z', null, 'GMT')
  assert.format('%z', null, '+0000')
  assert.format('%%', '%') // any other char
  ok('GMT')
  
  
  /// locales
  
  var it_IT =
  { days: words('domenica lunedi martedi mercoledi giovedi venerdi sabato')
  , shortDays: words('dom lun mar mer gio ven sab')
  , months: words('gennaio febbraio marzo aprile maggio giugno luglio agosto settembre ottobre novembre dicembre')
  , shortMonths: words('gen feb mar apr mag giu lug ago set ott nov dic')
  , AM: 'it$AM'
  , PM: 'it$PM'
  , am: 'it$am'
  , pm: 'it$pm'
  , formats: {
      D: 'it$%m/%d/%y'
    , F: 'it$%Y-%m-%d'
    , R: 'it$%H:%M'
    , r: 'it$%I:%M:%S %p'
    , T: 'it$%H:%M:%S'
    , v: 'it$%e-%b-%Y'
    }
  }
  
  assert.format_it = function(format, expected, expectedUTC) {
    function _assertFmt(expected, name) {
      name = name || 'strftime'
      var actual = lib[name](format, Time, it_IT)
      assert.equal(expected, actual,
                   name + '("' + format + '", Time) is ' + JSON.stringify(actual)
                   + ', expected ' + JSON.stringify(expected))
    }
  
    if (expected) _assertFmt(expected)
    _assertFmt(expectedUTC || expected, 'strftimeUTC')
  }
  
  assert.format_it('%A', 'martedi')
  assert.format_it('%a', 'mar')
  assert.format_it('%B', 'giugno')
  assert.format_it('%b', 'giu')
  assert.format_it('%D', 'it$06/07/11')
  assert.format_it('%F', 'it$2011-06-07')
  assert.format_it('%p', null, 'it$PM')
  assert.format_it('%P', null, 'it$pm')
  assert.format_it('%R', null, 'it$18:51')
  assert.format_it('%r', null, 'it$06:51:45 it$PM')
  assert.format_it('%T', null, 'it$18:51:45')
  assert.format_it('%v', 'it$7-giu-2011')
  ok('Localization')
  
  
  /// helpers
  
  function words(s) { return (s || '').split(' '); }
  
  function ok(s) { console.log('[ \033[32mOK\033[0m ] ' + s) }
  
  // Pass a regex or string that matches the timezone abbrev, e.g. %Z above.
  // Don't pass GMT! Every date includes it and it will fail.
  // Be careful if you pass a regex, it has to quack like the default one.
  function testTimezone(regex) {
    regex = typeof regex === 'string' ? RegExp('\\((' + regex + ')\\)$') : regex
    var match = Time.toString().match(regex)
    if (match) {
      var off = Time.getTimezoneOffset()
        , hourOff = off / 60
        , hourDiff = Math.floor(hourOff)
        , hours = 18 - hourDiff
        , padSpace24 = hours < 10 ? ' ' : ''
        , padZero24 = hours < 10 ? '0' : ''
        , hour24 = String(hours)
        , padSpace12 = (hours % 12) < 10 ? ' ' : ''
        , padZero12 = (hours % 12) < 10 ? '0' : ''
        , hour12 = String(hours % 12)
        , sign = hourDiff < 0 ? '+' : '-'
        , minDiff = Time.getTimezoneOffset() - (hourDiff * 60)
        , mins = String(51 - minDiff)
        , tz = match[1]
        , ampm = hour12 == hour24 ? 'AM' : 'PM'
        , R = hour24 + ':' + mins
        , r = padZero12 + hour12 + ':' + mins + ':45 ' + ampm
        , T = R + ':45'
      assert.format('%H', padZero24 + hour24, '18')
      assert.format('%I', padZero12 + hour12, '06')
      assert.format('%k', padSpace24 + hour24, '18')
      assert.format('%l', padSpace12 + hour12, ' 6')
      assert.format('%M', mins)
      assert.format('%P', ampm.toLowerCase(), 'pm')
      assert.format('%p', ampm, 'PM')
      assert.format('%R', R, '18:51')
      assert.format('%r', r, '06:51:45 PM')
      assert.format('%T', T, '18:51:45')
      assert.format('%Z', tz, 'GMT')
      assert.format('%z', sign + '0' + Math.abs(hourDiff) + '00', '+0000')
    }
  }
  