001    /**
002     * Copyright (c) 2000-2012 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 java.sql.Timestamp;
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.Map;
025    import java.util.TimeZone;
026    import java.util.concurrent.ConcurrentHashMap;
027    
028    /**
029     * @author Brian Wing Shun Chan
030     */
031    public class CalendarUtil {
032    
033            public static final String[] DAYS_ABBREVIATION = new String[] {
034                    "sunday-abbreviation", "monday-abbreviation", "tuesday-abbreviation",
035                    "wednesday-abbreviation", "thursday-abbreviation","friday-abbreviation",
036                    "saturday-abbreviation"
037            };
038    
039            public static final String ICAL_EXTENSION = "ics";
040    
041            public static final int[] MONTH_IDS = new int[] {
042                    Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL,
043                    Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST,
044                    Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER,
045                    Calendar.DECEMBER
046            };
047    
048            public static boolean afterByDay(Date date1, Date date2) {
049                    long millis1 = _getTimeInMillis(date1);
050                    long millis2 = _getTimeInMillis(date2);
051    
052                    if (millis1 > millis2) {
053                            return true;
054                    }
055                    else {
056                            return false;
057                    }
058            }
059    
060            public static boolean beforeByDay(Date date1, Date date2) {
061                    long millis1 = _getTimeInMillis(date1);
062                    long millis2 = _getTimeInMillis(date2);
063    
064                    if (millis1 < millis2) {
065                            return true;
066                    }
067                    else {
068                            return false;
069                    }
070            }
071    
072            public static boolean equalsByDay(Date date1, Date date2) {
073                    long millis1 = _getTimeInMillis(date1);
074                    long millis2 = _getTimeInMillis(date2);
075    
076                    if (millis1 == millis2) {
077                            return true;
078                    }
079                    else {
080                            return false;
081                    }
082            }
083    
084            public static int getAge(Date date, Calendar today) {
085                    Calendar birthday = CalendarFactoryUtil.getCalendar();
086    
087                    birthday.setTime(date);
088    
089                    int yearDiff = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
090    
091                    if (today.get(Calendar.MONTH) < birthday.get(Calendar.MONTH)) {
092                            yearDiff--;
093                    }
094                    else if (today.get(Calendar.MONTH) == birthday.get(Calendar.MONTH) &&
095                                     today.get(Calendar.DATE) < birthday.get(Calendar.DATE)) {
096    
097                            yearDiff--;
098                    }
099    
100                    return yearDiff;
101            }
102    
103            public static int getAge(Date date, TimeZone tz) {
104                    return getAge(date, CalendarFactoryUtil.getCalendar(tz));
105            }
106    
107            public static String[] getDays(Locale locale) {
108                    return getDays(locale, null);
109            }
110    
111            public static String[] getDays(Locale locale, String pattern) {
112                    if (Validator.isNull(pattern)) {
113                            pattern = "EEEE";
114                    }
115    
116                    StringBundler sb = new StringBundler(6);
117    
118                    sb.append("days_");
119                    sb.append(pattern);
120                    sb.append("_");
121                    sb.append(locale.getLanguage());
122                    sb.append("_");
123                    sb.append(locale.getCountry());
124    
125                    String key = sb.toString();
126    
127                    String[] days = _calendarPool.get(key);
128    
129                    if (days == null) {
130                            days = new String[7];
131    
132                            Format dayFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
133                                    pattern, locale);
134    
135                            Calendar cal = CalendarFactoryUtil.getCalendar();
136    
137                            cal.set(Calendar.DATE, 1);
138    
139                            for (int i = 0; i < 7; i++) {
140                                    cal.set(Calendar.DAY_OF_WEEK, i + 1);
141    
142                                    days[i] = dayFormat.format(cal.getTime());
143                            }
144    
145                            _calendarPool.put(key, days);
146                    }
147    
148                    return days;
149            }
150    
151            public static int getDaysInMonth(Calendar cal) {
152                    return getDaysInMonth(cal.get(Calendar.MONTH), cal.get(Calendar.YEAR));
153            }
154    
155            public static int getDaysInMonth(int month, int year) {
156                    month++;
157    
158                    if ((month == 1) || (month == 3) || (month == 5) || (month == 7) ||
159                            (month == 8) || (month == 10) || (month == 12)) {
160    
161                            return 31;
162                    }
163                    else if ((month == 4) || (month == 6) || (month == 9) ||
164                                     (month == 11)) {
165    
166                            return 30;
167                    }
168                    else {
169                            if (((year % 4) == 0) &&
170                                    ((year % 100) != 0) || ((year % 400) == 0)) {
171    
172                                    return 29;
173                            }
174                            else {
175                                    return 28;
176                            }
177                    }
178            }
179    
180            public static int getGregorianDay(Calendar cal) {
181                    int year = cal.get(Calendar.YEAR) - 1600;
182    
183                    int month = cal.get(Calendar.MONTH) + 1;
184    
185                    if (month < 3) {
186                            month += 12;
187                    }
188    
189                    int day = cal.get(Calendar.DATE);
190    
191                    int gregorianDay =
192                            (int)(6286 + (year * 365.25) - (year / 100) + (year / 400) +
193                                    (30.6 * month) + 0.2 + day);
194    
195                    return gregorianDay;
196            }
197    
198            public static Date getGTDate(Calendar cal) {
199                    Calendar gtCal = (Calendar)cal.clone();
200    
201                    gtCal.set(Calendar.HOUR_OF_DAY, 0);
202                    gtCal.set(Calendar.MINUTE, 0);
203                    gtCal.set(Calendar.SECOND, 0);
204                    gtCal.set(Calendar.MILLISECOND, 0);
205    
206                    return gtCal.getTime();
207            }
208    
209            public static int getLastDayOfWeek(Calendar cal) {
210                    int firstDayOfWeek = cal.getFirstDayOfWeek();
211    
212                    if (firstDayOfWeek == Calendar.SUNDAY) {
213                            return Calendar.SATURDAY;
214                    }
215                    else if (firstDayOfWeek == Calendar.MONDAY) {
216                            return Calendar.SUNDAY;
217                    }
218                    else if (firstDayOfWeek == Calendar.TUESDAY) {
219                            return Calendar.MONDAY;
220                    }
221                    else if (firstDayOfWeek == Calendar.WEDNESDAY) {
222                            return Calendar.TUESDAY;
223                    }
224                    else if (firstDayOfWeek == Calendar.THURSDAY) {
225                            return Calendar.WEDNESDAY;
226                    }
227                    else if (firstDayOfWeek == Calendar.FRIDAY) {
228                            return Calendar.THURSDAY;
229                    }
230    
231                    return Calendar.FRIDAY;
232            }
233    
234            public static Date getLTDate(Calendar cal) {
235                    Calendar ltCal = (Calendar)cal.clone();
236    
237                    ltCal.set(Calendar.HOUR_OF_DAY, 23);
238                    ltCal.set(Calendar.MINUTE, 59);
239                    ltCal.set(Calendar.SECOND, 59);
240                    ltCal.set(Calendar.MILLISECOND, 990);
241    
242                    return ltCal.getTime();
243            }
244    
245            public static int[] getMonthIds() {
246                    return MONTH_IDS;
247            }
248    
249            public static String[] getMonths(Locale locale) {
250                    return getMonths(locale, null);
251            }
252    
253            public static String[] getMonths(Locale locale, String pattern) {
254                    if (Validator.isNull(pattern)) {
255                            pattern = "MMMM";
256                    }
257    
258                    StringBundler sb = new StringBundler(6);
259    
260                    sb.append("months_");
261                    sb.append(pattern);
262                    sb.append("_");
263                    sb.append(locale.getLanguage());
264                    sb.append("_");
265                    sb.append(locale.getCountry());
266    
267                    String key = sb.toString();
268    
269                    String[] months = _calendarPool.get(key);
270    
271                    if (months == null) {
272                            months = new String[12];
273    
274                            Format monthFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
275                                    pattern, locale);
276    
277                            Calendar cal = CalendarFactoryUtil.getCalendar();
278    
279                            cal.set(Calendar.DATE, 1);
280    
281                            for (int i = 0; i < 12; i++) {
282                                    cal.set(Calendar.MONTH, i);
283    
284                                    months[i] = monthFormat.format(cal.getTime());
285                            }
286    
287                            _calendarPool.put(key, months);
288                    }
289    
290                    return months;
291            }
292    
293            public static Timestamp getTimestamp(Date date) {
294                    if (date == null) {
295                            return null;
296                    }
297                    else {
298                            return new Timestamp(date.getTime());
299                    }
300            }
301    
302            public static boolean isAfter(int month1, int day1, int year1, int hour1,
303                    int minute1, int amPm1, int month2, int day2, int year2, int hour2,
304                    int minute2, int amPm2, TimeZone timeZone, Locale locale) {
305    
306                    Calendar cal1 = CalendarFactoryUtil.getCalendar(timeZone, locale);
307    
308                    cal1.set(Calendar.MONTH, month1);
309                    cal1.set(Calendar.DATE, day1);
310                    cal1.set(Calendar.YEAR, year1);
311                    cal1.set(Calendar.HOUR, hour1);
312                    cal1.set(Calendar.MINUTE, minute1);
313                    cal1.set(Calendar.AM_PM, amPm1);
314    
315                    Calendar cal2 = CalendarFactoryUtil.getCalendar(timeZone, locale);
316    
317                    cal2.set(Calendar.MONTH, month2);
318                    cal2.set(Calendar.DATE, day2);
319                    cal2.set(Calendar.YEAR, year2);
320                    cal2.set(Calendar.HOUR, hour2);
321                    cal2.set(Calendar.MINUTE, minute2);
322                    cal2.set(Calendar.AM_PM, amPm2);
323    
324                    return cal1.after(cal2);
325            }
326    
327            public static boolean isBroadcastDate(int month, int day, int year) {
328                    if (!isDate(month, day, year)) {
329                            return false;
330                    }
331    
332                    Calendar cal1 = CalendarFactoryUtil.getCalendar();
333    
334                    cal1.setFirstDayOfWeek(Calendar.MONDAY);
335                    cal1.set(Calendar.MONTH, month);
336                    cal1.set(Calendar.DATE, day);
337                    cal1.set(Calendar.YEAR, year);
338    
339                    Calendar cal2 = CalendarFactoryUtil.getCalendar();
340    
341                    cal2.setFirstDayOfWeek(Calendar.MONDAY);
342                    cal2.set(Calendar.MONTH, month + 1);
343                    cal2.set(Calendar.DATE, 1);
344                    cal2.set(Calendar.YEAR, year);
345    
346                    if ((cal2.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) &&
347                            (cal2.get(Calendar.WEEK_OF_YEAR) == cal1.get(
348                                    Calendar.WEEK_OF_YEAR))) {
349    
350                            return false;
351                    }
352    
353                    return true;
354            }
355    
356            public static boolean isDate(int month, int day, int year) {
357                    return Validator.isDate(month, day, year);
358            }
359    
360            public static boolean isFuture(int month, int year) {
361                    return isFuture(
362                            month, year, TimeZoneUtil.getDefault(), LocaleUtil.getDefault());
363            }
364    
365            public static boolean isFuture(int month, int day, int year) {
366                    return isFuture(
367                            month, day, year, TimeZoneUtil.getDefault(),
368                            LocaleUtil.getDefault());
369            }
370    
371            public static boolean isFuture(
372                    int month, int day, int year, int hour, int minute, int amPm) {
373    
374                    return isFuture(
375                            month, day, year, hour, minute, amPm, TimeZoneUtil.getDefault(),
376                            LocaleUtil.getDefault());
377            }
378    
379            public static boolean isFuture(
380                    int month, int day, int year, int hour, int minute, int amPm,
381                    TimeZone timeZone, Locale locale) {
382    
383                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
384    
385                    Calendar cal = (Calendar)curCal.clone();
386    
387                    cal.set(Calendar.MONTH, month);
388                    cal.set(Calendar.DATE, day);
389                    cal.set(Calendar.YEAR, year);
390                    cal.set(Calendar.HOUR, hour);
391                    cal.set(Calendar.MINUTE, minute);
392                    cal.set(Calendar.AM_PM, amPm);
393    
394                    return cal.after(curCal);
395            }
396    
397            public static boolean isFuture(
398                    int month, int day, int year, TimeZone timeZone, Locale locale) {
399    
400                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
401    
402                    Calendar cal = (Calendar)curCal.clone();
403    
404                    cal.set(Calendar.MONTH, month);
405                    cal.set(Calendar.DATE, day);
406                    cal.set(Calendar.YEAR, year);
407    
408                    return cal.after(curCal);
409            }
410    
411            public static boolean isFuture(
412                    int month, int year, TimeZone timeZone, Locale locale) {
413    
414                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
415    
416                    curCal.set(Calendar.DATE, 1);
417    
418                    Calendar cal = (Calendar)curCal.clone();
419    
420                    cal.set(Calendar.MONTH, month);
421                    cal.set(Calendar.YEAR, year);
422    
423                    return cal.after(curCal);
424            }
425    
426            public static boolean isGregorianDate(int month, int day, int year) {
427                    return Validator.isGregorianDate(month, day, year);
428            }
429    
430            public static boolean isJulianDate(int month, int day, int year) {
431                    return Validator.isJulianDate(month, day, year);
432            }
433    
434            public static Calendar roundByMinutes(Calendar cal, int interval) {
435                    int minutes = cal.get(Calendar.MINUTE);
436    
437                    int delta = 0;
438    
439                    if (minutes < interval) {
440                            delta = interval - minutes;
441                    }
442                    else {
443                            delta = interval - (minutes % interval);
444                    }
445    
446                    if (delta == interval) {
447                            delta = 0;
448                    }
449    
450                    cal.add(Calendar.MINUTE, delta);
451    
452                    return cal;
453            }
454    
455            private static long _getTimeInMillis(Date date) {
456                    Calendar cal = CalendarFactoryUtil.getCalendar();
457    
458                    cal.setTime(date);
459    
460                    int year = cal.get(Calendar.YEAR);
461                    int month = cal.get(Calendar.MONTH);
462                    int day = cal.get(Calendar.DATE);
463                    int hour = 0;
464                    int minute = 0;
465                    int second = 0;
466    
467                    cal.set(year, month, day, hour, minute, second);
468    
469                    long millis = cal.getTimeInMillis() / Time.DAY;
470    
471                    return millis;
472            }
473    
474            private static Map<String, String[]> _calendarPool =
475                    new ConcurrentHashMap<String, String[]>();
476    
477    }