001/*
002 * #%L
003 * Netarchivesuite - common
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023package dk.netarkivet.common.utils.archive;
024
025import java.text.DateFormat;
026import java.text.SimpleDateFormat;
027import java.util.TimeZone;
028
029/**
030 * Utility class for dispensing ARC/WARC <code>DateFormat</code> objects. Each object is thread safe as long as it it
031 * only used by the same thread. This means no caching of this object for later use unless its by the same thread.
032 * <code>ThreadLocal</code> handles automatic instantiation and cleanup of objects.
033 *
034 * @author nicl
035 */
036public class ArchiveDateConverter {
037
038    /** ARC date format string as speficied in the ARC documentation. */
039    public static final String ARC_DATE_FORMAT = "yyyyMMddHHmmss";
040
041    /** WARC date format string as specified by the WARC ISO standard. */
042    public static final String WARC_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
043
044    /** ARC <code>DateFormat</code> as specified in the ARC documentation. */
045    private final DateFormat arcDateFormat;
046
047    /** WARC <code>DateFormat</code> as speficied in the WARC ISO standard. */
048    private final DateFormat warcDateFormat;
049
050    /**
051     * Creates a new <code>DateParser</code>.
052     */
053    private ArchiveDateConverter() {
054        arcDateFormat = new SimpleDateFormat(ARC_DATE_FORMAT);
055        arcDateFormat.setLenient(false);
056        arcDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
057        warcDateFormat = new SimpleDateFormat(WARC_DATE_FORMAT);
058        warcDateFormat.setLenient(false);
059        warcDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
060    }
061
062    /**
063     * <code>DateFormat</code> is not thread safe, so we wrap its construction inside a <code>ThreadLocal</code> object.
064     */
065    private static final ThreadLocal<ArchiveDateConverter> DateParserTL = new ThreadLocal<ArchiveDateConverter>() {
066        @Override
067        public ArchiveDateConverter initialValue() {
068            return new ArchiveDateConverter();
069        }
070    };
071
072    /**
073     * Returns a <code>DateFormat</code> object for ARC date conversion.
074     *
075     * @return a <code>DateFormat</code> object for ARC date conversion
076     */
077    public static DateFormat getArcDateFormat() {
078        return DateParserTL.get().arcDateFormat;
079    }
080
081    /**
082     * Returns a <code>DateFormat</code> object for WARC date conversion.
083     *
084     * @return a <code>DateFormat</code> object for WARC date conversion
085     */
086    public static DateFormat getWarcDateFormat() {
087        return DateParserTL.get().warcDateFormat;
088    }
089
090}