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    
164                    if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
165                            return 30;
166                    }
167    
168                    if (((year % 4) == 0) && ((year % 100) != 0) || ((year % 400) == 0)) {
169                            return 29;
170                    }
171                    else {
172                            return 28;
173                    }
174            }
175    
176            public static int getGregorianDay(Calendar cal) {
177                    int year = cal.get(Calendar.YEAR) - 1600;
178    
179                    int month = cal.get(Calendar.MONTH) + 1;
180    
181                    if (month < 3) {
182                            month += 12;
183                    }
184    
185                    int day = cal.get(Calendar.DATE);
186    
187                    int gregorianDay =
188                            (int)(6286 + (year * 365.25) - (year / 100) + (year / 400) +
189                                    (30.6 * month) + 0.2 + day);
190    
191                    return gregorianDay;
192            }
193    
194            public static Date getGTDate(Calendar cal) {
195                    Calendar gtCal = (Calendar)cal.clone();
196    
197                    gtCal.set(Calendar.HOUR_OF_DAY, 0);
198                    gtCal.set(Calendar.MINUTE, 0);
199                    gtCal.set(Calendar.SECOND, 0);
200                    gtCal.set(Calendar.MILLISECOND, 0);
201    
202                    return gtCal.getTime();
203            }
204    
205            public static int getLastDayOfWeek(Calendar cal) {
206                    int firstDayOfWeek = cal.getFirstDayOfWeek();
207    
208                    if (firstDayOfWeek == Calendar.SUNDAY) {
209                            return Calendar.SATURDAY;
210                    }
211                    else if (firstDayOfWeek == Calendar.MONDAY) {
212                            return Calendar.SUNDAY;
213                    }
214                    else if (firstDayOfWeek == Calendar.TUESDAY) {
215                            return Calendar.MONDAY;
216                    }
217                    else if (firstDayOfWeek == Calendar.WEDNESDAY) {
218                            return Calendar.TUESDAY;
219                    }
220                    else if (firstDayOfWeek == Calendar.THURSDAY) {
221                            return Calendar.WEDNESDAY;
222                    }
223                    else if (firstDayOfWeek == Calendar.FRIDAY) {
224                            return Calendar.THURSDAY;
225                    }
226    
227                    return Calendar.FRIDAY;
228            }
229    
230            public static Date getLTDate(Calendar cal) {
231                    Calendar ltCal = (Calendar)cal.clone();
232    
233                    ltCal.set(Calendar.HOUR_OF_DAY, 23);
234                    ltCal.set(Calendar.MINUTE, 59);
235                    ltCal.set(Calendar.SECOND, 59);
236                    ltCal.set(Calendar.MILLISECOND, 990);
237    
238                    return ltCal.getTime();
239            }
240    
241            public static int[] getMonthIds() {
242                    return MONTH_IDS;
243            }
244    
245            public static String[] getMonths(Locale locale) {
246                    return getMonths(locale, null);
247            }
248    
249            public static String[] getMonths(Locale locale, String pattern) {
250                    if (Validator.isNull(pattern)) {
251                            pattern = "MMMM";
252                    }
253    
254                    StringBundler sb = new StringBundler(6);
255    
256                    sb.append("months_");
257                    sb.append(pattern);
258                    sb.append("_");
259                    sb.append(locale.getLanguage());
260                    sb.append("_");
261                    sb.append(locale.getCountry());
262    
263                    String key = sb.toString();
264    
265                    String[] months = _calendarPool.get(key);
266    
267                    if (months == null) {
268                            months = new String[12];
269    
270                            Format monthFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
271                                    pattern, locale);
272    
273                            Calendar cal = CalendarFactoryUtil.getCalendar();
274    
275                            cal.set(Calendar.DATE, 1);
276    
277                            for (int i = 0; i < 12; i++) {
278                                    cal.set(Calendar.MONTH, i);
279    
280                                    months[i] = monthFormat.format(cal.getTime());
281                            }
282    
283                            _calendarPool.put(key, months);
284                    }
285    
286                    return months;
287            }
288    
289            public static Timestamp getTimestamp(Date date) {
290                    if (date == null) {
291                            return null;
292                    }
293                    else {
294                            return new Timestamp(date.getTime());
295                    }
296            }
297    
298            public static boolean isAfter(
299                    int month1, int day1, int year1, int hour1, int minute1, int amPm1,
300                    int month2, int day2, int year2, int hour2, int minute2, int amPm2,
301                    TimeZone timeZone, Locale locale) {
302    
303                    Calendar cal1 = CalendarFactoryUtil.getCalendar(timeZone, locale);
304    
305                    cal1.set(Calendar.MONTH, month1);
306                    cal1.set(Calendar.DATE, day1);
307                    cal1.set(Calendar.YEAR, year1);
308                    cal1.set(Calendar.HOUR, hour1);
309                    cal1.set(Calendar.MINUTE, minute1);
310                    cal1.set(Calendar.AM_PM, amPm1);
311    
312                    Calendar cal2 = CalendarFactoryUtil.getCalendar(timeZone, locale);
313    
314                    cal2.set(Calendar.MONTH, month2);
315                    cal2.set(Calendar.DATE, day2);
316                    cal2.set(Calendar.YEAR, year2);
317                    cal2.set(Calendar.HOUR, hour2);
318                    cal2.set(Calendar.MINUTE, minute2);
319                    cal2.set(Calendar.AM_PM, amPm2);
320    
321                    return cal1.after(cal2);
322            }
323    
324            public static boolean isBroadcastDate(int month, int day, int year) {
325                    if (!isDate(month, day, year)) {
326                            return false;
327                    }
328    
329                    Calendar cal1 = CalendarFactoryUtil.getCalendar();
330    
331                    cal1.setFirstDayOfWeek(Calendar.MONDAY);
332                    cal1.set(Calendar.MONTH, month);
333                    cal1.set(Calendar.DATE, day);
334                    cal1.set(Calendar.YEAR, year);
335    
336                    Calendar cal2 = CalendarFactoryUtil.getCalendar();
337    
338                    cal2.setFirstDayOfWeek(Calendar.MONDAY);
339                    cal2.set(Calendar.MONTH, month + 1);
340                    cal2.set(Calendar.DATE, 1);
341                    cal2.set(Calendar.YEAR, year);
342    
343                    if ((cal2.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) &&
344                            (cal2.get(Calendar.WEEK_OF_YEAR) == cal1.get(
345                                    Calendar.WEEK_OF_YEAR))) {
346    
347                            return false;
348                    }
349    
350                    return true;
351            }
352    
353            public static boolean isDate(int month, int day, int year) {
354                    return Validator.isDate(month, day, year);
355            }
356    
357            public static boolean isFuture(int month, int year) {
358                    return isFuture(
359                            month, year, TimeZoneUtil.getDefault(), LocaleUtil.getDefault());
360            }
361    
362            public static boolean isFuture(int month, int day, int year) {
363                    return isFuture(
364                            month, day, year, TimeZoneUtil.getDefault(),
365                            LocaleUtil.getDefault());
366            }
367    
368            public static boolean isFuture(
369                    int month, int day, int year, int hour, int minute, int amPm) {
370    
371                    return isFuture(
372                            month, day, year, hour, minute, amPm, TimeZoneUtil.getDefault(),
373                            LocaleUtil.getDefault());
374            }
375    
376            public static boolean isFuture(
377                    int month, int day, int year, int hour, int minute, int amPm,
378                    TimeZone timeZone, Locale locale) {
379    
380                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
381    
382                    Calendar cal = (Calendar)curCal.clone();
383    
384                    cal.set(Calendar.MONTH, month);
385                    cal.set(Calendar.DATE, day);
386                    cal.set(Calendar.YEAR, year);
387                    cal.set(Calendar.HOUR, hour);
388                    cal.set(Calendar.MINUTE, minute);
389                    cal.set(Calendar.AM_PM, amPm);
390    
391                    return cal.after(curCal);
392            }
393    
394            public static boolean isFuture(
395                    int month, int day, int year, TimeZone timeZone, Locale locale) {
396    
397                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
398    
399                    Calendar cal = (Calendar)curCal.clone();
400    
401                    cal.set(Calendar.MONTH, month);
402                    cal.set(Calendar.DATE, day);
403                    cal.set(Calendar.YEAR, year);
404    
405                    return cal.after(curCal);
406            }
407    
408            public static boolean isFuture(
409                    int month, int year, TimeZone timeZone, Locale locale) {
410    
411                    Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
412    
413                    curCal.set(Calendar.DATE, 1);
414    
415                    Calendar cal = (Calendar)curCal.clone();
416    
417                    cal.set(Calendar.MONTH, month);
418                    cal.set(Calendar.YEAR, year);
419    
420                    return cal.after(curCal);
421            }
422    
423            public static boolean isGregorianDate(int month, int day, int year) {
424                    return Validator.isGregorianDate(month, day, year);
425            }
426    
427            public static boolean isJulianDate(int month, int day, int year) {
428                    return Validator.isJulianDate(month, day, year);
429            }
430    
431            public static Calendar roundByMinutes(Calendar cal, int interval) {
432                    int minutes = cal.get(Calendar.MINUTE);
433    
434                    int delta = 0;
435    
436                    if (minutes < interval) {
437                            delta = interval - minutes;
438                    }
439                    else {
440                            delta = interval - (minutes % interval);
441                    }
442    
443                    if (delta == interval) {
444                            delta = 0;
445                    }
446    
447                    cal.add(Calendar.MINUTE, delta);
448    
449                    return cal;
450            }
451    
452            private static long _getTimeInMillis(Date date) {
453                    Calendar cal = CalendarFactoryUtil.getCalendar();
454    
455                    cal.setTime(date);
456    
457                    int year = cal.get(Calendar.YEAR);
458                    int month = cal.get(Calendar.MONTH);
459                    int day = cal.get(Calendar.DATE);
460                    int hour = 0;
461                    int minute = 0;
462                    int second = 0;
463    
464                    cal.set(year, month, day, hour, minute, second);
465    
466                    long millis = cal.getTimeInMillis() / Time.DAY;
467    
468                    return millis;
469            }
470    
471            private static Map<String, String[]> _calendarPool =
472                    new ConcurrentHashMap<String, String[]>();
473    
474    }