package ext.javax.xml.bind;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import javax.xml.bind.DatatypeConverter;

/**
 * <p>
 * Classe utilitaire fournissant des convertisseurs JAXB/JAXWS à destination du
 * type java.util.Date.
 * </p>
 * 
 * <p>
 * Ce type n'est pas le mapping par défaut des types XML xs:date, xs:time,
 * xs:dateTime (et xs:g qui n'est pas pris en charge par cette classe). Pour les
 * utiliser il faut mettre en place dans un fichier binding JAXB les
 * déclarations suivantes:
 * </p>
 * 
 * <pre>
 * &lt;globalBindings&gt;
 *     &lt;javaType name="java.util.Date" xmlType="xs:date"
 *         parseMethod="ext.javax.xml.bind.DateJaxbConverter.parseDate"
 *         printMethod="ext.javax.xml.bind.DateJaxbConverter.printDate" /&gt;
 *     &lt;javaType name="java.util.Date" xmlType="xs:dateTime"
 *         parseMethod="ext.javax.xml.bind.DateJaxbConverter.parseDateTime"
 *         printMethod="ext.javax.xml.bind.DateJaxbConverter.printDateTime" /&gt;
 *     &lt;javaType name="java.util.Date" xmlType="xs:time"
 *         parseMethod="ext.javax.xml.bind.DateJaxbConverter.parseTime"
 *         printMethod="ext.javax.xml.bind.DateJaxbConverter.printTime" /&gt;
 * &lt;/globalBindings&gt;
 * </pre>
 */
public final class DateJaxbConverter {

    /**
     * Zone horaire à utiliser pour produire les représentations XML en sortie.
     * Par défaut c'est la timezone par défaut de la JVM au moment où la classe
     * est chargée.
     */
    private static TimeZone xmlTz = TimeZone.getDefault();

    /**
     * Standard setter.
     * 
     * @param serverTz
     *            the serverTz to set. See the corresponding field for more
     *            documentation.
     */
    public static void setXmlTz(TimeZone serverTz) {
	DateJaxbConverter.xmlTz = serverTz;
    }

    /**
     * Extrait un objet Date Java d'une représentation XML de date seule.
     * 
     * @param repr
     *            La représentation caractère à analyser.
     * @return L'objet Date résolu.
     */
    public static Date parseDate(String repr) {
	Date ret = DatatypeConverter.parseDate(repr).getTime();
	return ret;
    }

    /**
     * Extrait un objet Date Java d'une représentation XML de date+heure.
     * 
     * @param repr
     *            La représentation caractère à analyser.
     * @return L'objet Date résolu.
     */
    public static Date parseDateTime(String repr) {
	Date ret = DatatypeConverter.parseDateTime(repr).getTime();
	return ret;
    }

    /**
     * Extrait un objet Date Java d'une représentation XML d'heure seule.
     * 
     * @param repr
     *            La représentation caractère à analyser.
     * @return L'objet Date résolu.
     */
    public static Date parseTime(String repr) {
	Date ret = DatatypeConverter.parseTime(repr).getTime();
	return ret;
    }

    /**
     * Produit la représentation XML pour la partie date de la valeur fournie.
     * 
     * @param d
     *            La date à imprimer, au format Java.
     * @return La représentation produite, en fonction de la timezone en cours.
     */
    public static String printDate(Date d) {
	Calendar cal = Calendar.getInstance(xmlTz);
	cal.setTime(d);
	// cal.set(Calendar.HOUR_OF_DAY, 0);
	// cal.set(Calendar.MINUTE, 0);
	// cal.set(Calendar.SECOND, 0);
	// cal.set(Calendar.MILLISECOND, 0);
	String ret = DatatypeConverter.printDate(cal);
	return ret;
    }

    /**
     * Produit la représentation XML pour la partie date+heure de la valeur
     * fournie.
     * 
     * @param d
     *            La date à imprimer, au format Java.
     * @return La représentation produite, en fonction de la timezone en cours.
     */
    public static String printDateTime(Date d) {
	Calendar cal = Calendar.getInstance(xmlTz);
	cal.setTime(d);
	String ret = DatatypeConverter.printDateTime(cal);
	return ret;
    }

    /**
     * Produit la représentation XML pour la partie heure de la valeur fournie.
     * 
     * @param d
     *            La date à imprimer, au format Java.
     * @return La représentation produite, en fonction de la timezone en cours.
     */
    public static String printTime(Date d) {
	Calendar cal = Calendar.getInstance(xmlTz);
	cal.setTime(d);
	String ret = DatatypeConverter.printTime(cal);
	return ret;
    }

}
