DateUtils.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.utils.date;

  21. import java.text.ParseException;
  22. import java.text.SimpleDateFormat;
  23. import java.time.Instant;
  24. import java.time.LocalDate;
  25. import java.time.LocalDateTime;
  26. import java.time.LocalTime;
  27. import java.time.ZoneId;
  28. import java.time.ZonedDateTime;
  29. import java.time.format.DateTimeFormatter;
  30. import java.util.Calendar;
  31. import java.util.Date;
  32. import java.util.HashMap;
  33. import java.util.Map;
  34. import java.util.regex.Matcher;
  35. import java.util.regex.Pattern;

  36. import org.joda.time.DateTime;
  37. import org.joda.time.DateTimeZone;
  38. import org.openspcoop2.utils.UtilsException;

  39. /**    
  40.  * DateUtils
  41.  *
  42.  * @author Poli Andrea (poli@link.it)
  43.  * @author $Author$
  44.  * @version $Rev$, $Date$
  45.  */
  46. public class DateUtils {


  47.     public static Date convertToLeftInterval(Date date, UnitaTemporale unitaTemporale) {
  48.        
  49.         Calendar calendar = null;
  50.         try{
  51.             calendar = DateManager.getCalendar();
  52.         }catch(Exception e){
  53.             calendar = Calendar.getInstance();
  54.         }
  55.         calendar.setTime(date);
  56.         switch (unitaTemporale) {
  57.         case SECONDI:
  58.             calendar.set(Calendar.MILLISECOND, 0);
  59.             break;
  60.         case MINUTI:        
  61.             calendar.set(Calendar.SECOND, 0);
  62.             calendar.set(Calendar.MILLISECOND, 0);
  63.             break;
  64.         case ORARIO:        
  65.             calendar.set(Calendar.MINUTE, 0);
  66.             calendar.set(Calendar.SECOND, 0);
  67.             calendar.set(Calendar.MILLISECOND, 0);
  68.             break;
  69.         case GIORNALIERO:  
  70.             calendar.set(Calendar.HOUR_OF_DAY, 0);
  71.             calendar.set(Calendar.MINUTE, 0);
  72.             calendar.set(Calendar.SECOND, 0);
  73.             calendar.set(Calendar.MILLISECOND, 0);
  74.             break;
  75.         case SETTIMANALE:
  76.             while(Calendar.MONDAY!=calendar.get(Calendar.DAY_OF_WEEK)){
  77.                 calendar.add(Calendar.DAY_OF_WEEK, -1);
  78.             }
  79.             calendar.set(Calendar.HOUR_OF_DAY, 0);
  80.             calendar.set(Calendar.MINUTE, 0);
  81.             calendar.set(Calendar.SECOND, 0);
  82.             calendar.set(Calendar.MILLISECOND, 0);
  83.             break;
  84.         case MENSILE:
  85.             calendar.set(Calendar.DAY_OF_MONTH, 1);
  86.             calendar.set(Calendar.HOUR_OF_DAY, 0);
  87.             calendar.set(Calendar.MINUTE, 0);
  88.             calendar.set(Calendar.SECOND, 0);
  89.             calendar.set(Calendar.MILLISECOND, 0);
  90.         }
  91.        
  92.         return calendar.getTime();
  93.     }
  94.    
  95.     public static Date convertToRightInterval(Date date, UnitaTemporale unitaTemporale) {
  96.                
  97.         Calendar calendar = null;
  98.         try{
  99.             calendar = DateManager.getCalendar();
  100.         }catch(Exception e){
  101.             calendar = Calendar.getInstance();
  102.         }
  103.         calendar.setTime(date);
  104.         switch (unitaTemporale) {
  105.         case SECONDI:
  106.             calendar.set(Calendar.MILLISECOND, 999);
  107.             break;
  108.         case MINUTI:        
  109.             calendar.set(Calendar.SECOND, 59);
  110.             calendar.set(Calendar.MILLISECOND, 999);
  111.             break;
  112.         case ORARIO:        
  113.             calendar.set(Calendar.MINUTE, 59);
  114.             calendar.set(Calendar.SECOND, 59);
  115.             calendar.set(Calendar.MILLISECOND, 999);
  116.             break;
  117.         case GIORNALIERO:  
  118.             calendar.set(Calendar.HOUR_OF_DAY, 23);
  119.             calendar.set(Calendar.MINUTE, 59);
  120.             calendar.set(Calendar.SECOND, 59);
  121.             calendar.set(Calendar.MILLISECOND, 999);
  122.             break;
  123.         case SETTIMANALE:
  124.             while(Calendar.SUNDAY!=calendar.get(Calendar.DAY_OF_WEEK)){
  125.                 calendar.add(Calendar.DAY_OF_WEEK, 1);
  126.             }
  127.             calendar.set(Calendar.HOUR_OF_DAY, 23);
  128.             calendar.set(Calendar.MINUTE, 59);
  129.             calendar.set(Calendar.SECOND, 59);
  130.             calendar.set(Calendar.MILLISECOND, 999);
  131.             break;
  132.         case MENSILE:
  133.             calendar.set(Calendar.HOUR_OF_DAY, 23);
  134.             calendar.set(Calendar.MINUTE, 59);
  135.             calendar.set(Calendar.SECOND, 59);
  136.             calendar.set(Calendar.MILLISECOND, 999);
  137.             // prelevo ultimo giorno del mese impostato nell'attuale data
  138.             int lastDayActualMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  139.             calendar.set(Calendar.DAY_OF_MONTH, lastDayActualMonth);
  140.             break;
  141.         }
  142.        
  143.         return calendar.getTime();
  144.     }
  145.        
  146.     public static Date incrementDate(Date date, UnitaTemporale unitaTemporale, int increment) {
  147.        
  148.         if(increment==0){
  149.             return date;
  150.         }
  151.        
  152.         Calendar calendar = null;
  153.         try{
  154.             calendar = DateManager.getCalendar();
  155.         }catch(Exception e){
  156.             calendar = Calendar.getInstance();
  157.         }
  158.         calendar.setTime(date);
  159.         switch (unitaTemporale) {
  160.         case SECONDI:
  161.             calendar.add(Calendar.SECOND, increment);
  162.             break;
  163.         case MINUTI:        
  164.             calendar.add(Calendar.MINUTE, increment);
  165.             break;
  166.         case ORARIO:        
  167.             calendar.add(Calendar.HOUR_OF_DAY, increment);
  168.             break;
  169.         case GIORNALIERO:  
  170.             calendar.add(Calendar.DAY_OF_YEAR, increment);
  171.             break;
  172.         case SETTIMANALE:
  173.             calendar.add(Calendar.DAY_OF_YEAR, (increment*7));
  174.             break;
  175.         case MENSILE:
  176.             calendar.add(Calendar.MONTH, increment);
  177.             // prelevo ultimo giorno del mese impostato nell'attuale data
  178.             int lastDayActualMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  179.             calendar.set(Calendar.DAY_OF_MONTH, lastDayActualMonth);
  180.             break;
  181.         }
  182.        
  183.         return calendar.getTime();
  184.     }
  185.    
  186.     public static Date incrementDate1Millisecond(Date date){
  187.         Calendar calendar = null;
  188.         try{
  189.             calendar = DateManager.getCalendar();
  190.         }catch(Exception e){
  191.             calendar = Calendar.getInstance();
  192.         }
  193.         calendar.setTime(date);
  194.         calendar.add(Calendar.MILLISECOND, 1);
  195.         return calendar.getTime();
  196.     }
  197.    
  198.     public Date decrementDate1Millisecond(Date date){
  199.         Calendar calendar = null;
  200.         try{
  201.             calendar = DateManager.getCalendar();
  202.         }catch(Exception e){
  203.             calendar = Calendar.getInstance();
  204.         }
  205.         calendar.setTime(date);
  206.         calendar.add(Calendar.MILLISECOND, -1);
  207.         return calendar.getTime();
  208.     }
  209.    
  210.     public static Date incredementDate1MsIf999(Date date){
  211.        
  212.         // se la data รจ impostata all'ultimo millisecondo (999), viene portato al successivo
  213.        
  214.         Calendar calendar = null;
  215.         try{
  216.             calendar = DateManager.getCalendar();
  217.         }catch(Exception e){
  218.             calendar = Calendar.getInstance();
  219.         }
  220.         calendar.setTime(date);
  221.        
  222.         int ms = calendar.get(Calendar.MILLISECOND);
  223.         if(ms>=999) {
  224.             calendar.add(Calendar.MILLISECOND, 1);
  225.             return calendar.getTime();
  226.         }
  227.         else {
  228.             return date;
  229.         }
  230.        
  231.     }
  232.    
  233.     /**
  234.      * https://datatracker.ietf.org/doc/html/rfc3339#section-5.6
  235.      *
  236.      * Secondo RFC 3339 Sezione 5.6, i caratteri T e Z sono case-sensitive, e quindi devono essere rispettivamente in maiuscolo. Inoltre, l'uso dello spazio al posto del carattere T per separare la data e l'ora non รจ permesso in una rappresentazione conforme a RFC 3339.
  237.      *
  238.      * Uso di "T" e "Z" maiuscole e minuscole
  239.      * Per ABNF e ISO 8601: L'RFC chiarisce che sia l'ABNF (usato per definire la sintassi) sia la specifica ISO 8601 permettono l'uso delle lettere minuscole "t" e "z" come alternative alle maiuscole "T" e "Z".
  240.      * Comunque sia le applicazioni che generano timestamp conformi a RFC 3339 dovrebbero preferibilmente utilizzare le lettere maiuscole "T" e "Z" per garantire maggiore compatibilitร  e aderenza alle convenzioni comuni.
  241.      *
  242.      * L'ultima nota evidenzia che ISO 8601 consente di usare uno spazio al posto della "T" come separatore tra la data e l'ora, ma RFC 3339 non prevede questa opzione.
  243.      * Quindi per rispettare rigorosamente l'RFC 3339, deve essere usate la "T" (o eventualmente "t").
  244.      * Tuttavia, in altri contesti o per migliorare la leggibilitร , potrebbe essere accettabile usare uno spazio, ma ciรฒ รจ fuori dall'ambito strettamente RFC 3339.
  245.      */
  246.     private static boolean dateTimeAllowLowerCaseTZ = false;
  247.     private static boolean dateTimeAllowSpaceSeparator = false;
  248.     public static boolean isDateTimeAllowLowerCaseTZ() {
  249.         return dateTimeAllowLowerCaseTZ;
  250.     }
  251.     public static void setDateTimeAllowLowerCaseTZ(boolean dateTimeAllowLowerCaseTZ) {
  252.         DateUtils.dateTimeAllowLowerCaseTZ = dateTimeAllowLowerCaseTZ;
  253.     }
  254.     public static boolean isDateTimeAllowSpaceSeparator() {
  255.         return dateTimeAllowSpaceSeparator;
  256.     }
  257.     public static void setDateTimeAllowSpaceSeparator(boolean dateTimeAllowSpaceSeparator) {
  258.         DateUtils.dateTimeAllowSpaceSeparator = dateTimeAllowSpaceSeparator;
  259.     }
  260.     private static String buildDateTimeSeparatorPattern(boolean dateTimeAllowLowerCase, boolean dateTimeAllowSpaceSeparator) {
  261.         StringBuilder sb = new StringBuilder();
  262.         sb.append("T");
  263.         if(dateTimeAllowLowerCase) {
  264.             sb.append("t");
  265.         }
  266.         if(dateTimeAllowSpaceSeparator) {
  267.             sb.append(" ");
  268.         }
  269.         return sb.toString();
  270.     }
  271.     private static String buildTimeZonePattern(boolean dateTimeAllowLowerCase) {
  272.         StringBuilder sb = new StringBuilder();
  273.         sb.append("Z");
  274.         if(dateTimeAllowLowerCase) {
  275.             sb.append("z");
  276.         }
  277.         return sb.toString();
  278.     }
  279.    
  280.     private static final String RFC3339_56_ERROR = "' has wrong format (see RFC 3339, section 5.6): ";
  281.     private static final String UNCORRECT_FORMAT = "Uncorrect format";
  282.    
  283.     private static final String DATETIME_PATTERN_SEPARATOR = "tT ";
  284.     private static final String DATETIME_PATTERN_TIMEZONE = "zZ";
  285.     private static final String DATETIME_PATTERN = "^\\d{4}-(?:0[0-9]{1}|1[0-2]{1})-(0?[1-9]|[12][0-9]|3[01])["+DATETIME_PATTERN_SEPARATOR+"]\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(["+DATETIME_PATTERN_TIMEZONE+"]|[+-]\\d{2}:\\d{2})$";
  286.     public static void validateDateTimeAsRFC3339Sec56(String dateTime) throws UtilsException {
  287.         validateDateTimeAsRFC3339Sec56(dateTime, DateUtils.dateTimeAllowLowerCaseTZ, DateUtils.dateTimeAllowSpaceSeparator);
  288.     }
  289.     public static void validateDateTimeAsRFC3339Sec56(String dateTime, boolean allowLowerCaseTZ, boolean allowSpaceSeparator) throws UtilsException {
  290.         // RFC 3339, section 5.6
  291.         // es 2017-07-21T17:32:28Z
  292.         String fullDate = null;
  293.         String fullTime = null;
  294.         try {
  295.             // date-time = full-date "T" full-time
  296.             String separator = null;
  297.             if(!dateTime.contains("T")) {
  298.                 if(allowLowerCaseTZ && dateTime.contains("t")) {
  299.                     separator="t";
  300.                 }
  301.                 else if(allowSpaceSeparator && dateTime.contains(" ")) {
  302.                     separator=" ";
  303.                 }
  304.                 else {
  305.                     throw new UtilsException("Expected 'T' separator");
  306.                 }
  307.             }
  308.             else {
  309.                 separator="T";
  310.             }
  311.             String [] split = dateTime.split(separator);
  312.             if(split==null || split.length!=2) {
  313.                 throw new UtilsException("Expected 'full-date T full-time' format");
  314.             }
  315.            
  316.             // check regexp
  317.             String dateTimePattern = DATETIME_PATTERN.replace(DATETIME_PATTERN_SEPARATOR, buildDateTimeSeparatorPattern(allowLowerCaseTZ, allowSpaceSeparator));
  318.             dateTimePattern = dateTimePattern.replace(DATETIME_PATTERN_TIMEZONE, buildTimeZonePattern(allowLowerCaseTZ));
  319.             if(!isMatchEngine(dateTime, dateTimePattern)) {
  320.                 throw new UtilsException(UNCORRECT_FORMAT);
  321.             }
  322.            
  323.             // full-date = date-fullyear "-" date-month "-" date-mday
  324.             // date-fullyear   = 4DIGIT
  325.             // date-month      = 2DIGIT  ; 01-12
  326.             // date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on month/year
  327.             fullDate = split[0];
  328.             fullTime = split[1];
  329.         }catch(Exception e){
  330.             throw new UtilsException("Found dateTime '"+dateTime+RFC3339_56_ERROR+e.getMessage(),e);
  331.         }
  332.        
  333.         validateDateAsRFC3339Sec56(fullDate);
  334.         validateTimeAsRFC3339Sec56(fullTime);
  335.     }
  336.    
  337.     private static final String FULL_DATE_FORMAT = "yyyy-MM-dd";
  338.     private static final String DATE_PATTERN = "^\\d{4}-(?:0[0-9]{1}|1[0-2]{1})-(0?[1-9]|[12][0-9]|3[01])$";
  339.     public static void validateDateAsRFC3339Sec56(String fullDate) throws UtilsException {
  340.         // RFC 3339, section 5.6
  341.         // es 2017-07-21
  342.         try {
  343.             // full-date = date-fullyear "-" date-month "-" date-mday
  344.             // date-fullyear   = 4DIGIT
  345.             // date-month      = 2DIGIT  ; 01-12
  346.             // date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on month/year
  347.             if(fullDate==null || "".equals(fullDate)) {
  348.                 throw new UtilsException("undefined");
  349.             }
  350.             // check regexp
  351.             if(!isMatchEngine(fullDate, DATE_PATTERN)) {
  352.                 throw new UtilsException(UNCORRECT_FORMAT);
  353.             }
  354.             validateDateAsRFC3339Sec56WithSimpleDateFormat(fullDate);
  355.         }catch(Exception e){
  356.             throw new UtilsException("Found date '"+fullDate+RFC3339_56_ERROR+e.getMessage(),e);
  357.         }
  358.     }
  359.     private static void validateDateAsRFC3339Sec56WithSimpleDateFormat(String fullDate) throws UtilsException {
  360.         try {
  361.             SimpleDateFormat sdf = new SimpleDateFormat(FULL_DATE_FORMAT);
  362.             Date d = sdf.parse(fullDate);
  363.             d.toString();
  364.         }catch(Exception e) {
  365.             throw new UtilsException("uncorrect format: "+e.getMessage(),e);
  366.         }
  367.     }
  368.    
  369.     private static final String FULL_TIME_FORMAT_SECONDS = "HH:mm:ss.SSS";
  370.     private static final String FULL_TIME_FORMAT_WITHOUT_SECONDS = "HH:mm:ss";
  371.     private static final String FULL_TIME_FORMAT_OFFSET = "HH:mm";
  372.     private static final String TIME_PATTERN = "^\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(["+DATETIME_PATTERN_TIMEZONE+"]|[+-]\\d{2}:\\d{2})$";
  373.     public static void validateTimeAsRFC3339Sec56(String fullTime) throws UtilsException {
  374.         validateTimeAsRFC3339Sec56(fullTime, DateUtils.dateTimeAllowLowerCaseTZ);
  375.     }
  376.     public static void validateTimeAsRFC3339Sec56(String fullTime, boolean allowLowerCaseTZ) throws UtilsException {
  377.         // RFC 3339, section 5.6
  378.         // es 17:32:28Z
  379.         try {
  380.             // full-time = partial-time time-offset
  381.             // partial-time    = time-hour ":" time-minute ":" time-second [time-secfrac]
  382.             // time-hour       = 2DIGIT  ; 00-23
  383.             // time-minute     = 2DIGIT  ; 00-59
  384.             // time-second     = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second
  385.             // time-secfrac    = "." 1*DIGIT
  386.             // time-offset     = "Z" / time-numoffset
  387.             // time-numoffset  = ("+" / "-") time-hour ":" time-minute
  388.             if(fullTime==null || "".equals(fullTime)) {
  389.                 throw new UtilsException("undefined");
  390.             }
  391.             if(fullTime.length()<9) {
  392.                 throw new UtilsException("too short");
  393.             }
  394.             // check regexp
  395.             String timePattern = TIME_PATTERN.replace(DATETIME_PATTERN_TIMEZONE, buildTimeZonePattern(allowLowerCaseTZ));
  396.             if(!isMatchEngine(fullTime, timePattern)) {
  397.                 throw new UtilsException(UNCORRECT_FORMAT);
  398.             }
  399.             String partialTime = validateTimeAsRFC3339Sec56PartialTime(fullTime);
  400.             if(partialTime==null || "".equals(partialTime)) {
  401.                 throw new UtilsException("undefined partial time");
  402.             }
  403.             validateTimeAsRFC3339Sec56WithSimpleDateFormaPartialTime(partialTime);
  404.            
  405.         }catch(Exception e){
  406.             throw new UtilsException("Found time '"+fullTime+RFC3339_56_ERROR+e.getMessage(),e);
  407.         }
  408.     }
  409.     private static String validateTimeAsRFC3339Sec56PartialTime(String fullTime) throws UtilsException {
  410.         String partialTime = null;
  411.         if(fullTime.endsWith("Z") || fullTime.endsWith("z")) {
  412.             partialTime = fullTime.substring(0, fullTime.length()-1);
  413.         }
  414.         else {
  415.             if(!fullTime.contains("+") && !fullTime.contains("-")) {
  416.                 throw new UtilsException("expected '(\"+\" / \"-\") or \"Z\" time-offset character");
  417.             }
  418.             String offset = null;
  419.             String [] splitFullTime = null;
  420.             if(fullTime.contains("+")) {
  421.                 splitFullTime = fullTime.split("\\+");
  422.             }
  423.             else {
  424.                 splitFullTime = fullTime.split("-");
  425.             }
  426.             if(splitFullTime==null || splitFullTime.length!=2) {
  427.                 throw new UtilsException("expected partial-time time-offset");
  428.             }
  429.             partialTime = splitFullTime[0];
  430.             offset = splitFullTime[1];
  431.            
  432.             if(offset==null || "".equals(fullTime)) {
  433.                 throw new UtilsException("undefined offset time");
  434.             }
  435.             validateTimeAsRFC3339Sec56WithSimpleDateFormatOffset(offset);
  436.         }
  437.         return partialTime;
  438.     }
  439.     private static void validateTimeAsRFC3339Sec56WithSimpleDateFormatOffset(String offset) throws UtilsException {
  440.         try {
  441.             SimpleDateFormat sdf = new SimpleDateFormat(FULL_TIME_FORMAT_OFFSET);
  442.             Date d = sdf.parse(offset);
  443.             d.toString();
  444.         }catch(Exception e) {
  445.             throw new UtilsException("uncorrect offset format: "+e.getMessage(),e);
  446.         }
  447.     }
  448.     private static void validateTimeAsRFC3339Sec56WithSimpleDateFormaPartialTime(String partialTime) throws UtilsException {
  449.         try {
  450.             SimpleDateFormat sdf = null;
  451.             if(partialTime.contains(".")) {
  452.                 sdf = new SimpleDateFormat(FULL_TIME_FORMAT_SECONDS);
  453.             }
  454.             else {
  455.                 sdf = new SimpleDateFormat(FULL_TIME_FORMAT_WITHOUT_SECONDS);
  456.             }
  457.             Date d = sdf.parse(partialTime);
  458.             d.toString();
  459.         }catch(Exception e) {
  460.             throw new UtilsException("uncorrect offset format: "+e.getMessage(),e);
  461.         }
  462.     }
  463.    
  464.     private static boolean isMatchEngine(String contenuto, String pattern) throws UtilsException{
  465.        
  466.         if( (pattern == null) || (pattern.length() == 0))
  467.             throw new UtilsException("Pattern di ricerca non fornito");
  468.         if( (contenuto == null) || (contenuto.length() == 0))
  469.             throw new UtilsException("Contenuto su cui effettuare una ricerca non fornita");
  470.        
  471.         try{
  472.             Pattern p = Pattern.compile(pattern);
  473.             Matcher matcher = p.matcher(contenuto);
  474.             return matcher.matches();
  475.         }catch(Exception e){
  476.             throw new UtilsException("isMatch contenuto["+contenuto+"] pattern["+pattern+"] error: "+e.getMessage(),e);
  477.         }
  478.     }
  479.    
  480.    
  481.    
  482.    

  483.     /** FORMAT Simple Date Format */
  484.    
  485.     private static DateEngineType DEFAULT_DATA_ENGINE_TYPE = DateEngineType.JAVA_TIME;
  486.     public static DateEngineType getDEFAULT_DATA_ENGINE_TYPE() {
  487.         return DEFAULT_DATA_ENGINE_TYPE;
  488.     }
  489.     public static void setDEFAULT_DATA_ENGINE_TYPE(DateEngineType dEFAULT_DATA_ENGINE_TYPE) {
  490.         DEFAULT_DATA_ENGINE_TYPE = dEFAULT_DATA_ENGINE_TYPE;
  491.     }

  492.     public static final String SIMPLE_DATE_FORMAT_MS = "yyyy-MM-dd_HH:mm:ss.SSS";
  493.     public static SimpleDateFormat getSimpleDateFormatMs() {
  494.         return getDefaultDateTimeFormatterMs();
  495.     }
  496.     public static SimpleDateFormat getOldSimpleDateFormatMs() {
  497.         return new SimpleDateFormat (SIMPLE_DATE_FORMAT_MS); // SimpleDateFormat non e' thread-safe
  498.     }
  499.     public static DateTimeFormatter getDateTimeFormatterMs() {
  500.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_MS);
  501.     }
  502.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterMs() {
  503.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_MS);
  504.     }
  505.     public static DateTimeFormatterWrapper getDateTimeFormatterMs(DateEngineType type) {
  506.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_MS, false);
  507.     }
  508.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterMs() {
  509.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_MS, false);
  510.     }
  511.    
  512.     public static final String SIMPLE_DATE_FORMAT_MS_ISO_8601_TZ = "yyyy-MM-dd_HH:mm:ss.SSSX";
  513.     public static SimpleDateFormat getSimpleDateFormatMs_ISO_8601_TZ() {
  514.         return getDefaultDateTimeFormatterMs_ISO_8601_TZ();
  515.     }
  516.     public static SimpleDateFormat getOldSimpleDateFormatMs_ISO_8601_TZ() {
  517.         SimpleDateFormat sdf = new SimpleDateFormat (SIMPLE_DATE_FORMAT_MS_ISO_8601_TZ); // SimpleDateFormat non e' thread-safe
  518.         sdf.setCalendar(Calendar.getInstance());
  519.         return sdf;
  520.     }
  521.     public static DateTimeFormatter getDateTimeFormatterMs_ISO_8601_TZ() {
  522.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_MS_ISO_8601_TZ);
  523.     }
  524.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterMs_ISO_8601_TZ() {
  525.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_MS_ISO_8601_TZ);
  526.     }
  527.     public static DateTimeFormatterWrapper getDateTimeFormatterMs_ISO_8601_TZ(DateEngineType type) {
  528.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_MS_ISO_8601_TZ, true);
  529.     }
  530.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterMs_ISO_8601_TZ() {
  531.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_MS_ISO_8601_TZ, true);
  532.     }
  533.    
  534.     public static final String SIMPLE_DATE_FORMAT_SECOND = "yyyy-MM-dd_HH:mm:ss";
  535.     public static SimpleDateFormat getSimpleDateFormatSecond() {
  536.         return getDefaultDateTimeFormatterSecond();
  537.     }
  538.     public static SimpleDateFormat getOldSimpleDateFormatSecond() {
  539.         return new SimpleDateFormat (SIMPLE_DATE_FORMAT_SECOND); // SimpleDateFormat non e' thread-safe
  540.     }
  541.     public static DateTimeFormatter getDateTimeFormatterSecond() {
  542.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_SECOND);
  543.     }
  544.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterSecond() {
  545.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_SECOND);
  546.     }
  547.     public static DateTimeFormatterWrapper getDateTimeFormatterSecond(DateEngineType type) {
  548.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_SECOND, false);
  549.     }
  550.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterSecond() {
  551.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_SECOND, false);
  552.     }
  553.    
  554.     public static final String SIMPLE_DATE_FORMAT_SECOND_ISO_8601_TZ = "yyyy-MM-dd_HH:mm:ssX";
  555.     public static SimpleDateFormat getSimpleDateFormatSecond_ISO_8601_TZ() {
  556.         return getDefaultDateTimeFormatterSecond_ISO_8601_TZ();
  557.     }
  558.     public static SimpleDateFormat getOldSimpleDateFormatSecond_ISO_8601_TZ() {
  559.         SimpleDateFormat sdf =  new SimpleDateFormat (SIMPLE_DATE_FORMAT_SECOND_ISO_8601_TZ); // SimpleDateFormat non e' thread-safe
  560.         sdf.setCalendar(Calendar.getInstance());
  561.         return sdf;
  562.     }
  563.     public static DateTimeFormatter getDateTimeFormatterSecond_ISO_8601_TZ() {
  564.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_SECOND_ISO_8601_TZ);
  565.     }
  566.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterSecond_ISO_8601_TZ() {
  567.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_SECOND_ISO_8601_TZ);
  568.     }
  569.     public static DateTimeFormatterWrapper getDateTimeFormatterSecond_ISO_8601_TZ(DateEngineType type) {
  570.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_SECOND_ISO_8601_TZ, true);
  571.     }
  572.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterSecond_ISO_8601_TZ() {
  573.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_SECOND_ISO_8601_TZ, true);
  574.     }
  575.    
  576.     public static final String SIMPLE_DATE_FORMAT_MINUTE = "yyyy-MM-dd_HH:mm";
  577.     public static SimpleDateFormat getSimpleDateFormatMinute() {
  578.         return getDefaultDateTimeFormatterMinute();
  579.     }
  580.     public static SimpleDateFormat getOldSimpleDateFormatMinute() {
  581.         return new SimpleDateFormat (SIMPLE_DATE_FORMAT_MINUTE); // SimpleDateFormat non e' thread-safe
  582.     }
  583.     public static DateTimeFormatter getDateTimeFormatterMinute() {
  584.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_MINUTE);
  585.     }
  586.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterMinute() {
  587.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_MINUTE);
  588.     }
  589.     public static DateTimeFormatterWrapper getDateTimeFormatterMinute(DateEngineType type) {
  590.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_MINUTE, false);
  591.     }
  592.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterMinute() {
  593.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_MINUTE, false);
  594.     }
  595.    
  596.     public static final String SIMPLE_DATE_FORMAT_MINUTE_ISO_8601_TZ = "yyyy-MM-dd_HH:mmX";
  597.     public static SimpleDateFormat getSimpleDateFormatMinute_ISO_8601_TZ() {
  598.         return getDefaultDateTimeFormatterMinute_ISO_8601_TZ();
  599.     }
  600.     public static SimpleDateFormat getOldSimpleDateFormatMinute_ISO_8601_TZ() {
  601.         SimpleDateFormat sdf =  new SimpleDateFormat (SIMPLE_DATE_FORMAT_MINUTE_ISO_8601_TZ); // SimpleDateFormat non e' thread-safe
  602.         sdf.setCalendar(Calendar.getInstance());
  603.         return sdf;
  604.     }
  605.     public static DateTimeFormatter getDateTimeFormatterMinute_ISO_8601_TZ() {
  606.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_MINUTE_ISO_8601_TZ);
  607.     }
  608.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterMinute_ISO_8601_TZ() {
  609.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_MINUTE_ISO_8601_TZ);
  610.     }
  611.     public static DateTimeFormatterWrapper getDateTimeFormatterMinute_ISO_8601_TZ(DateEngineType type) {
  612.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_MINUTE_ISO_8601_TZ, true);
  613.     }
  614.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterMinute_ISO_8601_TZ() {
  615.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_MINUTE_ISO_8601_TZ, true);
  616.     }
  617.    
  618.     public static final String SIMPLE_DATE_FORMAT_HOUR = "yyyy-MM-dd_HH";
  619.     public static SimpleDateFormat getSimpleDateFormatHour() {
  620.         return getDefaultDateTimeFormatterHour();
  621.     }
  622.     public static SimpleDateFormat getOldSimpleDateFormatHour() {
  623.         return new SimpleDateFormat (SIMPLE_DATE_FORMAT_HOUR); // SimpleDateFormat non e' thread-safe
  624.     }
  625.     public static DateTimeFormatter getDateTimeFormatterHour() {
  626.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_HOUR);
  627.     }
  628.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterHour() {
  629.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_HOUR);
  630.     }
  631.     public static DateTimeFormatterWrapper getDateTimeFormatterHour(DateEngineType type) {
  632.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_HOUR, false);
  633.     }
  634.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterHour() {
  635.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_HOUR, false);
  636.     }
  637.    
  638.     public static final String SIMPLE_DATE_FORMAT_HOUR_ISO_8601_TZ = "yyyy-MM-dd_HHX";
  639.     public static SimpleDateFormat getSimpleDateFormatHour_ISO_8601_TZ() {
  640.         return getDefaultDateTimeFormatterHour_ISO_8601_TZ();
  641.     }
  642.     public static SimpleDateFormat getOldSimpleDateFormatHour_ISO_8601_TZ() {
  643.         SimpleDateFormat sdf =  new SimpleDateFormat (SIMPLE_DATE_FORMAT_HOUR_ISO_8601_TZ); // SimpleDateFormat non e' thread-safe
  644.         sdf.setCalendar(Calendar.getInstance());
  645.         return sdf;
  646.     }
  647.     public static DateTimeFormatter getDateTimeFormatterHour_ISO_8601_TZ() {
  648.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_HOUR_ISO_8601_TZ);
  649.     }
  650.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterHour_ISO_8601_TZ() {
  651.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_HOUR_ISO_8601_TZ);
  652.     }
  653.     public static DateTimeFormatterWrapper getDateTimeFormatterHour_ISO_8601_TZ(DateEngineType type) {
  654.         return new DateTimeFormatterWrapper(type.toDateTimeType(), SIMPLE_DATE_FORMAT_HOUR_ISO_8601_TZ, true);
  655.     }
  656.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterHour_ISO_8601_TZ() {
  657.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), SIMPLE_DATE_FORMAT_HOUR_ISO_8601_TZ, true);
  658.     }
  659.    
  660.     public static final String SIMPLE_DATE_FORMAT_DAY = "yyyy-MM-dd";
  661.     public static SimpleDateFormat getSimpleDateFormatDay() {
  662.         return getDefaultDateTimeFormatterDay();
  663.     }
  664.     public static SimpleDateFormat getOldSimpleDateFormatDay() {
  665.         return new SimpleDateFormat (SIMPLE_DATE_FORMAT_DAY); // SimpleDateFormat non e' thread-safe
  666.     }
  667.     public static DateTimeFormatter getDateTimeFormatterDay() {
  668.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_DAY);
  669.     }
  670.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterDay() {
  671.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_DAY);
  672.     }
  673.     public static DateTimeFormatterWrapper getDateTimeFormatterDay(DateEngineType type) {
  674.         return new DateTimeFormatterWrapper(type.toDateType(), SIMPLE_DATE_FORMAT_DAY, false);
  675.     }
  676.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterDay() {
  677.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateType(), SIMPLE_DATE_FORMAT_DAY, false);
  678.     }
  679.    
  680.     public static final String SIMPLE_DATE_FORMAT_DAY_ISO_8601_TZ = "yyyy-MM-ddX";
  681.     public static SimpleDateFormat getSimpleDateFormatDay_ISO_8601_TZ() {
  682.         return getDefaultDateTimeFormatterDay_ISO_8601_TZ();
  683.     }
  684.     public static SimpleDateFormat getOldSimpleDateFormatDay_ISO_8601_TZ() {
  685.         SimpleDateFormat sdf = new SimpleDateFormat (SIMPLE_DATE_FORMAT_DAY_ISO_8601_TZ); // SimpleDateFormat non e' thread-safe
  686.         sdf.setCalendar(Calendar.getInstance());
  687.         return sdf;
  688.     }
  689.     public static DateTimeFormatter getDateTimeFormatterDay_ISO_8601_TZ() {
  690.         return DateUtils.getDateTimeFormatter(SIMPLE_DATE_FORMAT_DAY_ISO_8601_TZ);
  691.     }
  692.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatterDay_ISO_8601_TZ() {
  693.         return DateUtils.getJodaDateTimeFormatter(SIMPLE_DATE_FORMAT_DAY_ISO_8601_TZ);
  694.     }
  695.     public static DateTimeFormatterWrapper getDateTimeFormatterDay_ISO_8601_TZ(DateEngineType type) {
  696.         return new DateTimeFormatterWrapper(type.toDateType(), SIMPLE_DATE_FORMAT_DAY_ISO_8601_TZ, true);
  697.     }
  698.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatterDay_ISO_8601_TZ() {
  699.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateType(), SIMPLE_DATE_FORMAT_DAY_ISO_8601_TZ, true);
  700.     }

  701.     public static SimpleDateFormat getSimpleDateFormat(String format) {
  702.         return getDefaultDateTimeFormatter(format);
  703.     }
  704.     public static SimpleDateFormat getOldSimpleDateFormat(String format) {
  705.         return new SimpleDateFormat (format); // SimpleDateFormat non e' thread-safe
  706.     }
  707.     public static DateTimeFormatterWrapper getDateTimeFormatter(DateEngineType type, String format) {
  708.         return new DateTimeFormatterWrapper(type.toDateTimeType(), format, false);
  709.     }
  710.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatter(String format) {
  711.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), format, false);
  712.     }
  713.     public static DateTimeFormatterWrapper getDateFormatter(DateEngineType type, String format) {
  714.         return new DateTimeFormatterWrapper(type.toDateType(), format, false);
  715.     }
  716.     public static DateTimeFormatterWrapper getDefaultDateFormatter(String format) {
  717.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateType(), format, false);
  718.     }
  719.     public static DateTimeFormatterWrapper getTimeFormatter(DateEngineType type, String format) {
  720.         return new DateTimeFormatterWrapper(type.toTimeType(), format, false);
  721.     }
  722.     public static DateTimeFormatterWrapper getDefaultTimeFormatter(String format) {
  723.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toTimeType(), format, false);
  724.     }
  725.    
  726.     public static SimpleDateFormat getSimpleDateFormat_ISO_8601_TZ(String format) {
  727.         return getDefaultDateTimeFormatter_ISO_8601_TZ(format);
  728.     }
  729.     public static SimpleDateFormat getOldSimpleDateFormat_ISO_8601_TZ(String format) {
  730.         SimpleDateFormat sdf = new SimpleDateFormat (format); // SimpleDateFormat non e' thread-safe
  731.         sdf.setCalendar(Calendar.getInstance());
  732.         return sdf;
  733.     }
  734.     public static DateTimeFormatterWrapper getDateTimeFormatter_ISO_8601_TZ(DateEngineType type, String format) {
  735.         return new DateTimeFormatterWrapper(type.toDateTimeType(), format, true);
  736.     }
  737.     public static DateTimeFormatterWrapper getDefaultDateTimeFormatter_ISO_8601_TZ(String format) {
  738.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateTimeType(), format, true);
  739.     }
  740.     public static DateTimeFormatterWrapper getDateFormatter_ISO_8601_TZ(DateEngineType type, String format) {
  741.         return new DateTimeFormatterWrapper(type.toDateType(), format, true);
  742.     }
  743.     public static DateTimeFormatterWrapper getDefaultDateFormatter_ISO_8601_TZ(String format) {
  744.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toDateType(), format, true);
  745.     }
  746.     public static DateTimeFormatterWrapper getTimeFormatter_ISO_8601_TZ(DateEngineType type, String format) {
  747.         return new DateTimeFormatterWrapper(type.toTimeType(), format, true);
  748.     }
  749.     public static DateTimeFormatterWrapper getDefaultTimeFormatter_ISO_8601_TZ(String format) {
  750.         return new DateTimeFormatterWrapper(DEFAULT_DATA_ENGINE_TYPE.toTimeType(), format, true);
  751.     }
  752.    
  753.    
  754.    
  755.    
  756.    
  757.     /** Simple Date Format che supporta tutti i formati rfc3339 */
  758.    
  759.     public static Date parseDate(String dateParam) throws ParseException {
  760.         return parseDateRFC3339_sec5_6(dateParam);
  761.     }
  762.     public static Date parseDateRFC3339_sec5_6(String dateParam) throws ParseException {
  763.         String date = dateParam;
  764.        
  765.         // https://tools.ietf.org/html/rfc3339
  766.         boolean withTimeZone = false;
  767.         if(date.length()>SIMPLE_DATE_FORMAT_SECOND.length()) {
  768.             // prendo la parte dopo l'ora, almeno non confondo il '-' del giorno con il '-' dell'offset
  769.             String check = date.substring(SIMPLE_DATE_FORMAT_SECOND.length());
  770.             withTimeZone = check.endsWith("Z") || check.contains("+") || check.contains("-");
  771.         }
  772.                        
  773.         if(date.contains("T")) {
  774.             date = date.replace("T", "_");
  775.            
  776.             if(date.contains(".")) {
  777.                 if(withTimeZone) {
  778.                     return getSimpleDateFormatMs_ISO_8601_TZ().parse(date);
  779.                 }
  780.                 else {
  781.                     return getSimpleDateFormatMs().parse(date);
  782.                 }
  783.             }
  784.             else {
  785.                 if(date.contains(":")) {
  786.                     String [] split = date.split(":");
  787.                     if(split.length>1) {
  788.                         if(withTimeZone) {
  789.                             return getSimpleDateFormatSecond_ISO_8601_TZ().parse(date);
  790.                         }
  791.                         else {
  792.                             return getSimpleDateFormatSecond().parse(date);
  793.                         }
  794.                     }
  795.                     else {
  796.                         if(withTimeZone) {
  797.                             return getSimpleDateFormatMinute_ISO_8601_TZ().parse(date);
  798.                         }
  799.                         else {
  800.                             return getSimpleDateFormatMinute().parse(date);
  801.                         }
  802.                     }
  803.                 }
  804.                 else {
  805.                     if(withTimeZone) {
  806.                         return getSimpleDateFormatHour_ISO_8601_TZ().parse(date);
  807.                     }
  808.                     else {
  809.                         return getSimpleDateFormatHour().parse(date);
  810.                     }
  811.                 }
  812.             }
  813.         }
  814.         else {
  815.             if(withTimeZone) {
  816.                 return getSimpleDateFormatDay_ISO_8601_TZ().parse(date);
  817.             }
  818.             else {
  819.                 return getSimpleDateFormatDay().parse(date);
  820.             }
  821.         }
  822.     }
  823.    
  824.    
  825.    
  826.     /** java.time Parse */
  827.    
  828.     public static LocalDateTime parseToLocalDateTime(String format, String source) {
  829.         // bug fix: Text '20200131105154584' could not be parsed at index 0
  830.         if("yyyyMMddHHmmssSSS".equals(format)) {
  831.             String sCorrect = source;
  832.             if(sCorrect.length()>4) {
  833.                 sCorrect = source.substring(0, 4) + " " + source.substring(4, source.length());
  834.                 return LocalDateTime.parse(sCorrect, DateUtils.getDateTimeFormatter("yyyy MMddHHmmssSSS"));
  835.             }
  836.         }
  837.         return LocalDateTime.parse(source, DateUtils.getDateTimeFormatter(format));
  838.     }
  839.    
  840.     public static LocalDate parseToLocalDate(String format, String source) {
  841.         return LocalDate.parse(source, DateUtils.getDateTimeFormatter(format));
  842.     }
  843.    
  844.     public static LocalTime parseToLocalTime(String format, String source) {
  845.         return LocalTime.parse(source, DateUtils.getDateTimeFormatter(format));
  846.     }
  847.    
  848.    
  849.     /** java.time DateTimeFormatter */
  850.    
  851.     private static Map<String, DateTimeFormatter> mapFormatToDateTimeFormatter = new HashMap<String, DateTimeFormatter>();
  852.     private static synchronized void initDateTimeFormatter(String format) {
  853.         if(mapFormatToDateTimeFormatter.containsKey(format)==false) {
  854.             mapFormatToDateTimeFormatter.put(format, DateTimeFormatter.ofPattern(format));
  855.         }
  856.     }
  857.     public static DateTimeFormatter getDateTimeFormatter(String format) {
  858.         if(mapFormatToDateTimeFormatter.containsKey(format)==false) {
  859.             initDateTimeFormatter(format);
  860.         }
  861.         return mapFormatToDateTimeFormatter.get(format);
  862.     }
  863.    
  864.    
  865.     /** java.time Converter */
  866.    
  867.     private static ZoneId zoneId = ZoneId.systemDefault();
  868.    
  869.     /** java.time Converter (LocalDate) */
  870.    
  871.     public static LocalDate convertToLocalDateViaInstant(Date dateToConvert) {
  872.         return convertToLocalDateViaInstant(dateToConvert, DateUtils.zoneId);
  873.     }
  874.     public static LocalDate convertToLocalDateViaInstant(Date dateToConvert, ZoneId zoneIdParam) {
  875.         return dateToConvert.toInstant()
  876.           .atZone(zoneIdParam)
  877.           .toLocalDate();
  878.     }
  879.    
  880.     public static LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) {
  881.         return convertToLocalDateViaMilisecond(dateToConvert, DateUtils.zoneId);
  882.     }
  883.     public static LocalDate convertToLocalDateViaMilisecond(Date dateToConvert, ZoneId zoneIdParam) {
  884.         return Instant.ofEpochMilli(dateToConvert.getTime())
  885.           .atZone(zoneIdParam)
  886.           .toLocalDate();
  887.     }
  888.    
  889.     public static Date convertToDateViaSqlDate(LocalDate dateToConvert) {
  890.         return java.sql.Date.valueOf(dateToConvert);
  891.     }
  892.    
  893.     public static Date convertToDateViaInstant(LocalDate dateToConvert) {
  894.         return convertToDateViaInstant(dateToConvert, DateUtils.zoneId);
  895.     }
  896.     public static Date convertToDateViaInstant(LocalDate dateToConvert, ZoneId zoneIdParam) {
  897.         return java.util.Date.from(dateToConvert.atStartOfDay()
  898.           .atZone(zoneIdParam)
  899.           .toInstant());
  900.     }
  901.    
  902.    
  903.     /** java.time Converter (LocalTime) */
  904.    
  905.     public static LocalTime convertToLocalTimeViaInstant(Date dateToConvert) {
  906.         return convertToLocalTimeViaInstant(dateToConvert, DateUtils.zoneId);
  907.     }
  908.     public static LocalTime convertToLocalTimeViaInstant(Date dateToConvert, ZoneId zoneIdParam) {
  909.         return dateToConvert.toInstant()
  910.           .atZone(zoneIdParam)
  911.           .toLocalTime();
  912.     }
  913.    
  914.     public static LocalTime convertToLocalTimeViaMilisecond(Date dateToConvert) {
  915.         return convertToLocalTimeViaMilisecond(dateToConvert, DateUtils.zoneId);
  916.     }
  917.     public static LocalTime convertToLocalTimeViaMilisecond(Date dateToConvert, ZoneId zoneIdParam) {
  918.         return Instant.ofEpochMilli(dateToConvert.getTime())
  919.           .atZone(zoneIdParam)
  920.           .toLocalTime();
  921.     }
  922.    
  923.     public static Date convertToDateViaInstant(LocalTime dateToConvert) {
  924.         return convertToDateViaInstant(dateToConvert, DateUtils.zoneId);
  925.     }
  926.     public static Date convertToDateViaInstant(LocalTime dateToConvert, ZoneId zoneIdParam) {
  927.         return java.util.Date.from(dateToConvert.atDate(LocalDate.now())
  928.           .atZone(zoneIdParam)
  929.           .toInstant());
  930.     }
  931.    
  932.    
  933.     /** java.time Converter (LocalDateTime) */
  934.    
  935.     public static ZonedDateTime convertToZonedDateTimeViaInstant(Date dateToConvert) {
  936.         return convertToZonedDateTimeViaInstant(dateToConvert, DateUtils.zoneId);
  937.     }
  938.     public static ZonedDateTime convertToZonedDateTimeViaInstant(Date dateToConvert, ZoneId zoneIdParam) {
  939.         return dateToConvert.toInstant()
  940.           .atZone(zoneIdParam);
  941.     }
  942.    
  943.     public static LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) {
  944.         return convertToLocalDateTimeViaInstant(dateToConvert, DateUtils.zoneId);
  945.     }
  946.     public static LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert, ZoneId zoneIdParam) {
  947.         return convertToZonedDateTimeViaInstant(dateToConvert, zoneIdParam)
  948.           .toLocalDateTime();
  949.     }
  950.    
  951.     public static ZonedDateTime convertToZonedDateTimeViaMilisecond(Date dateToConvert) {
  952.         return convertToZonedDateTimeViaMilisecond(dateToConvert, DateUtils.zoneId);
  953.     }
  954.     public static ZonedDateTime convertToZonedDateTimeViaMilisecond(Date dateToConvert, ZoneId zoneIdParam) {
  955.         return Instant.ofEpochMilli(dateToConvert.getTime())
  956.           .atZone(zoneIdParam);
  957.     }
  958.    
  959.     public static LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) {
  960.         return convertToLocalDateTimeViaMilisecond(dateToConvert, DateUtils.zoneId);
  961.     }
  962.     public static LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert, ZoneId zoneIdParam) {
  963.         return convertToZonedDateTimeViaMilisecond(dateToConvert, zoneIdParam)
  964.           .toLocalDateTime();
  965.     }
  966.    
  967.     public static LocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) {
  968.         return new java.sql.Timestamp(dateToConvert.getTime()).toLocalDateTime();
  969.     }

  970.     public static Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) {
  971.         return java.sql.Timestamp.valueOf(dateToConvert);
  972.     }
  973.    
  974.     public static Date convertToDateViaInstant(LocalDateTime dateToConvert) {
  975.         return convertToDateViaInstant(dateToConvert, DateUtils.zoneId);
  976.     }
  977.     public static Date convertToDateViaInstant(LocalDateTime dateToConvert, ZoneId zoneIdParam) {
  978.         return java.util.Date
  979.           .from(dateToConvert.atZone(zoneIdParam)
  980.           .toInstant());
  981.     }
  982.    
  983.     public static Date convertToDateViaInstant(ZonedDateTime dateToConvert) {
  984.         return convertToDateViaInstant(dateToConvert, DateUtils.zoneId);
  985.     }
  986.     public static Date convertToDateViaInstant(ZonedDateTime dateToConvert, ZoneId zoneIdParam) {
  987.         return java.util.Date
  988.           .from(dateToConvert
  989.           .toInstant());
  990.     }
  991.    
  992.    
  993.    
  994.    
  995.     /** joda.time Parse */
  996.    
  997.     public static org.joda.time.DateTime parseToJodaDateTime(String format, String source) {
  998.         return DateUtils.getJodaDateTimeFormatter(format).parseDateTime(source);
  999.     }
  1000.    
  1001.     public static org.joda.time.LocalDateTime parseToJodaLocalDateTime(String format, String source) {
  1002.         return parseToJodaDateTime(format, source).toLocalDateTime();
  1003.     }
  1004.    
  1005.     public static org.joda.time.LocalDate parseToJodaLocalDate(String format, String source) {
  1006.         return parseToJodaDateTime(format, source).toLocalDate();
  1007.     }
  1008.    
  1009.     public static org.joda.time.LocalTime parseToJodaLocalTime(String format, String source) {
  1010.         return parseToJodaDateTime(format, source).toLocalTime();
  1011.     }
  1012.    
  1013.    
  1014.     /** joda.time DateTimeFormatter */
  1015.    
  1016.     private static Map<String, org.joda.time.format.DateTimeFormatter> mapFormatToJodaDateTimeFormatter = new HashMap<String, org.joda.time.format.DateTimeFormatter>();
  1017.     private static String normalizeTimeZoneFormatForJoda(String formato) {
  1018.         return formato.contains("X") ? formato.replaceAll("X", "Z") : formato;
  1019.     }
  1020.     private static synchronized void initJodaDateTimeFormatter(String format) {
  1021.         if(mapFormatToJodaDateTimeFormatter.containsKey(format)==false) {
  1022.             mapFormatToJodaDateTimeFormatter.put(format, org.joda.time.format.DateTimeFormat.forPattern(normalizeTimeZoneFormatForJoda(format)));
  1023.         }
  1024.     }
  1025.     public static org.joda.time.format.DateTimeFormatter getJodaDateTimeFormatter(String format) {
  1026.         if(mapFormatToJodaDateTimeFormatter.containsKey(format)==false) {
  1027.             initJodaDateTimeFormatter(format);
  1028.         }
  1029.         return mapFormatToJodaDateTimeFormatter.get(format);
  1030.     }
  1031.    
  1032.    
  1033.    
  1034.     /** joda.time Converter */
  1035.    
  1036.     private static DateTimeZone dtz = DateTimeZone.getDefault();
  1037.    
  1038.     public static org.joda.time.LocalDate convertToJodaLocalDate(Date dateToConvert) {
  1039.         return convertToJodaLocalDate(dateToConvert, DateUtils.dtz);
  1040.     }
  1041.     public static org.joda.time.LocalDate convertToJodaLocalDate(Date dateToConvert, DateTimeZone dtzParam) {
  1042.         return new org.joda.time.LocalDate(dateToConvert.getTime(), dtzParam);
  1043.     }
  1044.    
  1045.     public static org.joda.time.LocalTime convertToJodaLocalTime(Date dateToConvert) {
  1046.         return convertToJodaLocalTime(dateToConvert, DateUtils.dtz);
  1047.     }
  1048.     public static org.joda.time.LocalTime convertToJodaLocalTime(Date dateToConvert, DateTimeZone dtzParam) {
  1049.         return new org.joda.time.LocalTime(dateToConvert.getTime(), dtzParam);
  1050.     }
  1051.    
  1052.     public static org.joda.time.LocalDateTime convertToJodaLocalDateTime(Date dateToConvert) {
  1053.         return convertToJodaLocalDateTime(dateToConvert, DateUtils.dtz);
  1054.     }
  1055.     public static org.joda.time.LocalDateTime convertToJodaLocalDateTime(Date dateToConvert, DateTimeZone dtzParam) {
  1056.         return new org.joda.time.LocalDateTime(dateToConvert.getTime(), dtzParam);
  1057.     }
  1058.    
  1059.     public static DateTime convertToJodaDateTime(Date dateToConvert) {
  1060.         return convertToJodaDateTime(dateToConvert, DateUtils.dtz);
  1061.     }
  1062.     public static DateTime convertToJodaDateTime(Date dateToConvert, DateTimeZone dtzParam) {
  1063.         return new DateTime(dateToConvert.getTime(), dtzParam);
  1064.     }
  1065.    
  1066.     public static Date convertToDate(org.joda.time.LocalDate dateToConvert) {
  1067.         return dateToConvert.toDate();
  1068.     }
  1069.     public static Date convertToDate(org.joda.time.LocalTime dateToConvert) {
  1070.         return dateToConvert.toDateTimeToday().toDate();
  1071.     }
  1072.     public static Date convertToDate(org.joda.time.LocalDateTime dateToConvert) {
  1073.         return dateToConvert.toDate();
  1074.     }
  1075.     public static Date convertToDate(org.joda.time.DateTime dateToConvert) {
  1076.         return dateToConvert.toDate();
  1077.     }
  1078.    
  1079. }