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