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