001/*
002 * Shredzone Commons - pdb
003 *
004 * Copyright (C) 2009 Richard "Shred" Körber
005 *   http://commons.shredzone.org
006 *
007 * This program is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU Library General Public License as
009 * published by the Free Software Foundation, either version 3 of the
010 * License, or (at your option) any later version.
011 *
012 * This program is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU Library General Public License
018 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
019 */
020package org.shredzone.commons.pdb;
021
022import java.util.Calendar;
023import java.util.TimeZone;
024
025/**
026 * A factory singleton for creating {@link Calendar} instances and keeping a central
027 * {@link TimeZone}.
028 * <p>
029 * The default is the system's local time zone. To change to a different time zone, invoke
030 * {@code CalendarFactory.getInstance().setTimeZone(tz)}. Instances are thread local, so
031 * different threads may have different time zone settings.
032 */
033public class CalendarFactory {
034
035    /**
036     * Epoch of PalmOS starts on January 1st, 1904.
037     */
038    public static final int EPOCH_YEAR = 1904;
039
040    private static final ThreadLocal<CalendarFactory> INSTANCES = new ThreadLocal<CalendarFactory>() {
041        @Override
042        protected CalendarFactory initialValue() {
043            return new CalendarFactory();
044        }
045    };
046
047    private TimeZone timeZone = TimeZone.getDefault();
048
049    /**
050     * Gets the singleton instance of the factory. The returned singleton is thread local
051     * and can only be used by the invoking thread. On the other hand, multiple threads
052     * can have individual time zone settings.
053     *
054     * @return {@link CalendarFactory} instance
055     */
056    public static CalendarFactory getInstance() {
057        return INSTANCES.get();
058    }
059
060    /**
061     * The {@link TimeZone} to be used. Defaults to the system's time zone.
062     */
063    public void setTimeZone(TimeZone timeZone)      { this.timeZone = timeZone; }
064    public TimeZone getTimeZone()                   { return timeZone; }
065
066    /**
067     * Creates a new {@link Calendar} instance with the current time zone.
068     *
069     * @return {@link Calendar}
070     */
071    public Calendar create() {
072        return Calendar.getInstance(timeZone);
073    }
074
075    /**
076     * Creates a new {@link Calendar} instance with the given time zone.
077     *
078     * @param tz
079     *            {@link TimeZone} to be used
080     * @return {@link Calendar}
081     */
082    public Calendar createWithTimeZone(TimeZone tz) {
083        return Calendar.getInstance(tz);
084    }
085
086    /**
087     * Creates a {@link Calendar} that is set to the PalmOS epoch.
088     *
089     * @return {@link Calendar} set to the PalmOS epoch.
090     */
091    public Calendar createPalmEpoch() {
092        Calendar cal = Calendar.getInstance(timeZone);
093        cal.clear();
094        cal.set(EPOCH_YEAR, 0, 1, 0, 0, 0);
095        return cal;
096    }
097
098}