1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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 int[] MONTH_IDS = new int[] {
42          Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL,
43          Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST,
44          Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER,
45          Calendar.DECEMBER
46      };
47  
48      public static boolean afterByDay(Date date1, Date date2) {
49          long millis1 = _getTimeInMillis(date1);
50          long millis2 = _getTimeInMillis(date2);
51  
52          if (millis1 > millis2) {
53              return true;
54          }
55          else {
56              return false;
57          }
58      }
59  
60      public static boolean beforeByDay(Date date1, Date date2) {
61          long millis1 = _getTimeInMillis(date1);
62          long millis2 = _getTimeInMillis(date2);
63  
64          if (millis1 < millis2) {
65              return true;
66          }
67          else {
68              return false;
69          }
70      }
71  
72      public static boolean equalsByDay(Date date1, Date date2) {
73          long millis1 = _getTimeInMillis(date1);
74          long millis2 = _getTimeInMillis(date2);
75  
76          if (millis1 == millis2) {
77              return true;
78          }
79          else {
80              return false;
81          }
82      }
83  
84      public static int getAge(Date date, TimeZone tz) {
85          return getAge(date, CalendarFactoryUtil.getCalendar(tz));
86      }
87  
88      public static int getAge(Date date, Calendar today) {
89          Calendar birthday = CalendarFactoryUtil.getCalendar();
90  
91          birthday.setTime(date);
92  
93          int yearDiff = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
94  
95          if (today.get(Calendar.MONTH) < birthday.get(Calendar.MONTH)) {
96              yearDiff--;
97          }
98          else if (today.get(Calendar.MONTH) == birthday.get(Calendar.MONTH) &&
99                   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 }