001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.language.LanguageUtil;
018    
019    import java.text.Format;
020    
021    import java.util.Calendar;
022    import java.util.Date;
023    import java.util.Locale;
024    import java.util.TimeZone;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     */
029    public class Time {
030    
031            public static final long DAY = Time.HOUR * 24;
032    
033            public static final String DURATION_FORMAT = "HH:mm:ss.SSS";
034    
035            public static final long HOUR = Time.MINUTE * 60;
036    
037            public static final long MINUTE = Time.SECOND * 60;
038    
039            public static final long MONTH = Time.DAY * 30;
040    
041            public static final String RFC822_FORMAT = "EEE, dd MMM yyyy HH:mm:ss Z";
042    
043            public static final long SECOND = 1000;
044    
045            public static final String SHORT_TIMESTAMP_FORMAT = "yyyyMMddkkmm";
046    
047            public static final String TIMESTAMP_FORMAT = "yyyyMMddkkmmssSSS";
048    
049            public static final long WEEK = Time.DAY * 7;
050    
051            public static final long YEAR = Time.DAY * 365;
052    
053            public static Date getDate(Calendar cal) {
054                    Calendar adjustedCal = CalendarFactoryUtil.getCalendar();
055    
056                    adjustedCal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
057                    adjustedCal.set(Calendar.MONTH, cal.get(Calendar.MONTH));
058                    adjustedCal.set(Calendar.DATE, cal.get(Calendar.DATE));
059                    adjustedCal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY));
060                    adjustedCal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE));
061                    adjustedCal.set(Calendar.SECOND, cal.get(Calendar.SECOND));
062                    adjustedCal.set(Calendar.MILLISECOND, cal.get(Calendar.MILLISECOND));
063    
064                    return adjustedCal.getTime();
065            }
066    
067            public static Date getDate(Date date, TimeZone tz) {
068                    Calendar cal = CalendarFactoryUtil.getCalendar(tz);
069    
070                    cal.setTime(date);
071    
072                    return getDate(cal);
073            }
074    
075            public static Date getDate(TimeZone tz) {
076                    Calendar cal = CalendarFactoryUtil.getCalendar(tz);
077    
078                    return getDate(cal);
079            }
080    
081            public static String getDescription(long milliseconds) {
082                    return getDescription(milliseconds, false);
083            }
084    
085            public static String getDescription(
086                    long milliseconds, boolean approximate) {
087    
088                    String s = StringPool.BLANK;
089    
090                    int x = 0;
091    
092                    if (approximate) {
093                            if (milliseconds <= 0) {
094                                    s = "0 Seconds";
095                            }
096                            else if (milliseconds < MINUTE) {
097                                    x = (int)(milliseconds / SECOND);
098    
099                                    s = x + " Second";
100                            }
101                            else if (milliseconds < HOUR) {
102                                    x = (int)(milliseconds / MINUTE);
103    
104                                    s = x + " Minute";
105                            }
106                            else if (milliseconds < DAY) {
107                                    x = (int)(milliseconds / HOUR);
108    
109                                    s = x + " Hour";
110                            }
111                            else if (milliseconds < MONTH) {
112                                    x = (int)(milliseconds / DAY);
113    
114                                    s = x + " Day";
115                            }
116                            else if (milliseconds < YEAR) {
117                                    x = (int)(milliseconds / MONTH);
118    
119                                    s = x + " Month";
120                            }
121                            else if (milliseconds >= YEAR) {
122                                    x = (int)(milliseconds / YEAR);
123    
124                                    s = x + " Year";
125                            }
126                    }
127                    else {
128                            if ((milliseconds % WEEK) == 0) {
129                                    x = (int)(milliseconds / WEEK);
130    
131                                    s = x + " Week";
132                            }
133                            else if ((milliseconds % DAY) == 0) {
134                                    x = (int)(milliseconds / DAY);
135    
136                                    s = x + " Day";
137                            }
138                            else if ((milliseconds % HOUR) == 0) {
139                                    x = (int)(milliseconds / HOUR);
140    
141                                    s = x + " Hour";
142                            }
143                            else if ((milliseconds % MINUTE) == 0) {
144                                    x = (int)(milliseconds / MINUTE);
145    
146                                    s = x + " Minute";
147                            }
148                            else if ((milliseconds % SECOND) == 0) {
149                                    x = (int)(milliseconds / SECOND);
150    
151                                    s = x + " Second";
152                            }
153                            else {
154                                    x = (int)milliseconds;
155    
156                                    s = x + " Millisecond";
157                            }
158                    }
159    
160                    if (x > 1) {
161                            s += "s";
162                    }
163    
164                    return s;
165            }
166    
167            public static String getDuration(long milliseconds) {
168                    return getSimpleDate(new Date(milliseconds), DURATION_FORMAT);
169            }
170    
171            public static String getRelativeTimeDescription(
172                    long milliseconds, Locale locale, TimeZone timeZone) {
173    
174                    Format timeFormat = FastDateFormatFactoryUtil.getTime(locale, timeZone);
175    
176                    int daysBetween = DateUtil.getDaysBetween(
177                            new Date(milliseconds), new Date(), timeZone);
178    
179                    long millisAgo = System.currentTimeMillis() - milliseconds;
180    
181                    if (millisAgo <= Time.MINUTE) {
182                            return LanguageUtil.get(locale, "about-a-minute-ago");
183                    }
184                    else if (millisAgo < Time.HOUR) {
185                            return LanguageUtil.format(
186                                    locale, "x-minutes-ago", (millisAgo / Time.MINUTE));
187                    }
188                    else if ((millisAgo / Time.HOUR) == 1) {
189                            return LanguageUtil.get(locale, "about-an-hour-ago");
190                    }
191                    else if ((millisAgo < Time.DAY) || (daysBetween == 0)) {
192                            return LanguageUtil.format(
193                                    locale, "x-hours-ago", (millisAgo / Time.HOUR));
194                    }
195                    else if (daysBetween == 1) {
196                            return LanguageUtil.format(
197                                    locale, "yesterday-at-x", timeFormat.format(milliseconds));
198                    }
199    
200                    Format dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
201                            "EEEE, MMMMM dd, yyyy", locale, timeZone);
202    
203                    return dateFormat.format(milliseconds);
204            }
205    
206            public static String getRFC822() {
207                    return getRFC822(new Date());
208            }
209    
210            public static String getRFC822(Date date) {
211                    return getSimpleDate(date, RFC822_FORMAT);
212            }
213    
214            public static String getShortTimestamp() {
215                    return getShortTimestamp(new Date());
216            }
217    
218            public static String getShortTimestamp(Date date) {
219                    return getSimpleDate(date, SHORT_TIMESTAMP_FORMAT);
220            }
221    
222            public static String getSimpleDate(Date date, String format) {
223                    String s = StringPool.BLANK;
224    
225                    if (date != null) {
226                            Format dateFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
227                                    format);
228    
229                            s = dateFormat.format(date);
230                    }
231    
232                    return s;
233            }
234    
235            public static String getTimestamp() {
236                    return getTimestamp(new Date());
237            }
238    
239            public static String getTimestamp(Date date) {
240                    return getSimpleDate(date, TIMESTAMP_FORMAT);
241            }
242    
243    }