View Javadoc
1   package fr.ifremer.quadrige3.core.dao.technical;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Core Shared
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  
27  
28  import org.apache.commons.lang3.StringUtils;
29  import org.nuiton.util.DateUtil;
30  
31  import java.sql.Timestamp;
32  import java.text.ParseException;
33  import java.text.SimpleDateFormat;
34  import java.time.LocalDate;
35  import java.time.LocalDateTime;
36  import java.time.ZonedDateTime;
37  import java.time.format.DateTimeFormatter;
38  import java.time.format.DateTimeParseException;
39  import java.util.Calendar;
40  import java.util.Date;
41  import java.util.TimeZone;
42  
43  /**
44   * <p>Dates class.</p>
45   */
46  public class Dates extends org.apache.commons.lang3.time.DateUtils{
47  	
48      /**
49       * Remove a amount of month to a date
50       *
51       * @param date a {@link java.util.Date} object.
52       * @param amount the amount to remove, in month
53       * @return a new date (= the given date - amount in month)
54       */
55      public static Date removeMonth(Date date, int amount) {
56      	Assert.notNull(date);
57      	Assert.isTrue(amount > 0);
58      	
59      	// Compute the start date
60          Calendar calendar = Calendar.getInstance();
61  		calendar.setTimeInMillis(date.getTime());
62  		calendar.set(Calendar.HOUR_OF_DAY, 0);
63  		calendar.set(Calendar.DAY_OF_MONTH, 1);
64  		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH)-amount);
65  		return calendar.getTime();
66      }
67      
68      /**
69       * Get the number of days between two dates
70       *
71       * @param startDate a {@link java.util.Date} object.
72       * @param endDate a {@link java.util.Date} object.
73       * @return a number of hours
74       */
75      public static double hoursBetween(Date startDate, Date endDate){
76      	double millis = endDate.getTime() - startDate.getTime();
77          return millis / (1000 * 60 * 60);
78      }
79      
80      /**
81       * Add to date some hours
82       *
83       * @param date a {@link java.util.Date} object.
84       * @param amount a {@link java.lang.Double} object.
85       * @return a date (= date + amount)
86       */
87      public static Date addHours(Date date, Double amount){
88      	long millis = (long) (date.getTime() + amount * (1000 * 60 * 60));
89          return new Date(millis);
90      }
91      
92  
93      /**
94       * Get the last second time of a day: 23:59:59 (0 millisecond)
95       *
96       * @param date a {@link java.util.Date} object.
97       * @return a {@link java.util.Date} object.
98       */
99      public static Date lastSecondOfTheDay(Date date) {
100         Calendar calendar = Calendar.getInstance();
101         calendar.setTime(date);
102         calendar.set(Calendar.HOUR_OF_DAY, 23);
103         calendar.set(Calendar.MINUTE, 59);
104         calendar.set(Calendar.SECOND, 59);
105         calendar.set(Calendar.MILLISECOND, 0);
106         return calendar.getTime();
107     }
108 
109     /**
110      * reset to 00h00m00s (and 0 millisecond)
111      *
112      * @param date a {@link java.util.Date} object.
113      * @return a {@link java.util.Date} object.
114      */
115     public static Date resetTime(Date date) {
116         Calendar calendar = Calendar.getInstance();
117         calendar.setTime(date);
118         return resetTime(calendar).getTime();
119     }
120 
121     /**
122      * reset to 00h00m00s (and 0 millisecond)
123      *
124      * @param calendar a {@link java.util.Calendar} object.
125      * @return a {@link java.util.Calendar} object.
126      */
127     public static Calendar resetTime(Calendar calendar) {
128         calendar.set(Calendar.HOUR_OF_DAY, 0);
129         calendar.set(Calendar.MINUTE, 0);
130         calendar.set(Calendar.SECOND, 0);
131         calendar.set(Calendar.MILLISECOND, 0);
132 
133         return calendar;
134     }
135 
136     /**
137      * reset to 0 millisecond
138      *
139      * @param date a {@link java.sql.Timestamp} object.
140      * @return a {@link java.sql.Timestamp} object.
141      */
142     public static Timestamp resetMillisecond(Timestamp date) {
143         Calendar calendar = Calendar.getInstance();
144         calendar.setTime(date);
145         calendar.set(Calendar.MILLISECOND, 0);
146 
147         return new Timestamp(calendar.getTimeInMillis());
148     }
149 
150     /**
151      * reset to 0 millisecond
152      *
153      * @param calendar a {@link java.util.Calendar} object.
154      * @return a {@link java.util.Calendar} object.
155      */
156     public static Calendar resetMillisecond(Calendar calendar) {
157         calendar.set(Calendar.MILLISECOND, 0);
158 
159         return calendar;
160     }
161 
162     /**
163      * <p>getDifferenceInDays.</p>
164      *
165      * @param startDate a {@link java.util.Date} object.
166      * @param endDate a {@link java.util.Date} object.
167      * @return a int.
168      */
169     public static int getDifferenceInDays(Date startDate, Date endDate) {
170     	return DateUtil.getDifferenceInDays(startDate, endDate);
171     }
172 
173     /**
174      * <p>formatDate.</p>
175      *
176      * @param date a {@link java.util.Date} object.
177      * @param pattern a {@link java.lang.String} object.
178      * @return a {@link java.lang.String} object.
179      */
180     public static String formatDate(Date date, String pattern) {
181         if (date == null) return null;
182         SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
183         return simpleDateFormat.format(date);
184     }
185 
186     public static String formatDate(LocalDate date, String pattern) {
187         if (date == null) return null;
188         return date.format(DateTimeFormatter.ofPattern(pattern));
189     }
190 
191     /**
192      * Convert to a date, or return null if parse error
193      *
194      * @param date a {@link java.lang.String} object.
195      * @param patterns a {@link java.lang.String} object.
196      * @return a {@link java.util.Date} object.
197      */
198     public static LocalDate safeParseLocalDate(String date, String... patterns) {
199         LocalDate result = null;
200         if (StringUtils.isNotBlank(date)) {
201             for (String pattern: patterns) {
202                 try {
203                     result = LocalDate.parse(date, DateTimeFormatter.ofPattern(pattern));
204                 } catch (DateTimeParseException ignored) {
205                 }
206             }
207         }
208         return result;
209     }
210 
211     /**
212      * Convert to a date, or return null if parse error
213      *
214      * @param date a {@link String} object.
215      * @param patterns a {@link String} object.
216      * @return a {@link Date} object.
217      */
218     public static Date safeParseDate(String date, String... patterns) {
219         Date result = null;
220         if (StringUtils.isNotBlank(date)) {
221             for (String pattern: patterns) {
222                 try {
223                     SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
224                     result = simpleDateFormat.parse(date);
225                 } catch (ParseException ignored) {
226                     // Continue: try next pattern
227                 }
228             }
229         }
230         return result;
231     }
232 
233     /**
234      * Adds a number of seconds to a date returning a new object.
235      * The original {@code Timestamp} is unchanged.
236      *
237      * @param date  the Timestamp, not null
238      * @param amount  the amount to add, may be negative
239      * @return the new {@code Timestamp} with the amount added
240      * @throws IllegalArgumentException if the date is null
241      */
242     public static Timestamp addSeconds(Timestamp date, int amount) {
243         if(date == null) {
244             throw new IllegalArgumentException("The date must not be null");
245         } else {
246             Calendar c = Calendar.getInstance();
247             c.setTime(date);
248             c.add(Calendar.SECOND, amount);
249             return new Timestamp(c.getTimeInMillis());
250         }
251     }
252 
253     public static Date convertToDate(LocalDate localDate, TimeZone timeZone) {
254         if (localDate == null) return null;
255         Assert.notNull(timeZone);
256         return Date.from(localDate.atStartOfDay(timeZone.toZoneId()).toInstant());
257     }
258 
259     public static Date convertToDate(LocalDateTime localDateTime, TimeZone timeZone) {
260         if (localDateTime == null) return null;
261         Assert.notNull(timeZone);
262         return Date.from(localDateTime.atZone(timeZone.toZoneId()).toInstant());
263     }
264 
265     public static LocalDate convertToLocalDate(Date date, TimeZone timeZone) {
266         if (date == null) return null;
267         return convertToLocalDateTime(date, timeZone).toLocalDate();
268     }
269 
270     public static LocalDateTime convertToLocalDateTime(Date date, TimeZone timeZone) {
271         if (date == null) return null;
272         return convertToZonedDateTime(date, timeZone).toLocalDateTime();
273     }
274 
275     public static ZonedDateTime convertToZonedDateTime(Date date, TimeZone timeZone) {
276         if (date == null) return null;
277         Assert.notNull(timeZone);
278         return ZonedDateTime.ofInstant(date.toInstant(), timeZone.toZoneId());
279     }
280 
281     public static boolean isBetween(LocalDate targetDate, LocalDate startDate, LocalDate endDate) {
282         return !targetDate.isBefore(startDate) && !targetDate.isAfter(endDate);
283     }
284 
285     public static boolean isSameDay(LocalDate date1, LocalDate date2) {
286         if (date1 == null && date2 == null) return true;
287         if (date1 == null || date2 == null) return false;
288         return date1.equals(date2);
289     }
290 }