Tagged: Date api
Human readable past date formating in Grails
Sometimes it better to write ‘2 days ago’ instad of ’28 Jan 2015′.
You can find a lot of solution in How to calculate “time ago” in Java?.
Here is a simplest snippet for making it in Grails from my project with i18n support.
Just create new tag `timeAgo` in your project taglib:
static encodeAsForTags = [ timeAgo: [taglib:'html'] ] final static long ONE_SECOND = 1000; final static long ONE_MINUTE = ONE_SECOND * 60; final static long ONE_HOUR = ONE_MINUTE * 60; final static long ONE_DAY = ONE_HOUR * 24; /** Converts time (in milliseconds) to human-readable format "<w> days, <x> hours, <y> minutes ago" or "just now" <code> System.out.println(millisToLongDHMS(123)); System.out.println(millisToLongDHMS((5 * ONE_SECOND) + 123)); System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR)); System.out.println(millisToLongDHMS(ONE_DAY + 2 * ONE_SECOND)); System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE))); System.out.println(millisToLongDHMS((4 * ONE_DAY) + (3 * ONE_HOUR) + (2 * ONE_MINUTE) + ONE_SECOND)); System.out.println(millisToLongDHMS(42 * ONE_DAY)); </code> output : 0 second 5 seconds 1 day, 1 hour 1 day and 2 seconds 1 day, 1 hour, 2 minutes 4 days, 3 hours, 2 minutes 42 days */ private String millisToLongDHMS(long duration) { StringBuffer res = new StringBuffer(); long temp; if (duration >= ONE_MINUTE) { temp = duration / ONE_DAY; if (temp > 0) { duration -= temp * ONE_DAY; res.append(temp).append(' ').append(temp > 1 ? g.message(code: 'timeAgo.days') : g.message(code: 'timeAgo.day')).append(duration >= ONE_MINUTE ? ', ' : '') } temp = duration / ONE_HOUR; if (temp > 0) { duration -= temp * ONE_HOUR; res.append(temp).append(' ').append(temp > 1 ? g.message(code: 'timeAgo.hours') : g.message(code: 'timeAgo.hour')).append(duration >= ONE_MINUTE ? ', ' : '') } temp = duration / ONE_MINUTE if (temp > 0) { res.append(temp).append(' ').append(temp > 1 ? g.message(code: 'timeAgo.minutes') : g.message(code: 'timeAgo.minute')) } res.append(' ').append(g.message(code: 'timeAgo.ago')) return res.toString() } else { return g.message(code: 'timeAgo.justNow') } } /** * @emptyTag * * @attr date the date in past */ def timeAgo = { attrs -> Date date = attrs.date out << millisToLongDHMS((new Date().getTime()) - date.getTime()); }
And then you need to add message codes in `messages.properties`:
timeAgo.justNow=just now timeAgo.minute=minute timeAgo.minutes=minutes timeAgo.hour=hour timeAgo.hours=hours timeAgo.day=day timeAgo.days=days timeAgo.ago=ago # for Russian timeAgo.justNow=только что timeAgo.minute=минуту timeAgo.minutes=минут timeAgo.hour=час timeAgo.hours=часов timeAgo.day=день timeAgo.days=дней timeAgo.ago=назад # for Ukrainian timeAgo.justNow=тіки що timeAgo.minute=хвилину timeAgo.minutes=хвилин timeAgo.hour=годину timeAgo.hours=годин timeAgo.day=день timeAgo.days=днів timeAgo.ago=тому