View Javadoc
1   package fr.paris.lutece.plugins.statistics.tools;
2   
3   import java.text.ParseException;
4   import java.text.SimpleDateFormat;
5   import java.util.Calendar;
6   import java.util.Date;
7   import java.util.HashMap;
8   import java.util.Map;
9   
10  public class DateHelper {
11  
12  	private static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
13  	private static final long MONTH_IN_MILLIS = DAY_IN_MILLIS * 31;
14  
15  	public static final String YYYYMMDD = "yyyyMMdd";
16  	public static final String DDMMYYYY_SLASH = "dd/MM/yyyy";
17  	public static final String DDMM_SLASH = "dd/MM";
18  	public static final String YYYYMMDD_DASH = "yyyy-MM-dd";
19  	public static final String DDMMYYYY_DASH = "dd-MM-yyyy";
20  	public static final String YYYYMMDDHHMMSS_DASH = "yyyy-MM-ddHHmmss";
21  	public static final String YYYYMMDDTHHMMSS_DASH_COLONS = "yyyy-MM-dd'T'HH:mm:ss";
22  	public static final String YYYYMMDDHHMMSS_DASH_COLONS = "yyyy-MM-dd HH:mm:ss";
23  	public static final String YYYYMMDDHHMM_DASH_COLONS = "yyyy-MM-dd HH:mm";
24  	public static final String YYYYMMDDHHMMSS_SLASH_COLONS = "yyyy/MM/dd HH:mm:ss";
25  	public static final String YYYYDDMMHHMMSS_COLONS = "yyyyddMM HH:mm:ss";
26  	public static final String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
27  	public static final String HHHMM = "HH'h'mm";
28  	public static final String HHHMMMNSSS = "HH'h'mm'mn'ss's'";
29  	public static final String DDMMYYYYHHMM_SLASH = "dd/MM/yyyy HH:mm";
30  	public static final String DDMMYYYYHHMM_SLASH_BIS = "dd/MM/yyyy '   ' HH:mm";
31  	public static final String DDMMHHMM_SLASH = "dd/MM HH:mm";
32  	public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
33  	public static final String DDMMYYYYHHMMSSSSS = "ddMMyyyyHHmmssSSS";
34  	public static final String MMDDYYYYHHMMSS_SLASH_COLONS = "MM/dd/yyyy HH:mm:ss";
35  	public static final String MMDDYYYY_SLASH = "MM/dd/yyyy";
36  	public static final String YYYYMMDDHHMMSS_POINT_COLONS = "yyyy.MM.dd HH:mm:ss";
37  	public static final String YYYYMMDDHHMMSSSSS_DASH_COLONS = "yyyy-MM-dd HH:mm:ss.SSS";
38  	public static final String YYYYMMDDTHHMMSS_DASH_COLONS_Z = "yyyy-MM-dd'T'HH:mm:ss'Z'";
39  	// JSON Format
40  	public static final String YYYYMMDDHHMMSSZ_DASH = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
41  
42  	private static final FormattersThreadCache FMT_CACHE = new FormattersThreadCache();
43  
44  	static class FormattersThreadCache extends ThreadLocal<Map<String, SimpleDateFormat>> {
45  		@Override
46  		protected Map<String, SimpleDateFormat> initialValue() {
47  			return new HashMap<String, SimpleDateFormat>();
48  		}
49  
50  		public SimpleDateFormat get(final String pattern) {
51  			final Map<String, SimpleDateFormat> map = get();
52  			SimpleDateFormat sdf = map.get(pattern);
53  			if (sdf == null) {
54  				sdf = new SimpleDateFormat(pattern);
55  				map.put(pattern, sdf);
56  			}
57  			return sdf;
58  		}
59  	};
60  
61  	/**
62  	 * Create a Date object according to the given format and date.
63  	 * 
64  	 * @param pattern
65  	 *            A String that match the given date format
66  	 * @param strDate
67  	 *            The date to parse
68  	 * @return a Date object that represent the given date
69  	 */
70  	public static Date parse(final String pattern, final String strDate) {
71  		try {
72  			if (pattern != null && strDate != null) {
73  				return FMT_CACHE.get(pattern).parse(strDate);
74  			} else {
75  				return null;
76  			}
77  		} catch (final ParseException e) {
78  			return null;
79  		}
80  	}
81  
82  	/**
83  	 * 
84  	 * @param pattern
85  	 *            A String that represent the output date format
86  	 * @param date
87  	 *            The date that will be formated
88  	 * @return A String version of the Date according to the given format
89  	 */
90  	public static String format(final String pattern, final Date date) {
91  		String strDate = "";
92  		if (date != null) {
93  			strDate = FMT_CACHE.get(pattern).format(date);
94  		}
95  		return strDate;
96  	}
97  
98  	/**
99  	 * Get an independently initialized copy of the SimpleDateFormat according to
100 	 * the given pattern
101 	 * 
102 	 * @param pattern
103 	 *            Pattern of the returned SimpleDateFormat
104 	 * @return a SimpleDateFormat
105 	 */
106 	public static SimpleDateFormat getFormat(final String pattern) {
107 		return FMT_CACHE.get(pattern);
108 	}
109 
110 	/**
111 	 * Compute a date X day far from a reference date
112 	 * 
113 	 * @param date
114 	 *            reference date
115 	 * @param xDay
116 	 *            number of day to add (or decrease if negative)
117 	 * @return the computed date
118 	 */
119 	public static Date getDateXDayAfter(final Date date, final int xDay) {
120 
121 		final Calendar cal = Calendar.getInstance();
122 		cal.setTime(date);
123 		cal.add(Calendar.DATE, xDay);
124 		return cal.getTime();
125 	}
126 
127 	/**
128 	 * Compute a date X month far from a reference date
129 	 * 
130 	 * @param date
131 	 *            reference date
132 	 * @param xMonth
133 	 *            number of month to add (or decrease if negative)
134 	 * @return the computed date
135 	 */
136 	public static Date getDateXMonthAfter(final Date date, final int xMonth) {
137 
138 		final Calendar cal = Calendar.getInstance();
139 		cal.setTime(date);
140 		cal.add(Calendar.MONTH, xMonth);
141 		return cal.getTime();
142 	}
143 
144 	private static final int TIME_STAMP_REFERENCE_YEAR = 1970;
145 	private static final int MONTHS_IN_YEAR = 12;
146 	private static final int DAYS_IN_HALF_MONTH = 15;
147 
148 	/**
149 	 * Get the number of months between two dates
150 	 * 
151 	 * @param date1
152 	 * @param date2
153 	 * @return diffrence in months bettween two dates
154 	 */
155 	public static int nbOfMonthsBetweenTwoDates(final Date date1, final Date date2) {
156 		final Date date = new Date(Math.abs(date2.getTime() - date1.getTime()));
157 		final Calendar gcal = Calendar.getInstance();
158 		gcal.setTime(date);
159 
160 		final int years = gcal.get(Calendar.YEAR);
161 		int months = gcal.get(Calendar.MONTH);
162 
163 		months = months + (years - TIME_STAMP_REFERENCE_YEAR) * MONTHS_IN_YEAR;
164 		final int days = gcal.get(Calendar.DAY_OF_MONTH);
165 		if (days >= DAYS_IN_HALF_MONTH) {
166 			months++;
167 		}
168 		return months;
169 	}
170 
171 	/**
172 	 * Get the number of months between two dates without the absolute value
173 	 * 
174 	 * @param date1
175 	 * @param date2
176 	 * @return diffrence in months bettween two dates
177 	 */
178 	public static int nbOfMonthsBetweenTwoDatesNotAbs(final Date date1, final Date date2) {
179 		long diff = date2.getTime() - date1.getTime();
180 
181 		long months = diff / MONTH_IN_MILLIS;
182 
183 		return (int) months;
184 	}
185 
186 	/**
187 	 * Set the date with the year, month and day, if the day is greater than the max
188 	 * day for the month, the date will be the first of next month
189 	 * 
190 	 * @param year
191 	 * @param month
192 	 *            Attention: month begins by 0, that is, 0 for January, ..., 11 for
193 	 *            December
194 	 * @param day
195 	 * @return
196 	 */
197 	public static Date getDate(final int year, final int month, final int day) {
198 		final Calendar calendar = Calendar.getInstance();
199 		// set the first of the month
200 		calendar.set(year, month, 1);
201 
202 		// get the max day of the month
203 		final int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
204 
205 		if (day > maxDay) {
206 			// pass to the next month
207 			calendar.add(Calendar.MONTH, 1);
208 		} else {
209 			calendar.set(Calendar.DAY_OF_MONTH, day);
210 		}
211 		return calendar.getTime();
212 	}
213 
214 	/**
215 	 * Methode to know if the given dates is in the same day
216 	 * 
217 	 * @param date1
218 	 *            date to check
219 	 * @param date2
220 	 *            date to check
221 	 * @return true if the given date is today
222 	 */
223 	public static boolean isSameDay(final Date date1, final Date date2) {
224 		final Calendar cal1 = Calendar.getInstance();
225 		cal1.setTime(date1);
226 
227 		final Calendar cal2 = Calendar.getInstance();
228 		cal2.setTime(date2);
229 
230 		return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
231 				&& cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
232 	}
233 
234 	/**
235 	 * Methode to know if the given date is after today
236 	 * 
237 	 * @param date
238 	 *            date to check
239 	 * @return true if the given date is after today
240 	 */
241 	public static boolean isDayAfterToday(final Date date) {
242 		final Calendar today = Calendar.getInstance();
243 		today.setTime(new Date());
244 
245 		final Calendar cal = Calendar.getInstance();
246 		cal.setTime(date);
247 
248 		return (cal.get(Calendar.ERA) > today.get(Calendar.ERA) || cal.get(Calendar.YEAR) > today.get(Calendar.YEAR)
249 				|| cal.get(Calendar.DAY_OF_YEAR) > today.get(Calendar.DAY_OF_YEAR));
250 	}
251 
252 }