Created
January 13, 2009 10:45
-
-
Save kneath/46398 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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.getAttribute('utc')); | |
var rel = span.getAttribute('format'); | |
span.set('html', rel == 'words' ? utc.timeAgoInWords() : utc.strftime(rel)) | |
}); | |
} | |
} | |
var Locale = new Hash({ | |
monthNames: (typeof Date.CultureInfo == 'undefined' ? 'January February March April May June July August September October November December'.split(' ') : Date.CultureInfo.monthNames), | |
dayNames: (typeof Date.CultureInfo == 'undefined' ? 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' ') : Date.CultureInfo.dayNames) | |
}); | |
String.prototype.pad = function(l, s, t){ | |
s = s || " "; | |
return (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length) + 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2)) + this + s.substr(0, l - t) : this; | |
}; | |
$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.toString().pad(2, '0');}; | |
return format.replace(/\%([aAbBcdeHImMpSwyY])/g, "{$1}").substitute({ | |
'a': Locale.get('dayNames')[day].substr(0, 3), | |
'A': Locale.get('dayNames')[day], | |
'b': Locale.get('monthNames')[month].substr(0, 3), | |
'B': Locale.get('monthNames')[month], | |
'c': this.toString(), | |
'd': pad(this.getDate()), | |
'H': pad(hours), | |
'I': (hours % 12 == 0) ? 12 : pad(hours % 12), | |
'm': pad(month + 1), | |
'e': month + 1, | |
'M': pad(minutes), | |
'p': hours >= 12 ? 'PM' : 'AM', | |
'S': pad(this.getSeconds()), | |
'w': day, | |
'y': pad(this.getFullYear() % 100), | |
'Y': this.getFullYear().toString() | |
}); | |
}, | |
timeAgoInWords: function() { | |
var relative_to = (arguments.length > 0) ? arguments[1] : new Date(); | |
return Date.distanceOfTimeInWords(this, relative_to, arguments[2]); | |
} | |
}); | |
$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