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