diff --git a/src/xdate.js b/src/xdate.js index 6ace61c..b5f5e70 100644 --- a/src/xdate.js +++ b/src/xdate.js @@ -175,42 +175,42 @@ each(methodSubjects, function(subject, fieldIndex) { proto['get' + subject] = function() { return _getField(this[0], getUTCMode(this), fieldIndex); }; - + if (fieldIndex != YEAR) { // because there is no getUTCYear - + proto['getUTC' + subject] = function() { return _getField(this[0], true, fieldIndex); }; - + } if (fieldIndex != DAY) { // because there is no setDay or setUTCDay // and the add* and diff* methods use DATE instead - + proto['set' + subject] = function(value) { _set(this, fieldIndex, value, arguments, getUTCMode(this)); return this; // for chaining }; - + if (fieldIndex != YEAR) { // because there is no setUTCYear // and the add* and diff* methods use FULLYEAR instead - + proto['setUTC' + subject] = function(value) { _set(this, fieldIndex, value, arguments, true); return this; // for chaining }; - + proto['add' + (subjectPlurals[fieldIndex] || subject)] = function(delta, preventOverflow) { _add(this, fieldIndex, delta, preventOverflow); return this; // for chaining }; - + proto['diff' + (subjectPlurals[fieldIndex] || subject)] = function(otherDate) { return _diff(this, otherDate, fieldIndex); }; - + } - + } }); @@ -440,6 +440,79 @@ proto.toISOString = function() { return this.toUTCString(ISO_FORMAT_STRING_TZ); }; +proto.toRelativeString = function(unit) { + var relativeString = ''; + var unitString = ''; + var magnitude = 0; + var now = new XDate(); + switch (unit) { + case 'y': + unitString = 'years'; + magnitude = this.diffYears( now ); + break; + + case 'M': + unitString = 'months'; + magnitude = this.diffMonths( now ); + break; + + case 'd': + unitString = 'days'; + magnitude = this.diffDays( now ); + break; + + case 'h': + unitString = 'hours'; + magnitude = this.diffHours( now ); + break; + + case 'm': + unitString = 'minutes'; + magnitude = this.diffMinutes( now ); + break; + + case 's': + unitString = 'seconds'; + magnitude = this.diffSeconds( now ); + break; + + case 'ms': + unitString = 'milliseconds'; + magnitude = this.diffMilliseconds( now ); + break; + + // Use whichever unit yields the lowest magnitude greater than 1 + default: + if (Math.abs(magnitude = this.diffYears( now )) > 1) unitString = 'years'; + else if (Math.abs(magnitude = this.diffMonths( now )) > 1) unitString = 'months'; + else if (Math.abs(magnitude = this.diffDays( now )) > 1) unitString = 'days'; + else if (Math.abs(magnitude = this.diffHours( now )) > 1) unitString = 'hours'; + else if (Math.abs(magnitude = this.diffMinutes( now )) > 1) unitString = 'minutes'; + else if (Math.abs(magnitude = this.diffSeconds( now )) > 1) unitString = 'seconds'; + else if (Math.abs(magnitude = this.diffMilliseconds( now )) > 1) unitString = 'milliseconds'; + else magnitude = 0; + break; + } + + magnitude = parseInt( magnitude ); + + if (magnitude == 1 || magnitude == 0) { + unitString = unitString.slice(0, -1); + } + + if (magnitude > 0) { + relativeString = magnitude + ' ' + unitString + ' ago'; + } + else if (magnitude < 0) { + relativeString = 'in ' + Math.abs(magnitude) + ' ' + unitString; + } + else { + relativeString = 'within the past ' + unitString; + } + + return relativeString; +} + XDate.defaultLocale = ''; XDate.locales = { @@ -463,13 +536,13 @@ function format(xdate, formatString, settings, uniqueness, useUTC) { var locales = XDate.locales; var defaultLocaleSettings = locales[XDate.defaultLocale] || {}; var getField = curry(_getField, xdate, useUTC); - + settings = (isString(settings) ? locales[settings] : settings) || {}; - + function getSetting(name) { return settings[name] || defaultLocaleSettings[name]; } - + function getFieldAndTrace(fieldIndex) { if (uniqueness) { var i = (fieldIndex == DAY ? DATE : fieldIndex) - 1; @@ -479,7 +552,7 @@ function format(xdate, formatString, settings, uniqueness, useUTC) { } return getField(fieldIndex); } - + return _format(xdate, formatString, getFieldAndTrace, getSetting, useUTC); }