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