1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.kernel.util;
16  
17  import java.sql.Timestamp;
18  
19  import java.text.Format;
20  
21  import java.util.Calendar;
22  import java.util.Date;
23  import java.util.Locale;
24  import java.util.Map;
25  import java.util.TimeZone;
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  /**
29   * <a href="CalendarUtil.java.html"><b><i>View Source</i></b></a>
30   *
31   * @author Brian Wing Shun Chan
32   */
33  public class CalendarUtil {
34  
35      public static String[] DAYS_ABBREVIATION = new String[] {
36          "sunday-abbreviation", "monday-abbreviation", "tuesday-abbreviation",
37          "wednesday-abbreviation", "thursday-abbreviation","friday-abbreviation",
38          "saturday-abbreviation"
39      };
40  
41      public static final String ICAL_EXTENSION = "ics";
42  
43      public static int[] MONTH_IDS = new int[] {
44          Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL,
45          Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST,
46          Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER,
47          Calendar.DECEMBER
48      };
49  
50      public static boolean afterByDay(Date date1, Date date2) {
51          long millis1 = _getTimeInMillis(date1);
52          long millis2 = _getTimeInMillis(date2);
53  
54          if (millis1 > millis2) {
55              return true;
56          }
57          else {
58              return false;
59          }
60      }
61  
62      public static boolean beforeByDay(Date date1, Date date2) {
63          long millis1 = _getTimeInMillis(date1);
64          long millis2 = _getTimeInMillis(date2);
65  
66          if (millis1 < millis2) {
67              return true;
68          }
69          else {
70              return false;
71          }
72      }
73  
74      public static boolean equalsByDay(Date date1, Date date2) {
75          long millis1 = _getTimeInMillis(date1);
76          long millis2 = _getTimeInMillis(date2);
77  
78          if (millis1 == millis2) {
79              return true;
80          }
81          else {
82              return false;
83          }
84      }
85  
86      public static int getAge(Date date, TimeZone tz) {
87          return getAge(date, CalendarFactoryUtil.getCalendar(tz));
88      }
89  
90      public static int getAge(Date date, Calendar today) {
91          Calendar birthday = CalendarFactoryUtil.getCalendar();
92  
93          birthday.setTime(date);
94  
95          int yearDiff = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
96  
97          if (today.get(Calendar.MONTH) < birthday.get(Calendar.MONTH)) {
98              yearDiff--;
99          }
100         else if (today.get(Calendar.MONTH) == birthday.get(Calendar.MONTH) &&
101                  today.get(Calendar.DATE) < birthday.get(Calendar.DATE)) {
102 
103             yearDiff--;
104         }
105 
106         return yearDiff;
107     }
108 
109     public static String[] getDays(Locale locale) {
110         return getDays(locale, null);
111     }
112 
113     public static String[] getDays(Locale locale, String pattern) {
114         if (Validator.isNull(pattern)) {
115             pattern = "EEEE";
116         }
117 
118         StringBundler sb = new StringBundler(6);
119 
120         sb.append("days_");
121         sb.append(pattern);
122         sb.append("_");
123         sb.append(locale.getLanguage());
124         sb.append("_");
125         sb.append(locale.getCountry());
126 
127         String key = sb.toString();
128 
129         String[] days = _calendarPool.get(key);
130 
131         if (days == null) {
132             days = new String[7];
133 
134             Format dayFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
135                 pattern, locale);
136 
137             Calendar cal = CalendarFactoryUtil.getCalendar();
138 
139             cal.set(Calendar.DATE, 1);
140 
141             for (int i = 0; i < 7; i++) {
142                 cal.set(Calendar.DAY_OF_WEEK, i + 1);
143 
144                 days[i] = dayFormat.format(cal.getTime());
145             }
146 
147             _calendarPool.put(key, days);
148         }
149 
150         return days;
151     }
152 
153     public static int getDaysInMonth(Calendar cal) {
154         return getDaysInMonth(cal.get(Calendar.MONTH), cal.get(Calendar.YEAR));
155     }
156 
157     public static int getDaysInMonth(int month, int year) {
158         month++;
159 
160         if ((month == 1) || (month == 3) || (month == 5) || (month == 7) ||
161             (month == 8) || (month == 10) || (month == 12)) {
162 
163             return 31;
164         }
165         else if ((month == 4) || (month == 6) || (month == 9) ||
166                  (month == 11)) {
167 
168             return 30;
169         }
170         else {
171             if (((year % 4) == 0) &&
172                 ((year % 100) != 0) || ((year % 400) == 0)) {
173 
174                 return 29;
175             }
176             else {
177                 return 28;
178             }
179         }
180     }
181 
182     public static int getGregorianDay(Calendar cal) {
183         int year = cal.get(Calendar.YEAR) - 1600;
184 
185         int month = cal.get(Calendar.MONTH) + 1;
186 
187         if (month < 3) {
188             month += 12;
189         }
190 
191         int day = cal.get(Calendar.DATE);
192 
193         int gregorianDay =
194             (int)(6286 + (year * 365.25) - (year / 100) + (year / 400) +
195                 (30.6 * month) + 0.2 + day);
196 
197         return gregorianDay;
198     }
199 
200     public static Date getGTDate(Calendar cal) {
201         Calendar gtCal = (Calendar)cal.clone();
202 
203         gtCal.set(Calendar.HOUR_OF_DAY, 0);
204         gtCal.set(Calendar.MINUTE, 0);
205         gtCal.set(Calendar.SECOND, 0);
206         gtCal.set(Calendar.MILLISECOND, 0);
207 
208         return gtCal.getTime();
209     }
210 
211     public static int getLastDayOfWeek(Calendar cal) {
212         int firstDayOfWeek = cal.getFirstDayOfWeek();
213 
214         if (firstDayOfWeek == Calendar.SUNDAY) {
215             return Calendar.SATURDAY;
216         }
217         else if (firstDayOfWeek == Calendar.MONDAY) {
218             return Calendar.SUNDAY;
219         }
220         else if (firstDayOfWeek == Calendar.TUESDAY) {
221             return Calendar.MONDAY;
222         }
223         else if (firstDayOfWeek == Calendar.WEDNESDAY) {
224             return Calendar.TUESDAY;
225         }
226         else if (firstDayOfWeek == Calendar.THURSDAY) {
227             return Calendar.WEDNESDAY;
228         }
229         else if (firstDayOfWeek == Calendar.FRIDAY) {
230             return Calendar.THURSDAY;
231         }
232 
233         return Calendar.FRIDAY;
234     }
235 
236     public static Date getLTDate(Calendar cal) {
237         Calendar ltCal = (Calendar)cal.clone();
238 
239         ltCal.set(Calendar.HOUR_OF_DAY, 23);
240         ltCal.set(Calendar.MINUTE, 59);
241         ltCal.set(Calendar.SECOND, 59);
242         ltCal.set(Calendar.MILLISECOND, 990);
243 
244         return ltCal.getTime();
245     }
246 
247     public static int[] getMonthIds() {
248         return MONTH_IDS;
249     }
250 
251     public static String[] getMonths(Locale locale) {
252         return getMonths(locale, null);
253     }
254 
255     public static String[] getMonths(Locale locale, String pattern) {
256         if (Validator.isNull(pattern)) {
257             pattern = "MMMM";
258         }
259 
260         StringBundler sb = new StringBundler(6);
261 
262         sb.append("months_");
263         sb.append(pattern);
264         sb.append("_");
265         sb.append(locale.getLanguage());
266         sb.append("_");
267         sb.append(locale.getCountry());
268 
269         String key = sb.toString();
270 
271         String[] months = _calendarPool.get(key);
272 
273         if (months == null) {
274             months = new String[12];
275 
276             Format monthFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
277                 pattern, locale);
278 
279             Calendar cal = CalendarFactoryUtil.getCalendar();
280 
281             cal.set(Calendar.DATE, 1);
282 
283             for (int i = 0; i < 12; i++) {
284                 cal.set(Calendar.MONTH, i);
285 
286                 months[i] = monthFormat.format(cal.getTime());
287             }
288 
289             _calendarPool.put(key, months);
290         }
291 
292         return months;
293     }
294 
295     public static Timestamp getTimestamp(Date date) {
296         if (date == null) {
297             return null;
298         }
299         else {
300             return new Timestamp(date.getTime());
301         }
302     }
303 
304     public static boolean isAfter(int month1, int day1, int year1,
305                                   int hour1, int minute1, int amPm1,
306                                   int month2, int day2, int year2,
307                                   int hour2, int minute2, int amPm2,
308                                   TimeZone timeZone, Locale locale) {
309 
310         Calendar cal1 = CalendarFactoryUtil.getCalendar(timeZone, locale);
311 
312         cal1.set(Calendar.MONTH, month1);
313         cal1.set(Calendar.DATE, day1);
314         cal1.set(Calendar.YEAR, year1);
315         cal1.set(Calendar.HOUR, hour1);
316         cal1.set(Calendar.MINUTE, minute1);
317         cal1.set(Calendar.AM_PM, amPm1);
318 
319         Calendar cal2 = CalendarFactoryUtil.getCalendar(timeZone, locale);
320 
321         cal2.set(Calendar.MONTH, month2);
322         cal2.set(Calendar.DATE, day2);
323         cal2.set(Calendar.YEAR, year2);
324         cal2.set(Calendar.HOUR, hour2);
325         cal2.set(Calendar.MINUTE, minute2);
326         cal2.set(Calendar.AM_PM, amPm2);
327 
328         return cal1.after(cal2);
329     }
330 
331     public static boolean isBroadcastDate(int month, int day, int year) {
332         if (!isDate(month, day, year)) {
333             return false;
334         }
335 
336         Calendar cal1 = CalendarFactoryUtil.getCalendar();
337 
338         cal1.setFirstDayOfWeek(Calendar.MONDAY);
339         cal1.set(Calendar.MONTH, month);
340         cal1.set(Calendar.DATE, day);
341         cal1.set(Calendar.YEAR, year);
342 
343         Calendar cal2 = CalendarFactoryUtil.getCalendar();
344 
345         cal2.setFirstDayOfWeek(Calendar.MONDAY);
346         cal2.set(Calendar.MONTH, month + 1);
347         cal2.set(Calendar.DATE, 1);
348         cal2.set(Calendar.YEAR, year);
349 
350         if ((cal2.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) &&
351             (cal2.get(Calendar.WEEK_OF_YEAR) == cal1.get(
352                 Calendar.WEEK_OF_YEAR))) {
353 
354             return false;
355         }
356 
357         return true;
358     }
359 
360     public static boolean isDate(int month, int day, int year) {
361         return Validator.isDate(month, day, year);
362     }
363 
364     public static boolean isFuture(int month, int year) {
365         return isFuture(
366             month, year, TimeZoneUtil.getDefault(), LocaleUtil.getDefault());
367     }
368 
369     public static boolean isFuture(int month, int year, TimeZone timeZone,
370                                    Locale locale) {
371 
372         Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
373 
374         curCal.set(Calendar.DATE, 1);
375 
376         Calendar cal = (Calendar)curCal.clone();
377 
378         cal.set(Calendar.MONTH, month);
379         cal.set(Calendar.YEAR, year);
380 
381         return cal.after(curCal);
382     }
383 
384     public static boolean isFuture(int month, int day, int year) {
385         return isFuture(
386             month, day, year, TimeZoneUtil.getDefault(),
387             LocaleUtil.getDefault());
388     }
389 
390     public static boolean isFuture(int month, int day, int year,
391                                    TimeZone timeZone, Locale locale) {
392 
393         Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
394 
395         Calendar cal = (Calendar)curCal.clone();
396 
397         cal.set(Calendar.MONTH, month);
398         cal.set(Calendar.DATE, day);
399         cal.set(Calendar.YEAR, year);
400 
401         return cal.after(curCal);
402     }
403 
404     public static boolean isFuture(int month, int day, int year, int hour,
405                                    int minute, int amPm) {
406 
407         return isFuture(
408             month, day, year, hour, minute, amPm, TimeZoneUtil.getDefault(),
409             LocaleUtil.getDefault());
410     }
411 
412     public static boolean isFuture(int month, int day, int year,
413                                    int hour, int minute, int amPm,
414                                    TimeZone timeZone, Locale locale) {
415 
416         Calendar curCal = CalendarFactoryUtil.getCalendar(timeZone, locale);
417 
418         Calendar cal = (Calendar)curCal.clone();
419 
420         cal.set(Calendar.MONTH, month);
421         cal.set(Calendar.DATE, day);
422         cal.set(Calendar.YEAR, year);
423         cal.set(Calendar.HOUR, hour);
424         cal.set(Calendar.MINUTE, minute);
425         cal.set(Calendar.AM_PM, amPm);
426 
427         return cal.after(curCal);
428     }
429 
430     public static boolean isGregorianDate(int month, int day, int year) {
431         return Validator.isGregorianDate(month, day, year);
432     }
433 
434     public static boolean isJulianDate(int month, int day, int year) {
435         return Validator.isJulianDate(month, day, year);
436     }
437 
438     public static Calendar roundByMinutes(Calendar cal, int interval) {
439         int minutes = cal.get(Calendar.MINUTE);
440 
441         int delta = 0;
442 
443         if (minutes < interval) {
444             delta = interval - minutes;
445         }
446         else {
447             delta = interval - (minutes % interval);
448         }
449 
450         if (delta == interval) {
451             delta = 0;
452         }
453 
454         cal.add(Calendar.MINUTE, delta);
455 
456         return cal;
457     }
458 
459     private static long _getTimeInMillis(Date date) {
460         Calendar cal = CalendarFactoryUtil.getCalendar();
461 
462         cal.setTime(date);
463 
464         int year = cal.get(Calendar.YEAR);
465         int month = cal.get(Calendar.MONTH);
466         int day = cal.get(Calendar.DATE);
467         int hour = 0;
468         int minute = 0;
469         int second = 0;
470 
471         cal.set(year, month, day, hour, minute, second);
472 
473         long millis = cal.getTimeInMillis() / Time.DAY;
474 
475         return millis;
476     }
477 
478     private static Map<String, String[]> _calendarPool =
479         new ConcurrentHashMap<String, String[]>();
480 
481 }