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 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(
303                    int month1, int day1, int year1, int hour1, int minute1, int amPm1,
304                    int month2, int day2, int year2, int hour2, int minute2, int amPm2,
305                    TimeZone timeZone, Locale locale) {
306    
307                    Calendar cal1 = CalendarFactoryUtil.getCalendar(timeZone, locale);
308    
309                    cal1.set(Calendar.MONTH, month1);
310                    cal1.set(Calendar.DATE, day1);
311                    cal1.set(Calendar.YEAR, year1);
312                    cal1.set(Calendar.HOUR, hour1);
313                    cal1.set(Calendar.MINUTE, minute1);
314                    cal1.set(Calendar.AM_PM, amPm1);
315    
316                    Calendar cal2 = CalendarFactoryUtil.getCalendar(timeZone, locale);
317    
318                    cal2.set(Calendar.MONTH, month2);
319                    cal2.set(Calendar.DATE, day2);
320                    cal2.set(Calendar.YEAR, year2);
321                    cal2.set(Calendar.HOUR, hour2);
322                    cal2.set(Calendar.MINUTE, minute2);
323                    cal2.set(Calendar.AM_PM, amPm2);
324    
325                    return cal1.after(cal2);
326            }
327    
328            public static boolean isBroadcastDate(int month, int day, int year) {
329                    if (!isDate(month, day, year)) {
330                            return false;
331                    }
332    
333                    Calendar cal1 = CalendarFactoryUtil.getCalendar();
334    
335                    cal1.setFirstDayOfWeek(Calendar.MONDAY);
336                    cal1.set(Calendar.MONTH, month);
337                    cal1.set(Calendar.DATE, day);
338                    cal1.set(Calendar.YEAR, year);
339    
340                    Calendar cal2 = CalendarFactoryUtil.getCalendar();
341    
342                    cal2.setFirstDayOfWeek(Calendar.MONDAY);
343                    cal2.set(Calendar.MONTH, month + 1);
344                    cal2.set(Calendar.DATE, 1);
345                    cal2.set(Calendar.YEAR, year);
346    
347                    if ((cal2.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) &&
348                            (cal2.get(Calendar.WEEK_OF_YEAR) == cal1.get(
349                                    Calendar.WEEK_OF_YEAR))) {
350    
351                            return false;
352                    }
353    
354                    return true;
355            }
356    
357            public static boolean isDate(int month, int day, int year) {
358                    return Validator.isDate(month, day, year);
359            }
360    
361            public static boolean isFuture(int month, int year) {
362                    return isFuture(
363                            month, year, TimeZoneUtil.getDefault(), LocaleUtil.getDefault());
364            }
365    
366            public static boolean isFuture(int month, int day, int year) {
367                    return isFuture(
368                            month, day, year, TimeZoneUtil.getDefault(),
369                            LocaleUtil.getDefault());
370            }
371    
372            public static boolean isFuture(
373                    int month, int day, int year, int hour, int minute, int amPm) {
374    
375                    return isFuture(
376                            month, day, year, hour, minute, amPm, TimeZoneUtil.getDefault(),
377                            LocaleUtil.getDefault());
378            }
379    
380            public static boolean isFuture(
381                    int month, int day, int year, int hour, int minute, int amPm,
382                    TimeZone timeZone, Locale locale) {
383    
384                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
385    
386                    Calendar cal = (Calendar)curCal.clone();
387    
388                    cal.set(Calendar.MONTH, month);
389                    cal.set(Calendar.DATE, day);
390                    cal.set(Calendar.YEAR, year);
391                    cal.set(Calendar.HOUR, hour);
392                    cal.set(Calendar.MINUTE, minute);
393                    cal.set(Calendar.AM_PM, amPm);
394    
395                    return cal.after(curCal);
396            }
397    
398            public static boolean isFuture(
399                    int month, int day, int year, TimeZone timeZone, Locale locale) {
400    
401                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
402    
403                    Calendar cal = (Calendar)curCal.clone();
404    
405                    cal.set(Calendar.MONTH, month);
406                    cal.set(Calendar.DATE, day);
407                    cal.set(Calendar.YEAR, year);
408    
409                    return cal.after(curCal);
410            }
411    
412            public static boolean isFuture(
413                    int month, int year, TimeZone timeZone, Locale locale) {
414    
415                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
416    
417                    curCal.set(Calendar.DATE, 1);
418    
419                    Calendar cal = (Calendar)curCal.clone();
420    
421                    cal.set(Calendar.MONTH, month);
422                    cal.set(Calendar.YEAR, year);
423    
424                    return cal.after(curCal);
425            }
426    
427            public static boolean isGregorianDate(int month, int day, int year) {
428                    return Validator.isGregorianDate(month, day, year);
429            }
430    
431            public static boolean isJulianDate(int month, int day, int year) {
432                    return Validator.isJulianDate(month, day, year);
433            }
434    
435            public static Calendar roundByMinutes(Calendar cal, int interval) {
436                    int minutes = cal.get(Calendar.MINUTE);
437    
438                    int delta = 0;
439    
440                    if (minutes < interval) {
441                            delta = interval - minutes;
442                    }
443                    else {
444                            delta = interval - (minutes % interval);
445                    }
446    
447                    if (delta == interval) {
448                            delta = 0;
449                    }
450    
451                    cal.add(Calendar.MINUTE, delta);
452    
453                    return cal;
454            }
455    
456            private static long _getTimeInMillis(Date date) {
457                    Calendar cal = CalendarFactoryUtil.getCalendar();
458    
459                    cal.setTime(date);
460    
461                    int year = cal.get(Calendar.YEAR);
462                    int month = cal.get(Calendar.MONTH);
463                    int day = cal.get(Calendar.DATE);
464                    int hour = 0;
465                    int minute = 0;
466                    int second = 0;
467    
468                    cal.set(year, month, day, hour, minute, second);
469    
470                    long millis = cal.getTimeInMillis() / Time.DAY;
471    
472                    return millis;
473            }
474    
475            private static Map<String, String[]> _calendarPool =
476                    new ConcurrentHashMap<String, String[]>();
477    
478    }