View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.stock.utils;
35  
36  import java.sql.Timestamp;
37  import java.text.DateFormat;
38  import java.text.ParseException;
39  import java.text.SimpleDateFormat;
40  import java.util.Calendar;
41  import java.util.Date;
42  import java.util.GregorianCalendar;
43  import java.util.List;
44  import java.util.Locale;
45  
46  import org.apache.commons.lang3.StringUtils;
47  
48  /**
49   * Classe utilitaire pour la manipulation des dates
50   * 
51   */
52  public final class DateUtils
53  {
54      // index pour les triples champs de recherche par date (entre le -date 0- et le -date 1- ou le -date 2-)
55      public static final int DATE_CRITERE_ENTRE_LE = 0;
56      public static final int DATE_CRITERE_ET_LE = 1;
57      public static final int DATE_CRITERE_OU_LE = 2;
58      public static final String XML_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
59      public static final String DATE_FR = "dd/MM/yyyy";
60      public static final String HOUR_FR = "HH:mm";
61      private static SimpleDateFormat _sdfAnnee;
62  
63      /**
64       * Constructeur vide
65       */
66      private DateUtils( )
67      {
68          // rien
69      }
70  
71      /**
72       * Transfome une date en format string de type dd/MM/yyyy en objet Timestamp
73       * 
74       * @param strDate
75       *            Date à transformer
76       * @param isStartOfDayHour
77       *            TRUE si l'heure doit etre 00h01 FALSE si l'heure doit etre 23H59
78       * @return objet Timestamp correspondant à la date donnée en paramètre
79       */
80      public static Timestamp getDate( String strDate, boolean isStartOfDayHour )
81      {
82          if ( ( strDate == null ) )
83          {
84              return null;
85          }
86  
87          DateFormat dateFormat = new SimpleDateFormat( DATE_FR );
88          dateFormat.setLenient( false );
89  
90          Date date;
91  
92          try
93          {
94              date = dateFormat.parse( strDate.trim( ) );
95          }
96          catch( ParseException e )
97          {
98              return null;
99          }
100 
101         Calendar caldate = new GregorianCalendar( );
102         caldate.setTime( date );
103         caldate.set( Calendar.MILLISECOND, 0 );
104         caldate.set( Calendar.SECOND, 0 );
105 
106         if ( isStartOfDayHour )
107         {
108             caldate.set( Calendar.HOUR_OF_DAY, caldate.getActualMinimum( Calendar.HOUR_OF_DAY ) );
109             caldate.set( Calendar.MINUTE, caldate.getActualMinimum( Calendar.MINUTE ) );
110         }
111         else
112         {
113             caldate.set( Calendar.HOUR_OF_DAY, caldate.getActualMaximum( Calendar.HOUR_OF_DAY ) );
114             caldate.set( Calendar.MINUTE, caldate.getActualMaximum( Calendar.MINUTE ) );
115             caldate.set( Calendar.SECOND, caldate.getActualMaximum( Calendar.SECOND ) );
116         }
117 
118         Timestamp timeStamp = new Timestamp( caldate.getTimeInMillis( ) );
119 
120         return timeStamp;
121     }
122 
123     /**
124      * Renvoie la date sous le format défini par strPattern
125      * 
126      * @param date
127      *            la date
128      * @param strPattern
129      *            le format souhaite de la date
130      * @return la date sous forme EEEE dd MMMM yyyy
131      */
132     public static String getDate( Timestamp date, String strPattern )
133     {
134         SimpleDateFormat dateFormat = new SimpleDateFormat( strPattern, Locale.FRENCH );
135         String strDate = dateFormat.format( date );
136 
137         return strDate;
138     }
139 
140     /**
141      * Renvoie la date sous le format défini par strPattern
142      * 
143      * @param date
144      *            la date
145      * @param strPattern
146      *            le format souhaite de la date
147      * @return la date sous forme EEEE dd MMMM yyyy
148      */
149     public static String getDate( Date date, String strPattern )
150     {
151         SimpleDateFormat dateFormat = new SimpleDateFormat( strPattern, Locale.FRENCH );
152         String strDate = dateFormat.format( date );
153 
154         return strDate;
155     }
156 
157     /**
158      * Return string for date dd/MM/yyyy
159      * 
160      * @param date
161      *            the date
162      * @return date dd/MM/yyyy
163      */
164     public static String getDateFr( Date date )
165     {
166         return new SimpleDateFormat( DATE_FR ).format( date );
167     }
168 
169     /**
170      * Return string for date HH:mm
171      * 
172      * @param date
173      *            the date
174      * @return date HH:mm
175      */
176     public static String getHourFr( Date date )
177     {
178         return new SimpleDateFormat( HOUR_FR ).format( date );
179     }
180 
181     /**
182      * Retourne la date du jour
183      * 
184      * @return la date du jour
185      */
186     public static Timestamp getCurrentDate( )
187     {
188         return new Timestamp( GregorianCalendar.getInstance( ).getTimeInMillis( ) );
189     }
190 
191     /**
192      * renvoie la date courante
193      * 
194      * @param strPattern
195      *            Le format de la date courante
196      * @return la date courante
197      */
198     public static String getCurrentDateString( String strPattern )
199     {
200         SimpleDateFormat dateFormat = new SimpleDateFormat( strPattern, Locale.FRENCH );
201 
202         return dateFormat.format( new Timestamp( System.currentTimeMillis( ) ) );
203     }
204 
205     /**
206      * renvoie la date courante.
207      * 
208      * @return la date courante
209      */
210     public static String getCurrentDateString( )
211     {
212         return new SimpleDateFormat( DATE_FR ).format( new Timestamp( System.currentTimeMillis( ) ) );
213     }
214 
215     /**
216      * Renvoie un timestamp dont l'heure doit etre 00h01 FALSE si l'heure doit etre 23H59
217      * 
218      * @param date
219      *            Date à transformer
220      * @param isStartOfDayHour
221      *            true si l'heure doit etre 00h01 FALSE si l'heure doit etre 23H59
222      * @return objet Timestamp correspondant à la date donnée en paramètre
223      */
224     public static Timestamp getDate( Timestamp date, boolean isStartOfDayHour )
225     {
226         Calendar caldate = new GregorianCalendar( );
227         caldate.setTime( date );
228         caldate.set( Calendar.MILLISECOND, 0 );
229         caldate.set( Calendar.SECOND, 0 );
230 
231         if ( isStartOfDayHour )
232         {
233             caldate.set( Calendar.HOUR_OF_DAY, caldate.getActualMinimum( Calendar.HOUR_OF_DAY ) );
234             caldate.set( Calendar.MINUTE, caldate.getActualMinimum( Calendar.MINUTE ) );
235         }
236         else
237         {
238             caldate.set( Calendar.HOUR_OF_DAY, caldate.getActualMaximum( Calendar.HOUR_OF_DAY ) );
239             caldate.set( Calendar.MINUTE, caldate.getActualMaximum( Calendar.MINUTE ) );
240             caldate.set( Calendar.SECOND, caldate.getActualMaximum( Calendar.SECOND ) );
241         }
242 
243         Timestamp timeStamp = new Timestamp( caldate.getTimeInMillis( ) );
244 
245         return timeStamp;
246     }
247 
248     /**
249      * Retourne l'année en cours
250      * 
251      * @return l'année en cours
252      */
253     public static int getAnneeEnCours( )
254     {
255         Calendar caldate = new GregorianCalendar( );
256         caldate.setTime( new Date( ) );
257         return caldate.get( Calendar.YEAR );
258     }
259 
260     /**
261      * Convertis une date depuis le format dd/MM/yyyy vers le format dd-MM-yyyy.
262      * 
263      * @param dateAnglaise
264      *            date au format dd/MM/yyyy
265      * @return date au format dd-MM-yyyy
266      * @throws ParseException
267      *             lancé si la date en entrée n'est pas valide.
268      */
269     public static String converteDateAnglais( String dateAnglaise ) throws ParseException
270     {
271         SimpleDateFormat sdf = new SimpleDateFormat( "dd-MM-yyyy" );
272         SimpleDateFormat sdf2 = new SimpleDateFormat( "dd/MM/yyyy" );
273         return sdf.format( sdf2.parse( dateAnglaise ) );
274     }
275 
276     /**
277      * Vérifie que l'heure est bien au format HH:mm.
278      * 
279      * @param sHeure
280      *            string heure
281      * @return true, if successful
282      */
283     public static boolean verifierHeure( String sHeure )
284     {
285         if ( StringUtils.isNotEmpty( sHeure ) )
286         {
287             String [ ] sHeureSplit = sHeure.split( ":" );
288             if ( sHeureSplit.length == 2 )
289             {
290                 try
291                 {
292                     int heures = Integer.parseInt( sHeureSplit [0] );
293                     int minutes = Integer.parseInt( sHeureSplit [1] );
294                     if ( heures >= 0 && heures < 24 && minutes >= 0 && minutes < 60 )
295                     {
296                         return true;
297                     }
298                 }
299                 catch( NumberFormatException e )
300                 {
301                     return false;
302                 }
303             }
304         }
305         return false;
306     }
307 
308     /**
309      * Retourne l'année d'une date
310      * 
311      * @param date
312      *            date
313      * @return année
314      */
315     public static synchronized String getAnnee( Date date )
316     {
317         if ( _sdfAnnee == null )
318         {
319             _sdfAnnee = new SimpleDateFormat( "yyyy" );
320         }
321         return _sdfAnnee.format( date );
322     }
323 
324     /**
325      * Validate a date
326      * 
327      * @param date
328      *            la date
329      * @return boolean return true if the field is formated with dd/mm/yyyy
330      */
331     public static boolean validateDate( String date )
332     {
333         SimpleDateFormat sdf = new SimpleDateFormat( "dd/MM/yyyy" );
334         boolean hasError = true;
335 
336         if ( !date.equals( "" ) )
337         {
338             try
339             {
340                 sdf.setLenient( false );
341                 Date parse = sdf.parse( date );
342                 Calendar c = Calendar.getInstance( );
343                 c.setLenient( false );
344                 c.setTime( parse );
345                 c.getTime( );
346             }
347             catch( Exception ex )
348             {
349                 hasError = false;
350             }
351         }
352 
353         return hasError;
354     }
355 
356     /**
357      * vérifie un trigramme de dates entre le ... et le ... ou le.
358      * 
359      * @param dateEffetRecherche
360      *            the date effet recherche
361      * @param obligatoire
362      *            si obligatoire est à true la méthode vérifiera aussi si au moins une valeur est saisie.
363      * @return true si les dates sont valides (et éventuellement qu'une date est saisie).
364      */
365     public static boolean valideDateEntreLeEtLeOuLe( List<String> dateEffetRecherche, boolean obligatoire )
366     {
367         boolean ret = true;
368 
369         if ( dateEffetRecherche != null )
370         {
371             int size = dateEffetRecherche.size( );
372             boolean dateEffetValide = true;
373             boolean donneesPresentes = false;
374             if ( size > 0 )
375             {
376                 String dateTmp = dateEffetRecherche.get( 0 );
377                 if ( StringUtils.isNotEmpty( dateTmp ) )
378                 {
379                     donneesPresentes = true;
380                     dateEffetValide = DateUtils.validateDate( dateTmp );
381                 }
382 
383             }
384 
385             if ( size > 1 && dateEffetValide )
386             {
387                 String dateTmp = dateEffetRecherche.get( 1 );
388                 if ( StringUtils.isNotEmpty( dateTmp ) )
389                 {
390                     donneesPresentes = true;
391                     dateEffetValide = DateUtils.validateDate( dateTmp );
392                 }
393             }
394 
395             if ( size > 2 && dateEffetValide )
396             {
397                 String dateTmp = dateEffetRecherche.get( 2 );
398                 if ( StringUtils.isNotEmpty( dateTmp ) )
399                 {
400                     donneesPresentes = true;
401                     dateEffetValide = DateUtils.validateDate( dateTmp );
402                 }
403 
404             }
405 
406             ret = dateEffetValide && ( !obligatoire || ( obligatoire && donneesPresentes ) );
407         }
408         else
409             if ( obligatoire )
410             {
411                 ret = false;
412             }
413         return ret;
414     }
415 
416     /**
417      * Transfome une date en format string de type HH:mm en objet Timestamp
418      * 
419      * @param strHour
420      *            Date à transformer
421      * @return objet Timestamp correspondant à la date donnée en paramètre
422      */
423     public static Timestamp getHour( String strHour )
424     {
425         if ( ( strHour == null ) )
426         {
427             return null;
428         }
429 
430         DateFormat dateFormat = new SimpleDateFormat( HOUR_FR );
431         dateFormat.setLenient( false );
432 
433         Date date;
434 
435         try
436         {
437             date = dateFormat.parse( strHour.trim( ) );
438         }
439         catch( ParseException e )
440         {
441             return null;
442         }
443 
444         Calendar caldate = new GregorianCalendar( );
445         caldate.setTime( date );
446         caldate.set( Calendar.MILLISECOND, 0 );
447         caldate.set( Calendar.SECOND, 0 );
448 
449         Timestamp timeStamp = new Timestamp( caldate.getTimeInMillis( ) );
450 
451         return timeStamp;
452     }
453 
454     /**
455      * Set the given date hour with the given hour.
456      * 
457      * @param date
458      *            date
459      * @param hour
460      *            hour to set to the date
461      * @return the date
462      */
463     public static Date mergeDateHour( Date date, Date hour )
464     {
465         Calendar calDate = new GregorianCalendar( );
466         calDate.setTime( date );
467 
468         Calendar calHour = new GregorianCalendar( );
469         calHour.setTime( hour );
470 
471         calDate.set( Calendar.HOUR_OF_DAY, calHour.get( Calendar.HOUR_OF_DAY ) );
472         calDate.set( Calendar.MINUTE, calHour.get( Calendar.MINUTE ) );
473 
474         return calDate.getTime( );
475     }
476 
477     /**
478      * Get a timestamp with hour setted and date 01/01/1970.
479      * 
480      * @param hour
481      *            hour to set to the date
482      * @return the hour without date
483      */
484     public static Date getHourWithoutDate( Date hour )
485     {
486         Calendar calDate = new GregorianCalendar( );
487         calDate.setTime( new Date( 0 ) );
488 
489         Calendar calHour = new GregorianCalendar( );
490         calHour.setTime( hour );
491 
492         calDate.set( Calendar.HOUR_OF_DAY, calHour.get( Calendar.HOUR_OF_DAY ) );
493         calDate.set( Calendar.MINUTE, calHour.get( Calendar.MINUTE ) );
494 
495         return calDate.getTime( );
496     }
497 
498     /**
499      * return a timestamp Object which correspond with the string specified in parameter.
500      * 
501      * @param date
502      *            the date who must convert
503      * @return a timestamp Object which correspond with the string specified in parameter.
504      */
505     public static Timestamp getDateLastMinute( Date date )
506     {
507         if ( date == null )
508         {
509             return null;
510         }
511 
512         Calendar caldate = new GregorianCalendar( );
513         caldate.setTime( date );
514         caldate.set( Calendar.MILLISECOND, 0 );
515         caldate.set( Calendar.SECOND, 0 );
516         caldate.set( Calendar.HOUR_OF_DAY, caldate.getActualMaximum( Calendar.HOUR_OF_DAY ) );
517         caldate.set( Calendar.MINUTE, caldate.getActualMaximum( Calendar.MINUTE ) );
518 
519         Timestamp timeStamp = new Timestamp( caldate.getTimeInMillis( ) );
520 
521         return timeStamp;
522     }
523 
524     /**
525      * return a timestamp Object which correspond with the string specified in parameter.
526      * 
527      * @param date
528      *            the date who must convert
529      * @return a timestamp Object which correspond with the string specified in parameter.
530      */
531     public static Timestamp getDateFirstMinute( Date date )
532     {
533         if ( date == null )
534         {
535             return null;
536         }
537 
538         Calendar caldate = new GregorianCalendar( );
539         caldate.setTime( date );
540         caldate.set( Calendar.MILLISECOND, 0 );
541         caldate.set( Calendar.SECOND, 0 );
542         caldate.set( Calendar.HOUR_OF_DAY, caldate.getActualMinimum( Calendar.HOUR_OF_DAY ) );
543         caldate.set( Calendar.MINUTE, caldate.getActualMinimum( Calendar.MINUTE ) );
544 
545         Timestamp timeStamp = new Timestamp( caldate.getTimeInMillis( ) );
546 
547         return timeStamp;
548     }
549 }