Skip to content

Instantly share code, notes, and snippets.

@kneath
Created January 13, 2009 10:44
Show Gist options
  • Save kneath/46397 to your computer and use it in GitHub Desktop.
Save kneath/46397 to your computer and use it in GitHub Desktop.
/**
* Format any UTC timestamp on the page to the users local timezone.
*/
var DateFormat = {
autoParse: function(){
$$('span.timestamp').each(function(span) {
var utc = Date.parseUTC(span.innerHTML);
var rel = span.getAttribute('rel');
span.update(rel == 'words' ? utc.timeAgoInWords() : utc.strftime(rel))
});
}
}
Object.extend(Date.prototype, {
/**
* Given a formatted string, replace the necessary items and return.
* Example: Time.now().strftime("%B %d, %Y") => February 11, 2008
* @param {String} format The formatted string used to format the results
*/
strftime: function(format) {
var day = this.getDay(), month = this.getMonth();
var hours = this.getHours(), minutes = this.getMinutes();
function pad(num) { return num.toPaddedString(2); };
return format.gsub(/\%([aAbBcdHImMpSwyY])/, function(part) {
switch(part[1]) {
case 'a': return $w("Sun Mon Tue Wed Thu Fri Sat")[day]; break;
case 'A': return $w("Sunday Monday Tuesday Wednesday Thursday Friday Saturday")[day]; break;
case 'b': return $w("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")[month]; break;
case 'B': return $w("January February March April May June July August September October November December")[month]; break;
case 'c': return this.toString(); break;
case 'd': return pad(this.getDate()); break;
case 'H': return pad(hours); break;
case 'I': return pad((hours + 12) % 12); break;
case 'm': return pad(month + 1); break;
case 'M': return pad(minutes); break;
case 'p': return hours > 12 ? 'PM' : 'AM'; break;
case 'S': return pad(this.getSeconds()); break;
case 'w': return day; break;
case 'y': return pad(this.getFullYear() % 100); break;
case 'Y': return this.getFullYear().toString(); break;
}
}.bind(this));
},
timeAgoInWords: function() {
var relative_to = (arguments.length > 0) ? arguments[1] : new Date();
return Date.distanceOfTimeInWords(this, relative_to, arguments[2]);
}
});
Object.extend(Date, {
/**
* Common formats passed to strftime
*/
strftimeFormats: {
time: "%I:%M %p",
day: "%B %d",
short: '%b %d',
dayName: "%A"
},
/**
* Get an array back with hours, minutes and seconds from now to a future date.
* @param {Date} to The future time used to get equate the difference
* @return {Array} [hours, minutes, seconds]
*/
differenceFromNow: function(to) {
var seconds = Math.ceil((new Date().getTime() - to.getTime()) / 1000);
var hours = Math.floor(seconds / 3600).toPaddedString(2);
seconds = Math.floor(seconds % 3600);
var minutes = Math.floor(seconds / 60).toPaddedString(2);
seconds = (seconds % 60).toPaddedString(2);
return [hours, minutes, seconds];
},
/**
* Parse a string date and return a UTC date
* @param {String} value Formatted date string
* @return Date
*/
parseUTC: function(value) {
var localDate = new Date(value);
var utcSeconds = Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate(), localDate.getHours(), localDate.getMinutes(), localDate.getSeconds())
return new Date(utcSeconds);
},
/**
* Return the distance of time in words between two Dates
* Example: '5 days ago', 'about an hour ago'
* @param {Date} fromTime The start date to use in the calculation
* @param {Date} toTime The end date to use in the calculation
* @param {Boolean} Include the time in the output
*/
distanceOfTimeInWords: function(fromTime, toTime, includeTime) {
var delta = parseInt((toTime.getTime() - fromTime.getTime()) / 1000);
if(delta < 60) {
return 'less than a minute ago';
} else if(delta < 120) {
return 'about a minute ago';
} else if(delta < (45*60)) {
return (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (120*60)) {
return 'about an hour ago';
} else if(delta < (24*60*60)) {
return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
return '1 day ago';
} else {
var days = (parseInt(delta / 86400)).toString();
if(days > 5) {
var fmt = '%B %d'
if(toTime.getYear() != fromTime.getYear()) { fmt += ', %Y' }
if(includeTime) fmt += ' %I:%M %p'
return fromTime.strftime(fmt);
} else {
return days + " days ago"
}
}
}
});
// Time helpers by MARTIN STRÖM
Object.extend(Number.prototype, {
seconds: function() {
return this * 1000;
},
minutes: function() {
return this * (60).seconds();
},
hours: function() {
return this * (60).minutes();
},
days: function() {
return this * (24).hours();
},
weeks: function(args) {
return this * (7).days();
},
fortnights: function() {
return this * (2).weeks();
},
months: function() {
return this * (30).days();
},
years: function() {
return parseInt(this * (365.25).days())
},
since: function(time) {
time = time || new Date();
if (time instanceof Date) time = time.getTime();
return this + time;
},
ago: function(time) {
time = time || new Date();
if (time instanceof Date) time = time.getTime();
return time - this;
},
toDate: function() {
var date = new Date();
date.setTime(this);
return date;
}
});
Object.extend(Number.prototype, {
second: Number.prototype.seconds,
minute: Number.prototype.minutes,
hour: Number.prototype.hours,
day: Number.prototype.days,
week: Number.prototype.weeks,
fortnight: Number.prototype.fortnights,
month: Number.prototype.months,
year: Number.prototype.years,
from_now: Number.prototype.since,
fromNow: Number.prototype.since,
until: Number.prototype.ago
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment