/*

 * Created on 20-may-2004

 *

 * To change the template for this generated file go to

 * Window - Preferences - Java - Code Generation - Code and Comments

 */

package q02b.exe.arquitectura.utils;



import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;



import q02b.exe.arquitectura.utils.tablasBD.Q02bSysdate;





/**

 * Esta clase permite centralizar el parseo/formateo de fechas.

 * <br>

 * Contiene métodos para parsear (parseDate) y formatear fechas (formatDate). Estos métodos reciben un String con

 * el formato de la fecha (ver javadoc de la clase java.text.SimpleDateFormat). En el caso de que no se pase el

 * formato, se intentará formatear/parsear con una serie de formatos por defecto.<br>

 *  

 * Estos formatos por defecto se pueden

 * establecer llamando al método initialize, pasando un objeto Configurable con propiedades de tipo:

 * <ul>

 * <li>dateFormat.1=dd/MM/yyyy</li>

 * <li>dateFormat.2=yyyy/MM/dd</li>

 * <li>dateFormat.3=dd/MM/yyyy 24hh:mm:ss</li>

 * </ul>

 * <br>

 * En el caso de intentar realizar un formateo sin pasar el formato como parámetro, el formato a utilizar será el

 * primero de la lista de formatos por defecto.

 * <br>

 * En el caso de intentar realizar un parseo sin pasar el formato como parámetro, se intentará realizar el parseo

 * con todos los formatos, del primero al último, hasta que uno de ellos no falle al parsear.

 * <br>

 * En el caso de intentar un formateo/parseo sin pasar el formato, si no se ha inicializado la clase con un Configurable,

 * los formatos por defecto serán los siguientes:

 * <ul>

 * <li>yyyy-MM-dd</li>

 * <li>dd-MM-yyyy</li>

 * <li>yyyy-MM-dd hh24:mm:ss</li>

 * <li>dd-MM-yyyy hh24:mm:ss</li>

 * <li>yyyy-MM-dd hh24:mm:ss.SSS</li>

 * <li>dd-MM-yyyy hh24:mm:ss.SSS</li>

 * <li>yyyy/MM/dd</li>

 * <li>dd/MM/yyyy</li>

 * <li>yyyy/MM/dd hh24:mm:ss.SSS</li>

 * <li>dd/MM/yyyy hh24:mm:ss.SSS</li>

 * <li>yyyy/MM/dd hh24:mm:ss</li>

 * <li>dd/MM/yyyy hh24:mm:ss</li>

 * </ul>

 *  

 * <br>

 * Otra opción es parsear/formatear las fechas mediante los métodos parseDateByConfigKey y formatDateByConfigKey. 

 * Estos métodos formatean/parsean fechas basándose en los formatos recibidos en la configuración. En vez de pasar

 * un formato cada vez que se quiera parsear/formatear, se pasa una clave, que corresponderá con un formato en la

 * configuración

 * @author sergio.navarro

 */

public abstract class Q02bDateFormatter {

    public static final String SYSDATE="SYSDATE";

        

    

    /** Array de formatos por defecto que se usarán para formatear las fechas */

    private static String[] DEFAULT_FORMATS = null;

    

    /** Prefijo de las propiedades a buscar en el objeto configurable*/

    public static final String PROPERTY_PREFIX = "dateFormat.";

    

    

    

    /**

     * Carga los formatos por defecto por defecto

     */

    private static final void loadDefaultConfig(){

        DEFAULT_FORMATS = new String[]{

                "yyyy-MM-dd hh24:mm:ss.SSS",

                "dd-MM-yyyy hh24:mm:ss.SSS",

                "yyyy-MM-dd hh24:mm:ss",

                "dd-MM-yyyy hh24:mm:ss",

                "yyyy-MM-dd HH:mm:ss.SSS",

                "dd-MM-yyyy HH:mm:ss.SSS",

                "yyyy-MM-dd HH:mm:ss",

                "dd-MM-yyyy HH:mm:ss",

                "yyyy-MM-dd hh:mm:ss.SSS",

                "dd-MM-yyyy hh:mm:ss.SSS",

                "yyyy-MM-dd hh:mm:ss",

                "dd-MM-yyyy hh:mm:ss",

                "yyyy/MM/dd hh24:mm:ss.SSS",

    		    "dd/MM/yyyy hh24:mm:ss.SSS",

    		    "yyyy/MM/dd hh24:mm:ss",

    		    "dd/MM/yyyy hh24:mm:ss",

    		    "yyyy/MM/dd HH:mm:ss.SSS",

    		    "dd/MM/yyyy HH:mm:ss.SSS",

    		    "yyyy/MM/dd HH:mm:ss",

    		    "dd/MM/yyyy HH:mm:ss",

                "yyyy/MM/dd hh:mm:ss.SSS",

    		    "dd/MM/yyyy hh:mm:ss.SSS",

    		    "yyyy/MM/dd hh:mm:ss",

    		    "dd/MM/yyyy hh:mm:ss",

                "yyyy/MM/dd",

    		    "dd/MM/yyyy",

				"yyyy-MM-dd",

                "dd-MM-yyyy"

    		    

        };

        

        

    }

    



    /**

     * Parsea una fecha en formato String y devuelve un objeto Date para el formato recibido. Si el parámetro

     * date tiene el valor de la constante SYSDATE, se devolverá la hora del sistema.

     * @param date Fecha a formatear

     * @param format Formato

     * @return FEcha formateada

     * @throws ParseException Si se produce algún error

     */

    public static final Date parseDate(String date,String format) throws ParseException {

    	

    	

        if(DEFAULT_FORMATS==null){

            loadDefaultConfig();

        }

        

        if(SYSDATE.equalsIgnoreCase(date)){

            return new Q02bSysdate();

        }

        

        if(format==null){

            for (int i = 0; i < DEFAULT_FORMATS.length; i++) {

                try{

                	

                	Date fecha=new SimpleDateFormat(DEFAULT_FORMATS[i]).parse(date);

                    return fecha;

                    

                }catch(ParseException ex){

                	

                }

            }

            

            throw new ParseException("Error parseando la fecha "+date,0);

        }

        

        return new SimpleDateFormat(format).parse(date);

    }

    

   

    

    /**

     * Parsea una fecha en formato String y devuelve un objeto Date. Si el parámetro

     * date tiene el valor de la constante SYSDATE, se devolverá la hora del sistema

     * @param date Fecha a parsear

     * @return Objeto Date

     * @throws ParseException Si se produce algún error.

     */

    public static final Date parseDate(String date) throws ParseException {

        return parseDate(date,null);

    }

    

   

    /**

     * Formatea una fecha con un formato determinado

     * @param date Fecha a formatear

     * @param format Formato a aplicar

     * @return Fecha formateada

     */

    public static final String formatDate(Date date,String format){

        if(DEFAULT_FORMATS==null){

            loadDefaultConfig();

        }

        

        if(format==null){ format = DEFAULT_FORMATS[0];}

        

        return new SimpleDateFormat(format).format(date);

        

        

    }

    

    /**

     * Formatea una fecha con el formato por defecto

     * @param date Fecha a formatear

     * @return Fecha formateada

     */

    public static final String formatDate(Date date){

        return formatDate(date);

    }

/*

    public static void main(String[] args){

        Properties p = new Properties();

        

        p.setProperty("dateFormat.1","yyyy-MM-dd");

        p.setProperty("dateFormat.2","dd-MM-yyyy");

        p.setProperty("dateFormat.3","yyyy-MM-dd hh:mm:ss");

        p.setProperty("dateFormat.4","dd-MM-yyyy hh:mm:ss");

        

        

        Configurable conf = new ConfiguracionFicheroProperties(p);

        

        //DateFormatter.initialize(conf);

        

        long ahora = System.currentTimeMillis();

        

        for(int i=0;i<1000;i++){

            DateFormatter.formatDate(new Date(),"yyyy-MM-dd") ;

        }

        

        ahora = System.currentTimeMillis() - ahora;

        

        

        //

        

        DateFormatter.initialize(conf);

        

        ahora = System.currentTimeMillis();

        

        

        

        for(int i=0;i<1000;i++){

            DateFormatter.formatDate(new Date(),"yyyy-MM-dd") ;

        }

        

        ahora = System.currentTimeMillis() - ahora;

        

        

        //

        

        ahora = System.currentTimeMillis();

        

        for(int i=0;i<1000;i++){

            new SimpleDateFormat("yyyy-MM-dd").format(new Date()) ;

        }

        

        ahora = System.currentTimeMillis() - ahora;

        

        

        //

        

        ahora = System.currentTimeMillis();

        

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        for(int i=0;i<1000;i++){

            sdf.format(new Date()) ;

        }

        

        ahora = System.currentTimeMillis() - ahora;

        

    }

*/

}

