/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.gui.common.time.converter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; /** * Convert the passed value in to a relative date compared to now. * If the passed value is -1, the output will be empty (as a value of 0 * returns the number of days since the epoch) * @author Joseph Marques */ public class RelativeDurationConverter implements Converter { private static final long MILLIS_IN_SECOND = 1000L; private static final long MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND; private static final long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE; private static final long NEVER = -1; private static final long MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR; private static final SimpleDateFormat dayFormatter = new SimpleDateFormat("D"); private static final SimpleDateFormat formatter = new SimpleDateFormat("hh:mm aaa z"); public static TimeZone tz = null; public Object getAsObject(FacesContext context, UIComponent component, String value) { return null; // we only support rendering, deserialization back into object not possible } public String getAsString(FacesContext context, UIComponent component, Object value) { if (value == null) { return "0"; // visual indicator of issue } long millis = 0; if (value instanceof Long) { millis = (Long) value; } else if (value instanceof Double) { millis = ((Double) value).longValue(); } else if (value instanceof Date) { millis = ((Date)value).getTime(); } else { throw new IllegalArgumentException("The " + RelativeDurationConverter.class.getSimpleName() + " converter does not support rendering objects of type " + value.getClass().getSimpleName()); } if (millis== NEVER) return ""; String result = format(millis); return result; } public static String format(long eventMillis) { int dayOfYearToday = Integer.parseInt(dayFormatter.format(System.currentTimeMillis())); int dayOfYearEvent = Integer.parseInt(dayFormatter.format(eventMillis)); String result = null; if (dayOfYearEvent == dayOfYearToday) { // <time> result = formatter.format(new Date(eventMillis)); } else if (dayOfYearEvent == dayOfYearToday - 1) { // "yesterday" <time> result = "Yesterday, " + formatter.format(new Date(eventMillis)); } else { // <time> "ago" result = getRelativeTimeAgo(eventMillis) + " ago"; } return result; } private static TimeZone getTimeZone() { if (tz == null) { return TimeZone.getDefault(); } else { return tz; } } private static String getRelativeTimeAgo(long millis) { StringBuilder buf = new StringBuilder(); long timeAgo = System.currentTimeMillis() - millis; int count = 0; int days = (int) (timeAgo / MILLIS_IN_DAY); timeAgo %= MILLIS_IN_DAY; if (days > 0) { count++; buf.append(days).append(" day"); if (days != 1) buf.append("s"); } int hours = (int) (timeAgo / MILLIS_IN_HOUR); timeAgo %= MILLIS_IN_HOUR; if (hours > 0) { count++; if (buf.length() > 0) buf.append(", "); buf.append(hours).append(" hour"); if (hours != 1) buf.append("s"); } if (count < 2) { int mins = (int) (timeAgo / MILLIS_IN_MINUTE); timeAgo %= MILLIS_IN_MINUTE; if (mins > 0) { if (buf.length() > 0) buf.append(", "); buf.append(mins).append(" minute"); if (mins != 1) buf.append("s"); } } return buf.toString(); } }