diff --git a/index.js b/index.js index 2770f469..64361dc5 100644 --- a/index.js +++ b/index.js @@ -30,6 +30,14 @@ exports.init = function (options) { _config.filters = _.extend(filters, options.filters); _config.tags = _.extend(tags, options.tags); + if(_config.dateStrings) { + dateformat._months = _config.dateStrings.months || dateformat._months; + dateformat._days = _config.dateStrings.days || dateformat._days; + dateformat._ordinals = _config.dateStrings.ordinals || dateformat._ordinals; + dateformat._ampm = _config.dateStrings.ampm || dateformat._ampm; + dateformat._AMPM = _config.dateStrings.AMPM || dateformat._AMPM; + } + dateformat.defaultTZOffset = _config.tzOffset; }; diff --git a/lib/dateformat.js b/lib/dateformat.js index 9b81040b..ae48ddc6 100644 --- a/lib/dateformat.js +++ b/lib/dateformat.js @@ -1,13 +1,4 @@ -var _ = require('underscore'), - _months = { - full: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - abbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - }, - _days = { - full: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - abbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - alt: {'-1': 'Yesterday', 0: 'Today', 1: 'Tomorrow'} - }; +var _ = require('underscore'); /* DateZ is licensed under the MIT License: @@ -17,6 +8,29 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ exports.defaultTZOffset = 0; +exports._months = { + full: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + abbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + }; +exports._days = { + full: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + abbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + alt: {'-1': 'Yesterday', 0: 'Today', 1: 'Tomorrow'} + }; +exports._ampm = [ + { comparator:function(hour){ return hour < 12; }, result: "am"}, + { comparator:function(hour){ return hour >= 12; }, result: "pm"}, + ]; +exports._AMPM = [ + { comparator:function(hour){ return hour < 12; }, result: "AM"}, + { comparator:function(hour){ return hour >= 12; }, result: "PM"}, + ]; +exports._ordinals = [ + { comparator:function(day){ return day % 10 === 1 && day !== 11; }, result: "st"}, + { comparator:function(day){ return day % 10 === 2 && day !== 12; }, result: "nd"}, + { comparator:function(day){ return day % 10 === 3 && day !== 13; }, result: "rd"}, + { comparator:function(day){ return true; }, result: "th"} // default + ]; exports.DateZ = function () { var members = { 'default': ['getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'toISOString', 'toGMTString', 'toUTCString', 'valueOf', 'getTime'], @@ -103,23 +117,29 @@ exports.d = function (input) { return (input.getDate() < 10 ? '0' : '') + input.getDate(); }; exports.D = function (input) { - return _days.abbr[input.getDay()]; + return exports._days.abbr[input.getDay()]; }; exports.j = function (input) { return input.getDate(); }; exports.l = function (input) { - return _days.full[input.getDay()]; + return exports._days.full[input.getDay()]; }; exports.N = function (input) { - return input.getDay(); + return input.getDay() + 1; }; exports.S = function (input) { var d = input.getDate(); - return (d % 10 === 1 && d !== 11 ? 'st' : (d % 10 === 2 && d !== 12 ? 'nd' : (d % 10 === 3 && d !== 13 ? 'rd' : 'th'))); + var s; + _.each(exports._ordinals, function(element, index, list){ + if(typeof s !== "undefined") return; + var comparator = element.comparator; + if(comparator(d)) s = element.result; + }); + return s; }; exports.w = function (input) { - return input.getDay() - 1; + return input.getDay(); }; exports.z = function (input, offset, abbr) { var year = input.getFullYear(), @@ -149,13 +169,13 @@ exports.W = function (input) { // Month exports.F = function (input) { - return _months.full[input.getMonth()]; + return exports._months.full[input.getMonth()]; }; exports.m = function (input) { return (input.getMonth() < 9 ? '0' : '') + (input.getMonth() + 1); }; exports.M = function (input) { - return _months.abbr[input.getMonth()]; + return exports._months.abbr[input.getMonth()]; }; exports.n = function (input) { return input.getMonth() + 1; @@ -182,10 +202,24 @@ exports.y = function (input) { // Time exports.a = function (input) { - return input.getHours() < 12 ? 'am' : 'pm'; + var s; + var d = input.getHours(); + _.each(exports._ampm, function(element, index, list){ + if(typeof s !== "undefined") return; + var comparator = element.comparator; + if(comparator(d)) s = element.result; + }); + return s; }; exports.A = function (input) { - return input.getHours() < 12 ? 'AM' : 'PM'; + var s; + var d = input.getHours(); + _.each(exports._AMPM, function(element, index, list){ + if(typeof s !== "undefined") return; + var comparator = element.comparator; + if(comparator(d)) s = element.result; + }); + return s; }; exports.B = function (input) { var hours = input.getUTCHours(), beats; diff --git a/lib/filters.test.js b/lib/filters.test.js index 2a6ce81a..fed0518c 100644 --- a/lib/filters.test.js +++ b/lib/filters.test.js @@ -51,7 +51,6 @@ function makeDate(tzOffset, y, m, d, h, i, s) { exports.date = function (test) { var date = makeDate(420, 2011, 8, 6, 9, 5, 2), tpl = swig.compile('{{ d|date("d", 420) }}'); - function testFormat(format, expected) { testFilter(test, 'date("' + format + '", 420)', { v: date }, expected, format); } @@ -60,9 +59,9 @@ exports.date = function (test) { testFormat('D', 'Tue'); testFormat('j', '6'); testFormat('l', 'Tuesday'); - testFormat('N', '2'); + testFormat('N', '3'); testFormat('S', 'th'); - testFormat('w', '1'); + testFormat('w', '2'); testFormat('z', '248'); testFilter(test, 'date("z", 480)', { v: makeDate(480, 2011, 0, 1) }, '0', 'z'); testFilter(test, 'date("z", 480)', { v: makeDate(480, 2011, 11, 31) }, '364', 'z'); @@ -112,6 +111,18 @@ exports.date = function (test) { testFormat('r', 'Tue, 06 Sep 2011 16:05:02 GMT'); testFormat('U', '1315325102'); + // Test teen ordinals + date = makeDate(420, 2011, 8, 11, 9, 5, 2), + + testFormat('d', '11'); + testFormat('D', 'Sun'); + testFormat('j', '11'); + testFormat('l', 'Sunday'); + testFormat('N', '1'); + testFormat('S', 'th'); + testFormat('w', '0'); + testFormat('z', '253'); + test.done(); }; diff --git a/lib/spanish.dates.test.js b/lib/spanish.dates.test.js new file mode 100644 index 00000000..91aa692d --- /dev/null +++ b/lib/spanish.dates.test.js @@ -0,0 +1,71 @@ +var swig = require('../index'), + DateZ = require('./dateformat').DateZ; + +swig.init({ + allowErrors: true, + dateStrings:{ + days:{ + full: ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo'], + abbr: ['lun', 'mar', 'mié', 'jue', 'vie', 'sab', 'dom'], + alt: {'-1': 'de ayer', 0: 'de hoy', 1: 'de mañana'} + }, + months:{ + full: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'], + abbr: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'] + }, + ordinals: [ + { comparator : function(number){ return number % 10 === 1 || number % 10 === 3; }, result:"er" }, + { comparator : function(number){ return true; }, result:".o" } + ] + // AM and PM are the same in spanish so use defaults + } + }); + +function testFilter(test, filter, input, output, message) { + var tpl = swig.compile('{{ v|' + filter + ' }}'); + test.strictEqual(tpl(input), output, message); +} + +// Create dates for a particular timezone offset. +// For example, specifying 480 (offset in minutes) for tzOffset creates a date +// in your local timezone that is the same date as the specified y,m,d,h,i,s in PST. +function makeDate(tzOffset, y, m, d, h, i, s) { + var date = new Date(y, m || 0, d || 0, h || 0, i || 0, s || 0), + offset = date.getTimezoneOffset(); + + if (offset !== tzOffset) { // timezone offset in PST for september + date = new Date(date.getTime() - ((offset * 60000) - (tzOffset * 60000))); + } + + return date; +} + +exports.date = function (test) { + var date = makeDate(420, 2011, 8, 6, 9, 5, 2), + tpl = swig.compile('{{ d|date("d", 420) }}'); + + function testFormat(format, expected) { + testFilter(test, 'date("' + format + '", 420)', { v: date }, expected, format); + } + // Day + testFormat('D', 'mié'); + testFormat('l', 'miércoles'); + testFormat('S', '.o'); + + // Month + testFormat('F', 'septiembre'); + testFormat('M', 'sep'); + + // Time + testFormat('a', 'am'); + testFormat('A', 'AM'); + + // Test teen ordinals + date = makeDate(420, 2011, 8, 11, 9, 5, 2), + + testFormat('D', 'lun'); + testFormat('l', 'lunes'); + testFormat('S', 'er'); + + test.done(); +}; diff --git a/scripts/runtests.js b/scripts/runtests.js index fc494526..79045776 100644 --- a/scripts/runtests.js +++ b/scripts/runtests.js @@ -10,7 +10,8 @@ var util = require('util'), AssertionError = require(__dirname + '/../node_modules/nodeunit/lib/assert').AssertionError, config, i, - l; + l, + isWindows = (/^Windows/).test(require("os").type()); process.argv.forEach(function (val, index, array) { if (index < 2) { @@ -121,4 +122,7 @@ for (i = 0; i < l; i += 1) { ignore += ' ! -path "' + config.pathIgnore[i] + '"'; } -child_process.exec('find . -name "*.test.js" ' + ignore, { cwd: config.root }, runTests); +if(isWindows) + child_process.exec('find.exe ../. -name "*.test.js" ' + ignore, runTests); +else + child_process.exec('find . -name "*.test.js" ' + ignore, { cwd: config.root }, runTests);