|
| 1 | +/// strftime |
| 2 | +/// https://github.com/samsonjs/strftime |
| 3 | +/// @_sjs |
| 4 | +/// |
| 5 | +/// Copyright 2010 - 2011 Sami Samhuri <sami.samhuri@gmail.com> |
| 6 | +/// MIT License |
| 7 | + |
| 8 | +;(function() { |
| 9 | + |
| 10 | + //// Export the API |
| 11 | + var namespace; |
| 12 | + |
| 13 | + // CommonJS / Node module |
| 14 | + if (typeof exports !== 'undefined') { |
| 15 | + namespace = exports; |
| 16 | + } |
| 17 | + |
| 18 | + // Browsers and other environments |
| 19 | + else { |
| 20 | + // Get the global object. Works in ES3, ES5, and ES5 strict mode. |
| 21 | + namespace = (function(){ return this || (1,eval)('this') }()); |
| 22 | + } |
| 23 | + |
| 24 | + namespace.strftime = strftime; |
| 25 | + namespace.strftimeUTC = strftimeUTC; |
| 26 | + namespace.localizedStrftime = localizedStrftime; |
| 27 | + namespace.getLocalizedStrftime = function(locale) { |
| 28 | + console.log('[strftime] DEPRECATION NOTICE: getLocalizedStrftime is deprecated, use localizedStrftime instead'); |
| 29 | + return (namespace.getLocalizedStrftime = localizedStrftime)(locale); |
| 30 | + }; |
| 31 | + //// |
| 32 | + |
| 33 | + function words(s) { return (s || '').split(' '); } |
| 34 | + |
| 35 | + var DefaultLocale = |
| 36 | + { days: words('Sunday Monday Tuesday Wednesday Thursday Friday Saturday') |
| 37 | + , shortDays: words('Sun Mon Tue Wed Thu Fri Sat') |
| 38 | + , months: words('January February March April May June July August September October November December') |
| 39 | + , shortMonths: words('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec') |
| 40 | + , AM: 'AM' |
| 41 | + , PM: 'PM' |
| 42 | + } |
| 43 | + |
| 44 | + function strftime(fmt, d, locale) { |
| 45 | + return _strftime(fmt, d, locale, false); |
| 46 | + } |
| 47 | + |
| 48 | + function strftimeUTC(fmt, d, locale) { |
| 49 | + return _strftime(fmt, d, locale, true); |
| 50 | + } |
| 51 | + |
| 52 | + function localizedStrftime(locale) { |
| 53 | + return function(fmt, d) { |
| 54 | + return strftime(fmt, d, locale); |
| 55 | + }; |
| 56 | + } |
| 57 | + |
| 58 | + // locale is an object with the same structure as DefaultLocale |
| 59 | + function _strftime(fmt, d, locale, _useUTC) { |
| 60 | + // d and locale are optional so check if d is really the locale |
| 61 | + if (d && !(d instanceof Date)) { |
| 62 | + locale = d; |
| 63 | + d = undefined; |
| 64 | + } |
| 65 | + d = d || new Date(); |
| 66 | + locale = locale || DefaultLocale; |
| 67 | + locale.formats = locale.formats || {}; |
| 68 | + var msDelta = 0; |
| 69 | + if (_useUTC) { |
| 70 | + msDelta = (d.getTimezoneOffset() || 0) * 60000; |
| 71 | + d = new Date(d.getTime() + msDelta); |
| 72 | + } |
| 73 | + |
| 74 | + // Most of the specifiers supported by C's strftime, and one from Ruby (%L) |
| 75 | + return fmt.replace(/%(.)/g, function(_, c) { |
| 76 | + switch (c) { |
| 77 | + case 'A': return locale.days[d.getDay()]; |
| 78 | + case 'a': return locale.shortDays[d.getDay()]; |
| 79 | + case 'B': return locale.months[d.getMonth()]; |
| 80 | + case 'b': // fall through |
| 81 | + case 'h': return locale.shortMonths[d.getMonth()]; |
| 82 | + case 'D': return _strftime(locale.formats.D || '%m/%d/%y', d, locale); |
| 83 | + case 'd': return pad(d.getDate()); |
| 84 | + case 'e': return d.getDate(); |
| 85 | + case 'F': return _strftime(locale.formats.F || '%Y-%m-%d', d, locale); |
| 86 | + case 'H': return pad(d.getHours()); |
| 87 | + case 'I': return pad(hours12(d)); |
| 88 | + case 'k': return pad(d.getHours(), ' '); |
| 89 | + case 'L': return pad(Math.floor(d.getTime() % 1000), 3); |
| 90 | + case 'l': return pad(hours12(d), ' '); |
| 91 | + case 'M': return pad(d.getMinutes()); |
| 92 | + case 'm': return pad(d.getMonth() + 1); |
| 93 | + case 'n': return '\n'; |
| 94 | + case 'p': return d.getHours() < 12 ? locale.AM : locale.PM; |
| 95 | + case 'R': return _strftime(locale.formats.R || '%H:%M', d, locale); |
| 96 | + case 'r': return _strftime(locale.formats.r || '%I:%M:%S %p', d, locale); |
| 97 | + case 'S': return pad(d.getSeconds()); |
| 98 | + case 's': return Math.floor((d.getTime() - msDelta) / 1000); |
| 99 | + case 'T': return _strftime(locale.formats.T || '%H:%M:%S', d, locale); |
| 100 | + case 't': return '\t'; |
| 101 | + case 'u': |
| 102 | + var day = d.getDay(); |
| 103 | + return day == 0 ? 7 : day; // 1 - 7, Monday is first day of the week |
| 104 | + case 'v': return _strftime(locale.formats.v || '%e-%b-%Y', d, locale); |
| 105 | + case 'w': return d.getDay(); // 0 - 6, Sunday is first day of the week |
| 106 | + case 'Y': return d.getFullYear(); |
| 107 | + case 'y': |
| 108 | + var y = String(d.getFullYear()); |
| 109 | + return y.slice(y.length - 2); |
| 110 | + case 'Z': |
| 111 | + if (_useUTC) { |
| 112 | + return "GMT"; |
| 113 | + } |
| 114 | + else { |
| 115 | + var tz = d.toString().match(/\((\w+)\)/); |
| 116 | + return tz && tz[1] || ''; |
| 117 | + } |
| 118 | + case 'z': |
| 119 | + if (_useUTC) { |
| 120 | + return "+0000"; |
| 121 | + } |
| 122 | + else { |
| 123 | + var off = d.getTimezoneOffset(); |
| 124 | + return (off < 0 ? '+' : '-') + pad(off / 60) + pad(off % 60); |
| 125 | + } |
| 126 | + default: return c; |
| 127 | + } |
| 128 | + }); |
| 129 | + } |
| 130 | + |
| 131 | + // Default padding is '0' and default length is 2, both are optional. |
| 132 | + function pad(n, padding, length) { |
| 133 | + |
| 134 | + // pad(n, <length>) |
| 135 | + if (typeof padding === 'number') { |
| 136 | + length = padding; |
| 137 | + padding = '0'; |
| 138 | + } |
| 139 | + |
| 140 | + // Defaults handle pad(n) and pad(n, <padding>) |
| 141 | + padding = padding || '0'; |
| 142 | + length = length || 2; |
| 143 | + |
| 144 | + var s = String(n); |
| 145 | + while (s.length < length) s = padding + s; |
| 146 | + return s; |
| 147 | + } |
| 148 | + |
| 149 | + function hours12(d) { |
| 150 | + var hour = d.getHours(); |
| 151 | + if (hour == 0) hour = 12; |
| 152 | + else if (hour > 12) hour -= 12; |
| 153 | + return hour; |
| 154 | + } |
| 155 | + |
| 156 | +}()); |
0 commit comments