//
// https://www.ramecera.it/myscrewdriver.html
// e-mail: screwdriver@ramecera.it
//
/* This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0 which accompanies this
 * distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html */
package it.ramecera.salad.everyday;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.jar.Attributes;
import java.util.regex.Pattern;

/**
 * <p>
 * Various utility methods. Compared to the previous version, all the
 * deprecated methods have been canceled.
 * </p>
 * <p>
 * Company: Ramecera™<br>
 * Creation date: 2020-04-09<br>
 * Last updated: 2020-04-09
 * </p>
 * <p>
 * Changes:<br>
 * </p>
 * 
 * @author M. Maglioni */
public class HandleDate {

	/* error code: 200yyxxx */

	/**
	 * <p>
	 * Constructs a date in the XML standard, with double quotation
	 * marks, starting from a numerical date written as yyyymmmmgg (as
	 * happens on the DB Guritel).
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * 08/04 08: corrected the format from # dd / MM / yyyy # to # MM /
	 * dd / yyyy #<br>
	 * </p>
	 * 
	 * @param i the number to be transformed
	 * @return the date in XML format */
	public static String dataPerXML_A(int i) {
		String year = new DecimalFormat("0000").format(i / 10000);
		String month = new DecimalFormat("00").format(i % 10000 / 100);
		String day = new DecimalFormat("00").format(i % 100);
		return "\"" + year + "-" + month + "-" + day + "\"";
	}

	/**
	 * <p>
	 * Constructs the date pattern in the form yyyy mm dd differently
	 * depending on the DBMS used.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * 08/04 08: corrected the format from # dd / MM / yyyy # to # MM /
	 * dd / yyyy #<br>
	 * </p>
	 * 
	 * @param d the date to be formatted, Date
	 * @param jd object the jdbc of the DB server
	 * @return the necessary pattern */
	public static String dataPerDBMS_A(Date d, String jd) {

		if (Pattern.matches("jdbc:db2:\\p{Graph}+", jd) | jd
				.equalsIgnoreCase("DB2"))
			return "'" + new SimpleDateFormat("yyyy-MM-dd").format(d)
					+ "'";
		else if (Pattern.matches("jdbc:odbc:\\p{Graph}+", jd) | jd
				.equalsIgnoreCase("Access"))
			return "#" + new SimpleDateFormat("MM/dd/yyyy").format(d)
					+ "#"; // style
		// English,
		// mmddyy
		else
			return new SimpleDateFormat("dd/MM/yyyy").format(d);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c the date to be formatted, Calendar object
	 * @param jd the jdbc of the DB server
	 * @return the necessary pattern */
	public static String dataPerDBMS_A(Calendar c, String jd) {

		return dataPerDBMS_A(c.getTime(), jd);
	}

	/**
	 * <p>
	 * Constructs the date and time pattern in the form yyyy MM dd hh mm
	 * ss differently according to the DBMS used.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * <p>
	 * 
	 * @param d the date to be formatted
	 * @param jd the url of the DB server
	 * @return the necessary pattern
	 * @since SVutensiliJ4_1.3.0 */
	public static String dataPerDBMS_B(Date d, String jd) {

		if (Pattern.matches("jdbc:db2:\\p{Graph}+", jd) | jd
				.equalsIgnoreCase("DB2"))
			return "'" + new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss")
					.format(d) + "'";
		else if (Pattern.matches("jdbc:odbc:\\p{Graph}+", jd) | jd
				.equalsIgnoreCase("Access"))
			return "#" + new SimpleDateFormat("MM/dd/yyyy HH.mm.ss")
					.format(d) + "#"; // English style, MMddyy
		else if (Pattern.matches("jdbc:hsqldb:\\p{Graph}+", jd))
			return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
					.format(d) + "'";
		else
			return new SimpleDateFormat("dd/MM/yyyy HH.mm.ss").format(
					d);
	}

	/**
	 * <p>
	 * Constructs the date and time pattern in the form yyyy MM dd hh mm
	 * ss differently according to the DBMS used.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * <p>
	 * 
	 * @param d the date to be formatted
	 * @param jd the url of the DB server
	 * @return the necessary pattern
	 * @since SVutensiliJ4_1.3.0 */
	public static String dataPerDBMS_B(Timestamp d, String jd) {

		if (Pattern.matches("jdbc:db2:\\p{Graph}+", jd) | jd
				.equalsIgnoreCase("DB2"))
			return "'" + new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss.SSS")
					.format(d) + "'";
		else if (Pattern.matches("jdbc:odbc:\\p{Graph}+", jd) | jd
				.equalsIgnoreCase("Access"))
			return "#" + new SimpleDateFormat("MM/dd/yyyy HH.mm.ss.SSS")
					.format(d) + "#"; // English style, MMddyy
		else if (Pattern.matches("jdbc:hsqldb:\\p{Graph}+", jd))
			return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
					.format(d) + "'";
		else
			return new SimpleDateFormat("dd/MM/yyyy HH.mm.ss.SSS")
					.format(d);
	}

	/**
	 * <p>
	 * Constructs the date and time pattern in the form yyyy MM dd hh mm
	 * ss differently according to the DBMS used. Overload of
	 * dataPerDBMS_B to make use of Calendar objects instead of Date
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p >
	 * Changes:<br>
	 * <p>
	 * 
	 * @param d the date to be formatted
	 * @param u the url of the DB server
	 * @return the necessary pattern
	 * @since SVsalad_2.0.0 */
	public static String dataPerDBMS_C(Calendar d, String u) {

		if (Pattern.matches("jdbc:db2:\\p{Graph}+", u) | u
				.equalsIgnoreCase("DB2"))
			return "'" + new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss")
					.format(d.getTime()) + "'";
		else if (Pattern.matches("jdbc:odbc:\\p{Graph}+", u))
			return "#" + new SimpleDateFormat("MM/dd/yyyy HH.mm.ss")
					.format(d.getTime()) + "#"; // English style,
											    // mmddyy
		else if (Pattern.matches("jdbc:hsqldb:\\p{Graph}+", u))
			return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
					.format(d.getTime()) + "'";
		else if (Pattern.matches("jdbc:postgresql:\\p{Graph}+", u))
			return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
					.format(d.getTime()) + "'";
		else
			return new SimpleDateFormat("dd/MM/yyyy HH.mm.ss").format(d
					.getTime());
	}

	/**
	 * <p>
	 * Constructs the date and time pattern in the form yyyy MM dd hh mm
	 * ss differently according to the DBMS used. Overload of
	 * dataPerDBMS_B to make use of Timestamp objects instead of Date
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * last modified date: 2020-04-09
	 * </p>
	 * <p >
	 * Changes:<br>
	 * <p>
	 * 
	 * @param d the date to be formatted
	 * @param u the url of the DB server
	 * @return the necessary pattern
	 * @since salad_0 */
	public static String dataPerDBMS_C(Timestamp d, String u) {

		if (Pattern.matches("jdbc:db2:\\p{Graph}+", u) | u
				.equalsIgnoreCase("DB2"))
			return "'" + new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss")
					.format(d.getTime()) + "'";
		else if (Pattern.matches("jdbc:odbc:\\p{Graph}+", u))
			return "#" + new SimpleDateFormat("MM/dd/yyyy HH.mm.ss")
					.format(d.getTime()) + "#"; // English style,
											    // mmddyy
		else if (Pattern.matches("jdbc:hsqldb:\\p{Graph}+", u))
			return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
					.format(d.getTime()) + "'";
		else
			return new SimpleDateFormat("dd/MM/yyyy HH.mm.ss").format(d
					.getTime());
	}

	/**
	 * <p>
	 * Constructs the date and time pattern in the form "yyyy MM dd hh
	 * mm ss SSS" in different ways depending on the DBMS used.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * <p>
	 * 
	 * @param d the date to be formatted
	 * @param u the url of the DB server
	 * @return the necessary pattern
	 * @since salad_0 */
	public static String dataPerDBMS_D(Timestamp d, String u) {

		if (Pattern.matches("jdbc:db2:\\p{Graph}+", u) | u
				.equalsIgnoreCase("DB2"))
			return "'" + new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss.SSS")
					.format(d.getTime()) + "'";
		else if (Pattern.matches("jdbc:odbc:\\p{Graph}+", u))
			return "#" + new SimpleDateFormat("MM/dd/yyyy HH.mm.ss")
					.format(d.getTime()) + "#"; // English style,
											    // mmddyy
		else if (Pattern.matches("jdbc:hsqldb:\\p{Graph}+", u))
			return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
					.format(d.getTime()) + "'";
		else
			return new SimpleDateFormat("dd/MM/yyyy HH.mm.ss").format(d
					.getTime());
	}

	/**
	 * <p>
	 * Constructs the date and time pattern in the form yyyy MM dd hh mm
	 * ss differently according to the DBMS used. It differs from the
	 * previous version in that the date is provided as a long.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * <p>
	 * 
	 * @param l the date to be formatted in the form of a number of
	 *        milliseconds
	 * @param u the url of the DB server
	 * @return the necessary pattern
	 * @since SVutensiliJ4_1.3.0 */
	public static String dataPerDBMS_B(long l, String u) {

		return dataPerDBMS_B(new Date(l), u);
	}

	/** attention, not accented vowels, for caution */
	public static String[] italianWeekDays = {

			"", "domenica", "lunedi", "martedi", "mercoledi", "giovedi",
			"venerdi", "sabato" };

	/** months of the year */
	public static String[] italianWeekMonths = {

			"gennaio", "febbraio", "marzo", "aprile", "maggio",
			"giugno", "luglio", "agosto", "settembre", "ottobre",
			"novembre", "dicembre" };

	/** length of months of the year, formatted 00 */
	public static String[] longTimeMonths = {

			"31", "28", "31", "30", "31", "30", "31", "31", "30", "31",
			"30", "31" };

	/**
	 * <p>
	 * Simple routine to transform a date from yyyymmdd to dd / MM /
	 * yyyy. Old name: acconciaData0.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param s string to format
	 * @return formatted date string */
	public static String acconciaData_A(String s) {

		return s.substring(6, 8) + "/" + s.substring(4, 6) + "/" + s
				.substring(0, 4);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from MM / dd / yyyy to dd / MM
	 * / yyyy. Old name: acconciaData1.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param s string to format
	 * @return formatted date string */
	public static String acconciaData_B(String s) {

		return s.substring(3, 5) + "/" + s.substring(0, 2) + "/" + s
				.substring(6, 10);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to
	 * month-extended g yyyy.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param d date to be processed
	 * @return date string in extended format */
	public static String acconciaData_C(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return c.get(Calendar.DAY_OF_MONTH) + Candies.SPACE
				+ italianWeekMonths[c.get(Calendar.MONTH)]
				+ Candies.SPACE + c.get(Calendar.YEAR);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to dd / MM /
	 * yy.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Modifications:<br>
	 * 12/06 09: fixed error on "form" sign<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_D(Calendar c) {

		return new DecimalFormat("00").format(c.get(
				Calendar.DAY_OF_MONTH)) + "/" + new DecimalFormat("00")
						.format(c.get(Calendar.MONTH) + 1) + "/"
				+ new DecimalFormat("00").format(c.get(Calendar.YEAR)
						% 100);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d date to be processed
	 * @return date string in dd / MM / yy format */
	public static String acconciaData_D(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_D(c);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param millis date to be processed, expressed in milliseconds
	 * @return date string in format dd / MM / yy */
	public static String acconciaData_D(long millis) {

		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(millis);
		return acconciaData_D(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from Calendar object to
	 * yyyy-MM-dd. Remember that the form yyyy-MM-dd is the XML standard
	 * for writing dates.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_E(Calendar c) {

		return new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ "-" + new DecimalFormat("00").format(c.get(
						Calendar.MONTH) + 1) + "-" + new DecimalFormat(
								"00").format(c.get(
										Calendar.DAY_OF_MONTH));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param millis data to be processed, expressed in milliseconds
	 * @return date string in extended format */
	public static String acconciaData_E(long millis) {

		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(millis);
		return acconciaData_E(c);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d date to be processed
	 * @return date string in yyyy-MM-dd format */
	public static String acconciaData_E(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_E(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to dd / MM /
	 * yyyy.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_F(Calendar c) {

		return new DecimalFormat("00").format(c.get(
				Calendar.DAY_OF_MONTH)) + "/" + new DecimalFormat("00")
						.format(c.get(Calendar.MONTH) + 1) + "/"
				+ new DecimalFormat("0000").format(c.get(
						Calendar.YEAR));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d data to be processed
	 * @return date string in extended format */
	public static String acconciaData_F(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_F(c);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d data to be processed
	 * @return date string in extended format */
	public static String acconciaData_F(Timestamp d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_F(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to yyyymmdd.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_G(Calendar c) {

		return new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ new DecimalFormat("00").format(c.get(Calendar.MONTH)
						+ 1) + new DecimalFormat("00").format(c.get(
								Calendar.DAY_OF_MONTH));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d data to be processed
	 * @return date string in extended format */
	public static String acconciaData_G(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_G(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to dd / MM /
	 * yyyy hh: mm: ss.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_H(Calendar c) {

		return new DecimalFormat("00").format(c.get(
				Calendar.DAY_OF_MONTH)) + "/" + new DecimalFormat("00")
						.format(c.get(Calendar.MONTH) + 1) + "/"
				+ new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ Candies.SPACE + new DecimalFormat("00").format(c.get(
						Calendar.HOUR_OF_DAY)) + ":"
				+ new DecimalFormat("00").format(c.get(Calendar.MINUTE))
				+ ":" + new DecimalFormat("00").format(c.get(
						Calendar.SECOND));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d date to be processed
	 * @return date string in format dd / MM / yy hh: mm: ss */
	public static String acconciaData_H(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_H(c);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param millis date to be processed, expressed in milliseconds
	 * @return date string in format dd / MM / yy hh: mm: ss */
	public static String acconciaData_H(long millis) {

		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(millis);
		return acconciaData_H(c);
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param timestamp date to be processed, expressed as timestamp
	 * @return date string in format dd / MM / yy hh: mm: ss */
	public static String acconciaData_H(Timestamp timestamp) {

		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(timestamp.getTime());
		return acconciaData_H(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from data-object to hh: mm:
	 * ss.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09<br>
	 * </p>
	 * <p>
	 * Changes:<br>
	 * 2020-04-09: changed the name from acconciaData_h to
	 * acconciaData_O<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_O(Calendar c) {

		return new DecimalFormat("00").format(c.get(
				Calendar.HOUR_OF_DAY)) + ":" + new DecimalFormat("00")
						.format(c.get(Calendar.MINUTE)) + ":"
				+ new DecimalFormat("00").format(c.get(
						Calendar.SECOND));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param millis data to be processed, expressed in milliseconds
	 * @return date string in format hh: mm: ss */
	public static String acconciaData_O(long millis) {

		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(millis);
		return acconciaData_O(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from yyyy-mm-dd (XML standard)
	 * to a Date object
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * last modified date: 10/21 / 10
	 * </p>
	 * 
	 * @param s string to format
	 * @return formatted date string
	 * @throws ExactException objects if the date given is incorrect */

	public static Date acconciaData_I(String s)

			throws ExactException {

		return pacco(s.substring(8, 10), s.substring(5, 7), s.substring(
				0, 4));
	}

	/**
	 * <p>
	 * Simple routine to transform a date from yyyymmdd to a Date
	 * object.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param s string to format
	 * @return formatted date string
	 * @throws ExactException object if the date provided is
	 *         incorrect */

	public static Date acconciaData_K(String s)

			throws ExactException {

		return pacco(s.substring(6, 8), s.substring(4, 6), s.substring(
				0, 4));
	}

	/**
	 * <p>
	 * Simple routine to transform a date from yyyy-mm-dd (XML standard)
	 * to an 8-digit number yyyymmdd
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param s the date in XML format
	 * @return the date as integer
	 * @throws ExactException objecting if the given date is
	 *         incorrect */

	public static int acconciaData_L(String s)

			throws ExactException {

		try {
			int giorno = Integer.valueOf(s.substring(8, 10));
			int mese = Integer.valueOf(s.substring(5, 7));
			int anno = Integer.valueOf(s.substring(0, 4));
			return anno * 10000 + mese * 100 + giorno;
		} catch (NumberFormatException nfe) {
			throw new ExactException(nfe.getMessage(), 100300,
					"HandleDate", "");
		}
	}

	/**
	 * <p>
	 * Simple routine to transform a date from data-object to
	 * yyyymmdd_hhmmss.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_J(Calendar c) {

		return new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ new DecimalFormat("00").format(c.get(Calendar.MONTH)
						+ 1) + new DecimalFormat("00").format(c.get(
								Calendar.DAY_OF_MONTH)) + "_"
				+ new DecimalFormat("00").format(c.get(
						Calendar.HOUR_OF_DAY)) + new DecimalFormat("00")
								.format(c.get(Calendar.MINUTE))
				+ new DecimalFormat("00").format(c.get(
						Calendar.SECOND));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d data to be processed
	 * @return date string in extended format */
	public static String acconciaData_J(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_J(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from dd / mm / yyyy HH.mm.ss
	 * to a Date object.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param s string to format
	 * @return formatted date string
	 * @throws ExactException object if the date provided is
	 *         incorrect */

	public static Date acconciaData_M(String s)

			throws ExactException {

		return pacco(s.substring(0, 2), s.substring(3, 5), s.substring(
				6, 10), s.substring(11, 13), s.substring(14, 16), s
						.substring(17, 19));
	}

	/**
	 * <p>
	 * Simple routine to transform a date from dd / mm / yyyy to Date
	 * object.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * 
	 * @param s string to format
	 * @return formatted date string
	 * @throws ExactException object if the date provided is
	 *         incorrect */

	public static Date acconciaData_P(String s)

			throws ExactException {

		return pacco(s.substring(0, 2), s.substring(3, 5), s.substring(
				6, 10));
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to yyyy / mm
	 * / dd hh: mm: ss.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_N(Calendar c) {

		return new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ "/" + new DecimalFormat("00").format(c.get(
						Calendar.MONTH) + 1) + "/" + new DecimalFormat(
								"00").format(c.get(
										Calendar.DAY_OF_MONTH))
				+ Candies.SPACE + new DecimalFormat("00").format(c.get(
						Calendar.HOUR_OF_DAY)) + ":"
				+ new DecimalFormat("00").format(c.get(Calendar.MINUTE))
				+ ":" + new DecimalFormat("00").format(c.get(
						Calendar.SECOND));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d date to be processed
	 * @return date string in format dd / MM / yy hh: mm: ss */
	public static String acconciaData_N(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_N(c);
	}

	/**
	 * <p>
	 * Simple routine to transform a date from date-object to yyyy / mm
	 * / dd.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c date to be processed
	 * @return date string in extended format */
	public static String acconciaData_Q(Calendar c) {

		return new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ "/" + new DecimalFormat("00").format(c.get(
						Calendar.MONTH) + 1) + "/" + new DecimalFormat(
								"00").format(c.get(
										Calendar.DAY_OF_MONTH));
	}

	/**
	 * <p>
	 * Overload of the previous one.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d data to be processed
	 * @return date string in extended format */
	public static String acconciaData_Q(Date d) {

		Calendar c = Calendar.getInstance();
		c.setTime(d);
		return acconciaData_Q(c);
	}

	/**
	 * <p>
	 * Set the hours, minutes, seconds and milliseconds to 0.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param c the date to be processed
	 * @return the purified date of hours, minutes, seconds and
	 *         milliseconds */
	public static Calendar ammazzaMinuti(Calendar c) {
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		return c;
	}

	/**
	 * <p>
	 * Routine to produce the current time in the form hh: mm: ss.
	 * </p>
	 * <p>
	 * Creation date: 22 / apr / 08<br>
	 * Last updated: 22 / apr / 08
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @return the current time */
	public static String currentTime_B() {

		TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
		Calendar c = Calendar.getInstance(tz);
		return new DecimalFormat("00").format(c.get(
				Calendar.HOUR_OF_DAY)) + ":" + new DecimalFormat("00")
						.format(c.get(Calendar.MINUTE)) + ":"
				+ new DecimalFormat("00").format(c.get(
						Calendar.SECOND));
	}

	/**
	 * <p>
	 * Formal date check. It can be customized using the format
	 * parameter.
	 * </p>
	 * <p>
	 * Creation date: 21 / Feb / 08<br>
	 * Last updated: 21 / Feb / 08
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param data obvious
	 * @param format for example: dd-MM-yyyy
	 * @return true or false */
	public static boolean eDataValida(String data, String format) {

		try {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			sdf.setLenient(false);
			sdf.parse(data);
			Date d = sdf.getCalendar().getTime();
			String s = new SimpleDateFormat(format).format(d);
			return s.equals(data);
		} catch (ParseException e) {
			return false;
		} catch (IllegalArgumentException e) {
			return false;
		}
	}

	/**
	 * <p>
	 * Formal check of a written date such as: 5 September 1980.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param data obvious
	 * @return true or false */
	public static Date eLongValidDate(String data) {
		String t = Strings.compact_A(data);
		String[] wordE = t.split(Candies.SPACE);
		if (wordE.length != 3)
			return null;
		int i = 0;
		for (; i < 12 && !wordE[1].equalsIgnoreCase(
				italianWeekMonths[i]); i++)
			;
		if (i == 12)
			return null;
		try {
			return pacco(wordE[0], Integer.valueOf(i + 1).toString(),
					wordE[2]);
		} catch (ExactException e) {
			return null;
		}
	}

	/**
	 * <p>
	 * Production of today's date in the form dd / mm / yyyy.
	 * <p>
	 * Creation date: 22 / apr / 08<br>
	 * Last updated: 22 / apr / 08
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @return la string containing today's date */
	public static String currentDate_C() {

		TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
		Calendar c = Calendar.getInstance(tz);
		return new DecimalFormat("00").format(c.get(
				Calendar.DAY_OF_MONTH)) + "/" + new DecimalFormat("00")
						.format(c.get(Calendar.MONTH) + 1) + "/"
				+ new DecimalFormat("0000").format(c.get(
						Calendar.YEAR));
	}

	/**
	 * <p>
	 * Production of today's date in the form yyyy / MM / dd.
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @return la string containing today's date
	 * @since 2.1.0, package 2.0.0 */
	public static String dataCorrente_D() {

		TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
		Calendar c = Calendar.getInstance(tz);
		return new DecimalFormat("0000").format(c.get(Calendar.YEAR))
				+ "/" + new DecimalFormat("00").format(c.get(
						Calendar.MONTH) + 1) + "/" + new DecimalFormat(
								"00").format(c.get(
										Calendar.DAY_OF_MONTH));
	}

	/**
	 * <p>
	 * Calculation of how many days there are in a month. The month must
	 * be given as a number from 1 to 12.
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes :<br>
	 * 2020-04-09: added the else to the if, otherwise it was an error
	 * <br>
	 * 2020-04-09: corrected error on the sign of "form"<br>
	 * </p>
	 * 
	 * @param mese month, as a number from 1 to 12
	 * @param anno a positive 4-digit number
	 * @return how many days; if the month is incorrect, an empty string
	 *         returns */
	public static String quantiGiorniMese(int mese, int anno) {

		String q = "";
		if (mese < 1 | mese > 12)
			return q;
		if ((anno % 4) == 0 & (anno % 400) > 0)
			longTimeMonths[1] = "29";
		else
			// 2020-04-09
			longTimeMonths[1] = "28";
		return longTimeMonths[mese - 1];
	}

	/**
	 * <p>
	 * Transformation of a date from three integers: day, month, year to
	 * a Date object. The month must be given as a number from 1 to 12.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p class = " history ">
	 * Changes:<br>
	 * </p>
	 * 
	 * @param day as a number from 1 to 28, 29, 30 or 31
	 * @param month as a number from 1 to 12
	 * @param year a 4-digit positive number
	 * @return l Date object; if the month is incorrect, return an empty
	 *         string
	 * @throws ExactException exception for incorrect date */
	public static Date pacco(int day, int month, int year)
			throws ExactException {

		if (!eDataValida(day + "-" + month + "-" + year, "d-M-yyyy")) {
			ExactException ce = new ExactException("yyyy-MM-dd=" + year
					+ "-" + month + "-" + day, 100301, "HandleDate",
					"");
			throw ce;
		}
		Calendar c = Calendar.getInstance();
		c.set(year, month - 1, day, 0, 0, 0);
		c.set(Calendar.MILLISECOND, 0);
		Date d = c.getTime();
		return d;
	}

	/**
	 * <p>
	 * Variant of the previous one using 3 strings instead of 3 numbers.
	 * Transformation of a date from three integers: day, month, year to
	 * a Date object. The month must be provided as a number from 1 to
	 * 12.<br>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p class = " history ">
	 * Changes:<br>
	 * </p>
	 * 
	 * @param dayS as string from 1 to 28, 29, 30 or 31
	 * @param monthS as string from 1 to 12
	 * @param yearS as string, 4 digits
	 * @return the Date object; if the month is incorrect, return an
	 *         empty string
	 * @throws ExactException exception for incorrect date */
	public static Date pacco(final String dayS, final String monthS,
			final String yearS)

			throws ExactException {

		int giorno = Integer.valueOf(dayS).intValue();
		int mese = Integer.valueOf(monthS).intValue();
		int anno = Integer.valueOf(yearS).intValue();
		return pacco(giorno, mese, anno);
	}

	/**
	 * <p>
	 * Variant of the previous one that returns a Calendar object
	 * instead of a Date.<br>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * last modified date: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param dayS as string from 1 to 28, 29, 30 or 31
	 * @param monthS as string from 1 to 12
	 * @param yearS as string, 4 digits
	 * @return the Date object; if the month is incorrect, return an
	 *         empty string
	 * @throws ExactException exception for incorrect date */
	public static Calendar calPacco(final String dayS,
			final String monthS, final String yearS)
			throws ExactException {

		int giorno = Integer.valueOf(dayS).intValue();
		int mese = Integer.valueOf(monthS).intValue();
		int anno = Integer.valueOf(yearS).intValue();
		Calendar c = Calendar.getInstance();
		c.setTime(pacco(giorno, mese, anno));
		c = ammazzaMinuti(c);
		return c;
	}

	/**
	 * <p>
	 * Variant of the previous one using a single string of the type d /
	 * M / yyyy or d-M-yyyy. If the date is not valid, the usual
	 * ExactException is made. For practical reasons it was necessary to
	 * move from CodeExceprion to ExactException.
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param s input string
	 * @return the object Date
	 * @throws ExactException exception for null or incorrect date */
	public static Date pacco(final String s)

			throws ExactException {

		ExactException ne = new ExactException();
		ne.datum = "date=" + s;
		if (s == null)
			throw ne;
		String t[] = s.split("-");
		String u[] = s.split("/");
		try {
			if (t.length == 3)
				return pacco(t[0], t[1], t[2]);
			else if (u.length == 3)
				return pacco(u[0], u[1], u[2]);
			else {
				throw ne;
			}
		} catch (ExactException e) {
			throw ne;
		}
	}

	/**
	 * <p>
	 * Variant of the previous one using a single string of the type
	 * yyyy-mm-dd (it is also the XML standard). If the date is not
	 * valid, the usual ExactException is made. For practical reasons it
	 * was necessary to move from ExactException to ExactException.
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param s input string
	 * @return the object Date
	 * @throws ExactException exception for null or incorrect date
	 * @since 3 */
	public static Calendar xml(final String s)

			throws ExactException {

		ExactException ne = new ExactException();
		ne.datum = "date=" + s;
		if (s == null)
			throw ne;
		String t[] = s.split("-");
		try {
			if (t.length == 3)
				return calPacco(t[2], t[1], t[0]);
			else {
				throw ne;
			}
		} catch (ExactException e) {
			throw ne;
		}
	}

	/**
	 * <p>
	 * Transformation of a date from 6 integers: day, month, year, hour,
	 * minutes, seconds to a Date object. The month must be given as a
	 * number from 1 to 12.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p class = " history ">
	 * Changes:<br>
	 * </p>
	 * 
	 * @param day as a number from 1 to 28, 29, 30 or 31
	 * @param month as a number from 1 to 12
	 * @param year a 4-digit positive number
	 * @param hours the hours of the day
	 * @param minutes the minutes of the hour
	 * @param seconds the seconds of the minute
	 * @return the Date object; if the month is incorrect, return an
	 *         empty string
	 * @throws ExactException exception for incorrect date */
	public static Date pacco(final int day, final int month,
			final int year, final int hours, final int minutes,
			final int seconds)

			throws ExactException {

		if (!eDataValida(day + "-" + month + "-" + year, "dd-MM-yyyy")
				| hours > 23 | hours < 0 | minutes > 59 | minutes < 0
				| seconds > 59 | seconds < 0) {
			ExactException ce = new ExactException(
					"gg-mm-aaaa hh:mm:ss=" + day + "-" + month + "-"
							+ year + Candies.SPACE + hours + ":"
							+ minutes + ":" + seconds, 100302,
					"HandleDate", "");
			throw ce;
		}
		Calendar c = Calendar.getInstance();
		c.set(year, month - 1, day, hours, minutes, seconds);
		c.set(Calendar.MILLISECOND, 0);
		return c.getTime();
	}

	/**
	 * <p>
	 * Variant of the previous one using 6 strings instead of 6 numbers.
	 * Transformation of a date from 6 integers: day, month, year,
	 * hours, minutes and seconds into a Date object.<br>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 21 / 11/08
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param dayS as a string from 1 to 28, 29, 30 or 31
	 * @param monthS as a string from 1 to 12
	 * @param yearS as string, 4 digits
	 * @param hoursS as string, 2 digits
	 * @param minutesS as string, 2 digits
	 * @param secondsS as string, 2 digits
	 * @return the Date object; if the month is incorrect, return an
	 *         empty string
	 * @throws ExactException exception for incorrect date */
	public static Date pacco(final String dayS, final String monthS,
			final String yearS, final String hoursS,
			final String minutesS, final String secondsS)

			throws ExactException {

		int giorno = Integer.valueOf(dayS).intValue();
		int mese = Integer.valueOf(monthS).intValue();
		int anno = Integer.valueOf(yearS).intValue();
		int ore = Integer.valueOf(hoursS).intValue();
		int minuti = Integer.valueOf(minutesS).intValue();
		int secondi = Integer.valueOf(secondsS).intValue();
		return pacco(giorno, mese, anno, ore, minuti, secondi);
	}

	/**
	 * <p>
	 * Calculation of the number of days between two dates of type
	 * Calendar, independent of the type of calendar.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param d1 The first date.
	 * @param d2 The second date.
	 * @return The number of days between the two dates. Zero is
	 *         returned if the dates are the same, one if the dates are
	 *         adjacent, etc. The order of the dates does not matter,
	 *         the value returned is always &gt;= 0. If Calendar types
	 *         of d1 and d2 are different, the result may not be
	 *         accurate. */
	public static int quantiGiorni(Calendar d1, Calendar d2) {

		if (d1.after(d2)) { // swap dates so that d1 is start and d2 is
						    // end
			Calendar swap = d1;
			d1 = d2;
			d2 = swap;
		}
		int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(
				Calendar.DAY_OF_YEAR);
		int y2 = d2.get(Calendar.YEAR);
		if (d1.get(Calendar.YEAR) != y2) {
			d1 = (Calendar) d1.clone();
			do {
				days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
				d1.add(Calendar.YEAR, 1);
			} while (d1.get(Calendar.YEAR) != y2);
		}
		return days;
	}

	/**
	 * <p>
	 * Calculation of the date contained in a manifest such as
	 * Built-Date.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param attributes the attributes of the manifest
	 * @return data as object Date
	 * @throws ExactException exception for incorrect date */
	public static Date builtDate(Attributes attributes)
			throws ExactException {

		Date data = null;
		String dataS = attributes.getValue("Built-Date");
		if (dataS.length() == 16)
			data = pacco(dataS.substring(8, 10), dataS.substring(5, 7),
					dataS.substring(0, 4), dataS.substring(11, 13),
					dataS.substring(14, 16), "0");
		else
			data = pacco(dataS.substring(8, 10), dataS.substring(5, 7),
					dataS.substring(0, 4), dataS.substring(11, 13),
					dataS.substring(14, 16), dataS.substring(17, 19));
		return data;
	}

	/**
	 * <p>
	 * Examination of a date written in a text-box. It is to be used if
	 * you want to test the date just while the operator is writing it,
	 * digit by digit. The year is always 4 digits.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param data exception for incorrect date
	 * @param dataMin minimum acceptable value for the date
	 * @param dataMax maximum acceptable value for the date
	 * @return the date, if it is valid; otherwise a null returns */
	public static Calendar dataFluida(final String data,
			Calendar dataMin, Calendar dataMax) {

		if (Pattern.matches("\\d{1,2}/\\d{1,2}/\\d{4}", data)
				&& (HandleDate.eDataValida(data, "d/M/yyyy")
						| HandleDate.eDataValida(data, "dd/M/yyyy")
						| HandleDate.eDataValida(data, "d/MM/yyyy")
						| HandleDate.eDataValida(data, "dd/MM/yyyy"))) {
			String[] parola = new String[2];
			int anno = 0, mese = 0, giorno = 0;
			parola = data.split("/");
			anno = Integer.valueOf(parola[2]);
			mese = Integer.valueOf(parola[1]);
			giorno = Integer.valueOf(parola[0]);
			Calendar c = Calendar.getInstance();
			c.set(anno, mese - 1, giorno, 0, 0, 0);
			c.set(Calendar.MILLISECOND, 0);
			if (c.compareTo(dataMin) >= 0 & c.compareTo(dataMax) <= 0)
				return c;
			else
				return null;
		} else
			return null;
	}

	/**
	 * <p>
	 * Transformation of a date + time as a string into a Calendar
	 * object. It must be of the type g / m / yyyy hh: mm: ss or g / m /
	 * yyyy hh: mm: ss, sss or g / m / yyyy hh: mm: ss.sss.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param b string date + time
	 * @return true or false
	 * @throws ExactException standard exception */
	public static Calendar formatBoxCal(final String b)

			throws ExactException {

		/* error code: 20050xxx */

		ExactException ce = new ExactException();
		ce.className = "HandleDate";
		ce.method = "formatBox";
		ce.code = 0;
		Calendar c = Calendar.getInstance();
		if (b == null || b.isEmpty()) {
			ce.code = 20050000;
			ce.datum = "The provided datum is null or empty.";
			throw ce;
		}
		String s = Strings.compact_A(b);
		String[] p = s.split("\\x20"); // the space character
		if (p.length != 2) {
			ce.datum = "The provided datum is incorrect,"
					+ " it must contain one space.";
			ce.code = 20050001;
			throw ce;
		}
		if (!eDataValida(p[0], "d/M/yyyy")) {
			ce.datum = "The provided date is uncorrect, it must be"
					+ " written according to format d/M/yyyy.";
			ce.code = 20050002;
			throw ce;
		}
		String[] q = p[0].split("\\x2f"); // the slash character
		c.set(Calendar.DAY_OF_MONTH, Integer.valueOf(q[0]).intValue());
		c.set(Calendar.MONTH, Integer.valueOf(q[1]).intValue() - 1);
		c.set(Calendar.YEAR, Integer.valueOf(q[2]).intValue());
		Integer[] y = eOraValida(p[1]);
		if (y == null) {
			ce.datum = "The provided time is incorrect, it must be "
					+ " written according to format"
					+ " hh:mm:ss or hh:mm:ss,sss.";
			ce.code = 20050003;
			throw ce;
		}
		c.set(Calendar.HOUR_OF_DAY, y[0].intValue());
		c.set(Calendar.MINUTE, y[1].intValue());
		c.set(Calendar.SECOND, y[2].intValue());
		c.set(Calendar.MILLISECOND, y[3].intValue());
		return c;
	}

	/**
	 * <p>
	 * Variant of the previous one, produces a Timestamp object instead
	 * of a Calendar object.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param b the string date + time
	 * @return the object Timestamp
	 * @throws ExactException application exception */
	public static Timestamp formatBoxTim(final String b)

			throws ExactException {

		Calendar c = formatBoxCal(b);
		long l = c.getTimeInMillis();
		return new Timestamp(l);
	}

	/**
	 * <p>
	 * Formal time control. It must be of the type hh: mm: ss or hh: mm:
	 * ss, sss or hh: mm: ss.sss. If it is not correct, the method
	 * returns a null value.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Changes:<br>
	 * </p>
	 * 
	 * @param now obvious
	 * @return true or false */
	public static Integer[] eOraValida(String now) {

		/* error code: 20051xxx */

		Integer[] x = new Integer[4];
		if (now == null || now.isEmpty()) {
			return null;
		}
		String[] r = now.split("\\x3a"); // 3a is the colon character
		if (r.length != 3) {
			return null;
		}
		r[0] = r[0].trim();
		r[1] = r[1].trim();
		r[2] = r[2].trim();
		/* I turn the point into a comma when milliseconds are
		 * expressed */
		r[2] = r[2].replaceFirst("\\x2e", ",");
		if (!r[0].matches("\\d{2}") | !r[1].matches("\\d{2}")) {
			return null;
		} else if (r[2].matches("\\d{2}")) {
			x[0] = Integer.valueOf(r[0]);
			x[1] = Integer.valueOf(r[1]);
			x[2] = Integer.valueOf(r[2]);
			x[3] = Integer.valueOf(0);
			if (x[0].intValue() > 23 | x[1].intValue() > 59 | x[2]
					.intValue() > 59) {
				return null;
			} else {
				return x;
			}
		} else if (r[2].matches("\\d{2}\\x2c\\d{3}")) {
			x[0] = Integer.valueOf(r[0]);
			x[1] = Integer.valueOf(r[1]);
			x[2] = Integer.valueOf(r[2].substring(0, 2));
			x[3] = Integer.valueOf(r[2].substring(3, 6));
			if (x[0].intValue() > 23 | x[1].intValue() > 59 | x[2]
					.intValue() > 59) {
				return null;
			} else {
				return x;
			}
		} else {
			return null;
		}
	}
}