001package com.hfg.units;
002
003
004import java.util.Calendar;
005import java.util.Collection;
006import java.util.HashMap;
007import java.util.List;
008import java.util.Map;
009
010import com.hfg.util.StringUtil;
011
012//------------------------------------------------------------------------------
013/**
014 Enumeration of standard time units.
015 <div>
016  @author J. Alex Taylor, hairyfatguy.com
017 </div>
018 */
019//------------------------------------------------------------------------------
020// com.hfg XML/HTML Coding Library
021//
022// This library is free software; you can redistribute it and/or
023// modify it under the terms of the GNU Lesser General Public
024// License as published by the Free Software Foundation; either
025// version 2.1 of the License, or (at your option) any later version.
026//
027// This library is distributed in the hope that it will be useful,
028// but WITHOUT ANY WARRANTY; without even the implied warranty of
029// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
030// Lesser General Public License for more details.
031//
032// You should have received a copy of the GNU Lesser General Public
033// License along with this library; if not, write to the Free Software
034// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
035//
036// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
037// jataylor@hairyfatguy.com
038//------------------------------------------------------------------------------
039
040public class TimeUnit extends Unit
041{
042   //**************************************************************************
043   // PRIVATE FIELDS
044   //**************************************************************************
045
046   private int    mCalendarNum;
047   private long   mMilliseconds;
048
049   private static final Map<String, TimeUnit> sUniqueMap = new HashMap<>(8);
050   private static final Map<String, TimeUnit> sLookupMap = new HashMap<>(25);
051
052   //**************************************************************************
053   // PUBLIC FIELDS
054   //**************************************************************************
055   // The base SI unit of time is the second
056   public static final TimeUnit second      = new TimeUnit(MeasurementSystem.SI,      "second",    "s", Calendar.SECOND).addAlternateName("sec").setPlural("seconds");
057   public static final TimeUnit millisecond = new TimeUnit(MeasurementSystem.SI, "millisecond",   "ms", Calendar.MILLISECOND,  new BaseSIUnitConverter(.001)).setPlural("milliseconds");
058   public static final TimeUnit minute      = new TimeUnit(MeasurementSystem.SI,      "minute",  "min", Calendar.MINUTE,       new BaseSIUnitConverter(60)).setPlural("minutes");
059   public static final TimeUnit hour        = new TimeUnit(MeasurementSystem.SI,        "hour",   "hr", Calendar.HOUR_OF_DAY,  new BaseSIUnitConverter(60 * 60)).setPlural("hours").setPluralAbbrev("hrs");
060   public static final TimeUnit day         = new TimeUnit(MeasurementSystem.SI,         "day",  "day", Calendar.DAY_OF_MONTH, new BaseSIUnitConverter(24 * 60 * 60)).setPlural("days").setPluralAbbrev("days");
061   public static final TimeUnit week        = new TimeUnit(MeasurementSystem.SI,        "week",   "wk", Calendar.WEEK_OF_YEAR, new BaseSIUnitConverter(7 * 24 * 60 * 60)).setPlural("weeks").setPluralAbbrev("wks");
062   public static final TimeUnit month       = new TimeUnit(MeasurementSystem.SI,       "month",  "mon", Calendar.MONTH,        new BaseSIUnitConverter(365.25 * 24 * 60 * 60 / 12)).setPlural("months");
063   public static final TimeUnit year        = new TimeUnit(MeasurementSystem.SI,        "year",   "yr", Calendar.YEAR,         new BaseSIUnitConverter(365.25 * 24 * 60 * 60)).setPlural("years").setPluralAbbrev("yrs");
064
065   //**************************************************************************
066   // CONSTRUCTORS
067   //**************************************************************************
068
069   //---------------------------------------------------------------------------
070   private TimeUnit(MeasurementSystem inSystem, String inName, String inAbbrev, int inCalendarNum)
071   {
072      this(inSystem, inName, inAbbrev, inCalendarNum, null);
073   }
074
075   //---------------------------------------------------------------------------
076   private TimeUnit(MeasurementSystem inSystem, String inName, String inAbbrev, int inCalendarNum, BaseSIUnitConverter inBaseUnitConverter)
077   {
078      super(inSystem, QuantityType.TIME, inName, inAbbrev, null, inBaseUnitConverter);
079
080      mCalendarNum = inCalendarNum;
081      mMilliseconds = 1000 * (int) this.computeBaseSIValue(1);
082
083      sUniqueMap.put(name(), this);
084
085      sLookupMap.put(name(), this);
086      sLookupMap.put(getAbbrev(), this);
087   }
088
089
090   //---------------------------------------------------------------------------
091   protected TimeUnit(List<SubUnit> inSubUnits)
092   {
093      super(inSubUnits);
094   }
095
096
097   //**************************************************************************
098   // PUBLIC METHODS
099   //**************************************************************************
100
101   //---------------------------------------------------------------------------
102   public static Collection<TimeUnit> values()
103   {
104      return sUniqueMap.values();
105   }
106
107   //---------------------------------------------------------------------------
108   /**
109    Returns the TimeUnit object that corresponds to the specified name or abbreviation string.
110    @param inValue the string name or abbreviation value to be converted into a TimeUnit object
111    @return the TimeUnit constant corresponding to the specified name or abbreviation
112    */
113   public static TimeUnit valueOf(String inValue)
114   {
115      TimeUnit result = null;
116      if (StringUtil.isSet(inValue))
117      {
118         String stringValue = inValue.trim();
119
120         result = sLookupMap.get(stringValue);
121
122         // Plural?
123         if (null == result
124               && stringValue.endsWith("s"))
125         {
126            result = sLookupMap.get(stringValue.substring(0, stringValue.length() - 1));
127         }
128
129         // Capitalization?
130         if (null == result
131               && Character.isUpperCase(stringValue.charAt(0)))
132         {
133            result = sLookupMap.get(stringValue.toLowerCase());
134
135            // Plural?
136            if (null == result
137                && stringValue.toLowerCase().endsWith("s"))
138            {
139               result = sLookupMap.get(stringValue.substring(0, stringValue.length() - 1).toLowerCase());
140            }
141         }
142
143         if (null == result)
144         {
145            // Try a more intensive parse attempt
146            Unit unitResult = Unit.valueOf(stringValue);
147            if (unitResult instanceof TimeUnit)
148            {
149               result = (TimeUnit) unitResult;
150            }
151         }
152      }
153
154      return result;
155   }
156
157   //---------------------------------------------------------------------------
158   @Override
159   public TimeUnit setMeasurementSystem(MeasurementSystem inValue)
160   {
161      return (TimeUnit) super.setMeasurementSystem(inValue);
162   }
163
164   //---------------------------------------------------------------------------
165   @Override
166   public TimeUnit setPlural(String inValue)
167   {
168      return (TimeUnit) super.setPlural(inValue);
169   }
170
171   //---------------------------------------------------------------------------
172   @Override
173   public TimeUnit setPluralAbbrev(String inValue)
174   {
175      return (TimeUnit) super.setPluralAbbrev(inValue);
176   }
177
178   //---------------------------------------------------------------------------
179   /**
180    Returns the associated int value to use with a Calendar object's get() method.
181    @return the Calendar object int value associated with this time unit.
182    */
183   public int getCalendarNum()
184   {
185      return mCalendarNum;
186   }
187
188   //---------------------------------------------------------------------------
189
190   /**
191    Returns the time unit's length in milliseconds. Note that the values for MONTH
192    and YEAR are approximations.
193    @return the length of time in milliseconds that corresponds to this unit of time.
194    */
195   public long getMilliseconds()
196   {
197      return mMilliseconds;
198   }
199
200
201   //---------------------------------------------------------------------------
202   @Override
203   public TimeUnit addAlternateName(String inValue)
204   {
205      super.addAlternateName(inValue);
206      sLookupMap.put(inValue, this);
207      return this;
208   }
209}