/* * This software is distributed under the terms of the FSF * Gnu Lesser General Public License (see lgpl.txt). * * This program is distributed WITHOUT ANY WARRANTY. See the * GNU General Public License for more details. */ package com.scooterframework.web.util; import java.util.Calendar; import java.util.Date; import java.util.Locale; /** * D class has helper methods for Date and Time. * * @author (Fei) John Chen */ public class D { public static final long ONE_SECOND = 1000L; public static final long ONE_MINUTE = ONE_SECOND * 60; public static final long ONE_HOUR = ONE_MINUTE * 60; public static final long ONE_DAY = ONE_HOUR * 24; public static final long ONE_WEEK = ONE_DAY * 7; public static final long ONE_MONTH = ONE_DAY * 30; public static final long ONE_YEAR = ONE_DAY * 365; protected static final String KEY_SECONDS_AFTER = "friendlytime.seconds.after"; protected static final String KEY_MINUTES_AFTER = "friendlytime.minutes.after"; protected static final String KEY_HOURS_AFTER = "friendlytime.hours.after"; protected static final String KEY_DAYS_AFTER = "friendlytime.days.after"; protected static final String KEY_WEEKS_AFTER = "friendlytime.weeks.after"; protected static final String KEY_MONTHS_AFTER = "friendlytime.months.after"; protected static final String KEY_YEARS_AFTER = "friendlytime.years.after"; protected static final String KEY_MOMENTS_AFTER = "friendlytime.moments.after"; protected static final String KEY_NOW = "friendlytime.now"; protected static final String KEY_MOMENTS_AGO = "friendlytime.moments.ago"; protected static final String KEY_SECONDS_AGO = "friendlytime.seconds.ago"; protected static final String KEY_MINUTES_AGO = "friendlytime.minutes.ago"; protected static final String KEY_HOURS_AGO = "friendlytime.hours.ago"; protected static final String KEY_DAYS_AGO = "friendlytime.days.ago"; protected static final String KEY_WEEKS_AGO = "friendlytime.weeks.ago"; protected static final String KEY_MONTHS_AGO = "friendlytime.months.ago"; protected static final String KEY_YEARS_AGO = "friendlytime.years.ago"; protected static final String COUNT_UNIT_SEPARATOR = "_"; /** * Returns a human-friendly date/time message. See <tt>messages.properties</tt> * file for messages. You may override the message by providing your own * messages in a messages properties file of your own locale. * * <pre> * Sample outputs: * <tt>moments from now</tt> * <tt>right now</tt> * <tt>5 minutes from now</tt> * <tt>2 weeks ago</tt> * <tt>10 years from now</tt> * </pre> * * @param d a Date instance * @return friendly date/time message */ public static String message(Date d) { String s = diffFromNow(d); String[] sm = s.split(COUNT_UNIT_SEPARATOR); return W.message(sm[1], sm); } /** * Returns a human-friendly date/time message in a specific locale. * * See <tt>messages.properties</tt> * file for messages. You may override the message by providing your own * messages in a messages properties file of your own locale. * * <pre> * Sample outputs: * <tt>moments from now</tt> * <tt>right now</tt> * <tt>5 minutes from now</tt> * <tt>2 weeks ago</tt> * <tt>10 years from now</tt> * </pre> * * @param d a Date instance * @return friendly date/time message */ public static String message(Date d, Locale locale) { String s = diffFromNow(d); String[] sm = s.split(COUNT_UNIT_SEPARATOR); return W.message(sm[1], locale, sm); } private static String diffFromNow(Date d) { if (d == null) throw new IllegalArgumentException("Date cannot be null."); long count = 0L; String key = ""; long diff = d.getTime() - Calendar.getInstance().getTimeInMillis(); if (diff >= ONE_YEAR) { count = countTime(diff, ONE_YEAR); key = KEY_YEARS_AFTER; } else if (diff >= ONE_MONTH){ count = countTime(diff, ONE_MONTH); key = KEY_MONTHS_AFTER; } else if (diff >= ONE_WEEK){ count = countTime(diff, ONE_WEEK); key = KEY_WEEKS_AFTER; } else if (diff >= ONE_DAY){ count = countTime(diff, ONE_DAY); key = KEY_DAYS_AFTER; } else if (diff >= ONE_HOUR){ count = countTime(diff, ONE_HOUR); key = KEY_HOURS_AFTER; } else if (diff >= ONE_MINUTE){ count = countTime(diff, ONE_MINUTE); key = KEY_MINUTES_AFTER; } else if (diff >= ONE_SECOND){ count = countTime(diff, ONE_SECOND); key = KEY_SECONDS_AFTER; } else if (diff > 0){ key = KEY_MOMENTS_AFTER; } else if (diff == 0){ key = KEY_NOW; } else if (diff <= (ONE_YEAR * (-1))){ count = countTime(diff, ONE_YEAR); key = KEY_YEARS_AGO; } else if (diff <= (ONE_MONTH * (-1))){ count = countTime(diff, ONE_MONTH); key = KEY_MONTHS_AGO; } else if (diff <= (ONE_WEEK * (-1))){ count = countTime(diff, ONE_WEEK); key = KEY_WEEKS_AGO; } else if (diff <= (ONE_DAY * (-1))){ count = countTime(diff, ONE_DAY); key = KEY_DAYS_AGO; } else if (diff <= (ONE_HOUR * (-1))){ count = countTime(diff, ONE_HOUR); key = KEY_HOURS_AGO; } else if (diff <= (ONE_MINUTE * (-1))){ count = countTime(diff, ONE_MINUTE); key = KEY_MINUTES_AGO; } else if (diff <= (ONE_SECOND * (-1))){ count = countTime(diff, ONE_SECOND); key = KEY_SECONDS_AGO; } else if (diff < 0){ key = KEY_MOMENTS_AGO; } return count + COUNT_UNIT_SEPARATOR + key; } private static long countTime(long diff, long interval) { return Math.abs(diff)/interval; } }