1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.Format;
28  
29  import java.util.Calendar;
30  import java.util.Date;
31  import java.util.Locale;
32  import java.util.Map;
33  import java.util.TimeZone;
34  import java.util.concurrent.ConcurrentHashMap;
35  
36  /**
37   * <a href="CalendarUtil.java.html"><b><i>View Source</i></b></a>
38   *
39   * @author Brian Wing Shun Chan
40   */
41  public class CalendarUtil {
42  
43      public static String[] DAYS_ABBREVIATION = new String[] {
44          "sunday-abbreviation", "monday-abbreviation", "tuesday-abbreviation",
45          "wednesday-abbreviation", "thursday-abbreviation","friday-abbreviation",
46          "saturday-abbreviation"
47      };
48  
49      public static int[] MONTH_IDS = new int[] {
50          Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL,
51          Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST,
52          Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER,
53          Calendar.DECEMBER
54      };
55  
56      public static boolean afterByDay(Date date1, Date date2) {
57          long millis1 = _getTimeInMillis(date1);
58          long millis2 = _getTimeInMillis(date2);
59  
60          if (millis1 > millis2) {
61              return true;
62          }
63          else {
64              return false;
65          }
66      }
67  
68      public static boolean beforeByDay(Date date1, Date date2) {
69          long millis1 = _getTimeInMillis(date1);
70          long millis2 = _getTimeInMillis(date2);
71  
72          if (millis1 < millis2) {
73              return true;
74          }
75          else {
76              return false;
77          }
78      }
79  
80      public static boolean equalsByDay(Date date1, Date date2) {
81          long millis1 = _getTimeInMillis(date1);
82          long millis2 = _getTimeInMillis(date2);
83  
84          if (millis1 == millis2) {
85              return true;
86          }
87          else {
88              return false;
89          }
90      }
91  
92      public static int getAge(Date date, TimeZone tz) {
93          return getAge(date, CalendarFactoryUtil.getCalendar(tz));
94      }
95  
96      public static int getAge(Date date, Calendar today) {
97          Calendar birthday = CalendarFactoryUtil.getCalendar();
98  
99          birthday.setTime(date);
100 
101         int yearDiff = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
102 
103         if (today.get(Calendar.MONTH) < birthday.get(Calendar.MONTH)) {
104             yearDiff--;
105         }
106         else if (today.get(Calendar.MONTH) == birthday.get(Calendar.MONTH) &&
107                  today.get(Calendar.DATE) < birthday.get(Calendar.DATE)) {
108 
109             yearDiff--;
110         }
111 
112         return yearDiff;
113     }
114 
115     public static String[] getDays(Locale locale) {
116         return getDays(locale, null);
117     }
118 
119     public static String[] getDays(Locale locale, String pattern) {
120         if (Validator.isNull(pattern)) {
121             pattern = "EEEE";
122         }
123 
124         StringBuilder sb = new StringBuilder();
125 
126         sb.append("days_");
127         sb.append(pattern);
128         sb.append("_");
129         sb.append(locale.getLanguage());
130         sb.append("_");
131         sb.append(locale.getCountry());
132 
133         String key = sb.toString();
134 
135         String[] days = _calendarPool.get(key);
136 
137         if (days == null) {
138             days = new String[7];
139 
140             Format dayFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
141                 pattern, locale);
142 
143             Calendar cal = CalendarFactoryUtil.getCalendar();
144 
145             cal.set(Calendar.DATE, 1);
146 
147             for (int i = 0; i < 7; i++) {
148                 cal.set(Calendar.DAY_OF_WEEK, i + 1);
149 
150                 days[i] = dayFormat.format(cal.getTime());
151             }
152 
153             _calendarPool.put(key, days);
154         }
155 
156         return days;
157     }
158 
159     public static int getDaysInMonth(Calendar cal) {
160         return getDaysInMonth(cal.get(Calendar.MONTH), cal.get(Calendar.YEAR));
161     }
162 
163     public static int getDaysInMonth(int month, int year) {
164         month++;
165 
166         if ((month == 1) || (month == 3) || (month == 5) || (month == 7) ||
167             (month == 8) || (month == 10) || (month == 12)) {
168 
169             return 31;
170         }
171         else if ((month == 4) || (month == 6) || (month == 9) ||
172                  (month == 11)) {
173 
174             return 30;
175         }
176         else {
177             if (((year % 4) == 0) &&
178                 ((year % 100) != 0) || ((year % 400) == 0)) {
179 
180                 return 29;
181             }
182             else {
183                 return 28;
184             }
185         }
186     }
187 
188     public static int getGregorianDay(Calendar cal) {
189         int year = cal.get(Calendar.YEAR) - 1600;
190 
191         int month = cal.get(Calendar.MONTH) + 1;
192 
193         if (month < 3) {
194             month += 12;
195         }
196 
197         int day = cal.get(Calendar.DATE);
198 
199         int gregorianDay =
200             (int)(6286 + (year * 365.25) - (year / 100) + (year / 400) +
201                 (30.6 * month) + 0.2 + day);
202 
203         return gregorianDay;
204     }
205 
206     public static Date getGTDate(Calendar cal) {
207         Calendar gtCal = (Calendar)cal.clone();
208 
209         gtCal.set(Calendar.HOUR_OF_DAY, 0);
210         gtCal.set(Calendar.MINUTE, 0);
211         gtCal.set(Calendar.SECOND, 0);
212         gtCal.set(Calendar.MILLISECOND, 0);
213 
214         return gtCal.getTime();
215     }
216 
217     public static int getLastDayOfWeek(Calendar cal) {
218         int firstDayOfWeek = cal.getFirstDayOfWeek();
219 
220         if (firstDayOfWeek == Calendar.SUNDAY) {
221             return Calendar.SATURDAY;
222         }
223         else if (firstDayOfWeek == Calendar.MONDAY) {
224             return Calendar.SUNDAY;
225         }
226         else if (firstDayOfWeek == Calendar.TUESDAY) {
227             return Calendar.MONDAY;
228         }
229         else if (firstDayOfWeek == Calendar.WEDNESDAY) {
230             return Calendar.TUESDAY;
231         }
232         else if (firstDayOfWeek == Calendar.THURSDAY) {
233             return Calendar.WEDNESDAY;
234         }
235         else if (firstDayOfWeek == Calendar.FRIDAY) {
236             return Calendar.THURSDAY;
237         }
238 
239         return Calendar.FRIDAY;
240     }
241 
242     public static Date getLTDate(Calendar cal) {
243         Calendar ltCal = (Calendar)cal.clone();
244 
245         ltCal.set(Calendar.HOUR_OF_DAY, 23);
246         ltCal.set(Calendar.MINUTE, 59);
247         ltCal.set(Calendar.SECOND, 59);
248         ltCal.set(Calendar.MILLISECOND, 999);
249 
250         return ltCal.getTime();
251     }
252 
253     public static int[] getMonthIds() {
254         return MONTH_IDS;
255     }
256 
257     public static String[] getMonths(Locale locale) {
258         return getMonths(locale, null);
259     }
260 
261     public static String[] getMonths(Locale locale, String pattern) {
262         if (Validator.isNull(pattern)) {
263             pattern = "MMMM";
264         }
265 
266         StringBuilder sb = new StringBuilder();
267 
268         sb.append("months_");
269         sb.append(pattern);
270         sb.append("_");
271         sb.append(locale.getLanguage());
272         sb.append("_");
273         sb.append(locale.getCountry());
274 
275         String key = sb.toString();
276 
277         String[] months = _calendarPool.get(key);
278 
279         if (months == null) {
280             months = new String[12];
281 
282             Format monthFormat = FastDateFormatFactoryUtil.getSimpleDateFormat(
283                 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 long _getTimeInMillis(Date date) {
466         Calendar cal = CalendarFactoryUtil.getCalendar();
467 
468         cal.setTime(date);
469 
470         int year = cal.get(Calendar.YEAR);
471         int month = cal.get(Calendar.MONTH);
472         int day = cal.get(Calendar.DATE);
473         int hour = 0;
474         int minute = 0;
475         int second = 0;
476 
477         cal.set(year, month, day, hour, minute, second);
478 
479         long millis = cal.getTimeInMillis() / Time.DAY;
480 
481         return millis;
482     }
483 
484     private static Map<String, String[]> _calendarPool =
485         new ConcurrentHashMap<String, String[]>();
486 
487 }