13219e97566a093ed10b2a9d6fe77ed9089084d63Mitchell Wills// © 2016 and later: Unicode, Inc. and others.
294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills// License & terms of use: http://www.unicode.org/copyright.html#License
394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills/*
494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills******************************************************************************
594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills* Copyright (C) 2007, International Business Machines Corporation and   *
694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills* others. All Rights Reserved.                                               *
794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills******************************************************************************
894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills*/
994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willspackage com.ibm.icu.impl.duration;
1194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
1294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willsimport com.ibm.icu.impl.duration.impl.DataRecord.ETimeLimit;
1394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
14a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills/**
1594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Represents an approximate duration in multiple TimeUnits.  Each unit,
1694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * if set, has a count (which can be fractional and must be non-negative).
17a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills * In addition Period can either represent the duration as being into the past
1894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * or future, and as being more or less than the defined value.
190ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills * <p>
2023216ca333dc411e6ce0829f777ca29992388443Roshan Pius * Use a PeriodFormatter to convert a Period to a String.
2123216ca333dc411e6ce0829f777ca29992388443Roshan Pius * <p>
220ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills * Periods are immutable.  Mutating operations return the new
230ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills * result leaving the original unchanged.
240ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills * <p>
2594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Example:<pre>
26f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley * Period p1 = Period.at(3, WEEK).and(2, DAY).inFuture();
27107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne * Period p2 = p1.and(12, HOUR);</pre>
2894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */
2994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Willspublic final class Period {
306c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein  final byte timeLimit;
3194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  final boolean inFuture;
32c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius  final int[] counts;
3394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
3494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
351345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills   * Constructs a Period representing a duration of
360ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills   * count units extending into the past.
3794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param count the number of units, must be non-negative
3894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param unit the unit
391345d63ec537cc75b8daf9cafbb8b1fd78338ec5Mitchell Wills   * @return the new Period
406c11cd5d6ff04afdf1bbbc99a850025d46c7bdc9Rebecca Silberstein   */
410ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills  public static Period at(float count, TimeUnit unit) {
42f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley    checkCount(count);
4394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return new Period(ETimeLimit.NOLIMIT, false, count, unit);
44c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius  }
4594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
4694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
475382acb5eb3a0448a32651dcc7fe9fd634ce0e38Roshan Pius   * Constructs a Period representing a duration more than
4894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * count units extending into the past.
49f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley   * @param count the number of units. must be non-negative
50ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius   * @param unit the unit
514fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao   * @return the new Period
52e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao   */
53a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills  public static Period moreThan(float count, TimeUnit unit) {
54a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills    checkCount(count);
55a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills    return new Period(ETimeLimit.MT, false, count, unit);
56a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills  }
57a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills
58da94688198c864bb29be2e9603ebbe9ae6492a87Tamas Berghammer  /**
59e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao   * Constructs a Period representing a duration
6094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * less than count units extending into the past.
6194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param count the number of units. must be non-negative
6294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param unit the unit
6394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @return the new Period
6494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
65d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  public static Period lessThan(float count, TimeUnit unit) {
6694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    checkCount(count);
6794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return new Period(ETimeLimit.LT, false, count, unit);
684fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao  }
69160c5fd3f82eeed7271d0efc44b6a409c9176326Paul Duffin
7094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
71d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills   * Set the given unit to have the given count.  Marks the
72d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills   * unit as having been set.  This can be used to set
73d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills   * multiple units, or to reset a unit to have a new count.
74c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius   * This does <b>not</b> add the count to an existing count
75c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius   * for this unit.
76c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius   *
77d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein   * @param count the number of units.  must be non-negative
78d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills   * @param unit the unit
79c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius   * @return the new Period
8094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
81a8367288377cbaed6371256ca837b7aa22280706Mitchell Wills  public Period and(float count, TimeUnit unit) {
8294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    checkCount(count);
8394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return setTimeUnitValue(unit, count);
8494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
8594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
8694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
871b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius   * Mark the given unit as not being set.
881b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius   *
8994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param unit the unit to unset
90f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley   * @return the new Period
9194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
9294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  public Period omit(TimeUnit unit) {
9394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return setTimeUnitInternalValue(unit, 0);
94c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne  }
95e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao
96107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne  /**
974fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao   * Mark the duration as being at the defined duration.
98c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne   *
99f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley   * @return the new Period
10094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
10194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  public Period at() {
102c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    return setTimeLimit(ETimeLimit.NOLIMIT);
10394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
10494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
10594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
10694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * Mark the duration as being more than the defined duration.
107f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley   *
1088adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @return the new Period
1098adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   */
1108adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  public Period moreThan() {
111e6d8fa5fb50afdfc04922f7f87c2cac08db5bbecMitchell Wills    return setTimeLimit(ETimeLimit.MT);
11294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
11394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
11494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
11594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * Mark the duration as being less than the defined duration.
116f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley   *
11746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne   * @return the new Period
118ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius   */
119fee1cae825bad9459edcefb67fa600874d875816Ningyuan Wang  public Period lessThan() {
12094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return setTimeLimit(ETimeLimit.LT);
1217e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills  }
122c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1234fbaf3821bd5c3056c7c4cdd1aee3e17ac7046d0Sohani Rao  /**
124e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao   * Mark the time as being in the future.
125e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao   *
126e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao   * @return the new Period
127e7ebc3fba71f4f996794bc5fa939674f8b4b2c5aSohani Rao   */
12823216ca333dc411e6ce0829f777ca29992388443Roshan Pius  public Period inFuture() {
12994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return setFuture(true);
130c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne  }
13194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
13294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
13394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * Mark the duration as extending into the past.
13494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   *
13594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @return the new Period
13694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
13794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  public Period inPast() {
138d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    return setFuture(false);
139d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  }
140d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
141d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
142d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Mark the duration as extending into the future if
14394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * future is true, and into the past otherwise.
14494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   *
14594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param future true if the time is in the future
14694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @return the new Period
14794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
14894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  public Period inFuture(boolean future) {
14994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return setFuture(future);
15094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
15194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
15294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
15394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * Mark the duration as extending into the past if
15494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * past is true, and into the future otherwise.
15594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   *
15694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param past true if the time is in the past
15794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @return the new Period
1585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   */
15994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  public Period inPast(boolean past) {
160d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    return setFuture(!past);
16194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
16294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
16394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
1645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * Returns true if any unit is set.
1658adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @return true if any unit is set
1668adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   */
167160c5fd3f82eeed7271d0efc44b6a409c9176326Paul Duffin  public boolean isSet() {
1688adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    for (int i = 0; i < counts.length; ++i) {
1698adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills      if (counts[i] != 0) {
1708adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills        return true;
1718adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills      }
1728adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1738adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    return false;
1748adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  }
1758adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills
176d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein  /**
177d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Returns true if the given unit is set.
1788adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @param unit the unit to test
1798adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @return true if the given unit is set.
180d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   */
181d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  public boolean isSet(TimeUnit unit) {
182d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    return counts[unit.ordinal] > 0;
1835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills  }
184d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
185d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
186d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Returns the count for the specified unit.  If the
187d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * unit is not set, returns 0.
188d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * @param unit the unit to test
189d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * @return the count
190d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   */
191d94a62ffdf0e7f282948109d05d96e682eb32eefRebecca Silberstein  public float getCount(TimeUnit unit) {
1925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    int ord = unit.ordinal;
1938adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    if (counts[ord] == 0) {
1948adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills      return 0;
1958adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    }
1968adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    return (counts[ord] - 1)/1000f;
1978adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  }
1985751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
1998adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  /**
2008adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * Returns true if this represents a
2018adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * duration into the future.
2028adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @return true if this represents a
2035751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * duration into the future.
2040ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills   */
2050ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills  public boolean isInFuture() {
2060ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills    return inFuture;
2070ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills  }
208d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
2090ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills  /**
210d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Returns true if this represents a
211d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * duration into the past
2125751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * @return true if this represents a
2130ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills   * duration into the past
2140ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills   */
2150ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills  public boolean isInPast  () {
2160ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills    return !inFuture;
2178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  }
2180ea5062316013cd4173faf16c2a0f3ecd1b9ed43Mitchell Wills
2198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  /**
2208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * Returns true if this represents a duration in
2211ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * excess of the defined duration.
2221ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * @return true if this represents a duration in
2231ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * excess of the defined duration.
2241ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   */
2251ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  public boolean isMoreThan() {
2261ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    return timeLimit == ETimeLimit.MT;
2271ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  }
2281ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2291ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  /**
2301ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * Returns true if this represents a duration
2311ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * less than the defined duration.
2321ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * @return true if this represents a duration
2335751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * less than the defined duration.
234d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   */
235d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  public boolean isLessThan() {
23694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    return timeLimit == ETimeLimit.LT;
23794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
2385751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
239d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
240d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Returns true if rhs extends Period and
241d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * the two Periods are equal.
242d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * @param rhs the object to compare to
243d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * @return true if rhs is a Period and is equal to this
244d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   */
245d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  @Override
246d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  public boolean equals(Object rhs) {
247d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    try {
248d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills      return equals((Period)rhs);
2495751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    }
2505751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    catch (ClassCastException e) {
2515751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills      return false;
2521ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2531ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  }
2545751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
2555751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills  /**
2561ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * Returns true if the same units are defined with
2571ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * the same counts, both extend into the future or both into the
2585751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * past, and if the limits (at, more than, less than) are the same.
2591ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills   * Note that this means that a period of 1000ms and a period of 1sec
2605751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * will not compare equal.
2615751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   *
2625751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * @param rhs the period to compare to
2635751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * @return true if the two periods are equal
2645751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   */
2655751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills  public boolean equals(Period rhs) {
2665751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    if (rhs != null &&
2675751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        this.timeLimit == rhs.timeLimit &&
2685751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        this.inFuture == rhs.inFuture) {
2695751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills      for (int i = 0; i < counts.length; ++i) {
2705751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        if (counts[i] != rhs.counts[i]) {
2715751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills          return false;
2725751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills        }
2731ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills      }
2741ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills      return true;
2751ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2761ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    return false;
2771ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  }
2785751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
2795751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills  /**
2805751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * Returns the hashCode.
2815751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * @return the hashCode
2825751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   */
2835751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills  @Override
2845751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Willspublic int hashCode() {
2855751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    int hc = (timeLimit << 1) | (inFuture ? 1 : 0);
2865751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    for (int i = 0; i < counts.length; ++i) {
2871ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills      hc = (hc << 2) ^ counts[i];
2881ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    }
2891ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    return hc;
2901ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  }
2911ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills
2925751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills  /**
2935751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   * Private constructor used by static factory methods.
2945751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills   */
2951ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  private Period(int limit, boolean future, float count, TimeUnit unit) {
2961ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    this.timeLimit = (byte) limit;
2971ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    this.inFuture = future;
2981ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    this.counts = new int[TimeUnit.units.length];
2991ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills    this.counts[unit.ordinal] = (int)(count * 1000) + 1;
3001ba04405f98489f0fbd66b6566c64324be11111aMitchell Wills  }
3015751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills
30294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
303d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Package private constructor used by setters and factory.
304d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   */
30594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  Period(int timeLimit, boolean inFuture, int[] counts) {
30694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    this.timeLimit = (byte) timeLimit;
3075751e82f645ab5b4366c63e0fbc561534c1cb3b8Mitchell Wills    this.inFuture = inFuture;
30894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    this.counts = counts;
309d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  }
310d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
311d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
312d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   * Set the unit's internal value, converting from float to int.
313d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills   */
314d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  private Period setTimeUnitValue(TimeUnit unit, float value) {
315d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    if (value < 0) {
316d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills      throw new IllegalArgumentException("value: " + value);
317d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
318d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    return setTimeUnitInternalValue(unit, (int)(value * 1000) + 1);
319d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  }
320d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
321d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
3228adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * Sets the period to have the provided value, 1/1000 of the
3238adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * unit plus 1.  Thus unset values are '0', 1' is the set value '0',
3248adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * 2 is the set value '1/1000', 3 is the set value '2/1000' etc.
3258adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @param p the period to change
3268adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @param value the int value as described above.
3278adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @eturn the new Period object.
3288adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   */
3298adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills  private Period setTimeUnitInternalValue(TimeUnit unit, int value) {
3308adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    int ord = unit.ordinal;
3318adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills    if (counts[ord] != value) {
3328adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills      int[] newCounts = new int[counts.length];
3338adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills      for (int i = 0; i < counts.length; ++i) {
334c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius        newCounts[i] = counts[i];
335c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius      }
336d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills      newCounts[ord] = value;
337d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills      return new Period(timeLimit, inFuture, newCounts);
338c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    }
339c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius    return this;
340d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  }
341c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius
342d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
343c343aec32e1d3fe320eb97c527b0bcfb2d334e45Roshan Pius   * Sets whether this defines a future time.
34494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @param future true if the time is in the future
34594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * @return  the new Period
3468adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   */
34794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  private Period setFuture(boolean future) {
34894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    if (this.inFuture != future) {
3491b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius      return new Period(timeLimit, future, counts);
3503040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    }
3513040b86393a04bc939a5a94cda4169b0293dfac7Mitchell Wills    return this;
3521b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius  }
35394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
35494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  /**
35594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * Sets whether this is more than, less than, or
35694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   * 'about' the specified time.
3571b76ca405029249b41b38424a253a8c5fa72dab1Roshan Pius   * @param limit the kind of limit
3588adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills   * @return the new Period
35994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills   */
36094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  private Period setTimeLimit(byte limit) {
36194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    if (this.timeLimit != limit) {
36294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills      return new Period(limit, inFuture, counts);
36394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills
364d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    }
365d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills    return this;
36694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  }
367d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills
368d2d3de4c2bea4b949ed78a9b01b920bffa7e51a9Mitchell Wills  /**
36968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang   * Validate count.
37068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang   */
37194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills  private static void checkCount(float count) {
37294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills    if (count < 0) {
37394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills      throw new IllegalArgumentException("count (" + count +
374d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills                                         ") cannot be negative");
375d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills    }
376d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills  }
377d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills}
378d36b93b07ee7a3f6116cc7ae7a1a1e6b687a9d3cMitchell Wills