1 /* 2 * hunt-time: A time library for D programming language. 3 * 4 * Copyright (C) 2015-2018 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.time.temporal.TemporalAmount; 13 14 import hunt.time.Exceptions; 15 import hunt.time.Duration; 16 import hunt.time.Period; 17 import hunt.collection.List; 18 import hunt.time.temporal.TemporalUnit; 19 import hunt.time.temporal.Temporal; 20 21 /** 22 * Framework-level interface defining an amount of time, such as 23 * "6 hours", "8 days" or "2 years and 3 months". 24 * !(p) 25 * This is the base interface type for amounts of time. 26 * An amount is distinct from a date or time-of-day _in that it is not tied 27 * to any specific point on the time-line. 28 * !(p) 29 * The amount can be thought of as a {@code Map} of {@link TemporalUnit} to 30 * {@code long}, exposed via {@link #getUnits()} and {@link #get(TemporalUnit)}. 31 * A simple case might have a single unit-value pair, such as "6 hours". 32 * A more complex case may have multiple unit-value pairs, such as 33 * "7 years, 3 months and 5 days". 34 * !(p) 35 * There are two common implementations. 36 * {@link Period} is a date-based implementation, storing years, months and days. 37 * {@link Duration} is a time-based implementation, storing seconds and nanoseconds, 38 * but providing some access using other duration based units such as minutes, 39 * hours and fixed 24-hour days. 40 * !(p) 41 * This interface is a framework-level interface that should not be widely 42 * used _in application code. Instead, applications should create and pass 43 * around instances of concrete types, such as {@code Period} and {@code Duration}. 44 * 45 * @implSpec 46 * This interface places no restrictions on the mutability of implementations, 47 * however immutability is strongly recommended. 48 * 49 * @since 1.8 50 */ 51 public interface TemporalAmount { 52 53 /** 54 * Returns the value of the requested unit. 55 * The units returned from {@link #getUnits()} uniquely define the 56 * value of the {@code TemporalAmount}. A value must be returned 57 * for each unit listed _in {@code getUnits}. 58 * 59 * @implSpec 60 * Implementations may declare support for units not listed by {@link #getUnits()}. 61 * Typically, the implementation would define additional units 62 * as conversions for the convenience of developers. 63 * 64 * @param unit the {@code TemporalUnit} for which to return the value 65 * @return the long value of the unit 66 * @throws DateTimeException if a value for the unit cannot be obtained 67 * @throws UnsupportedTemporalTypeException if the {@code unit} is not supported 68 */ 69 long get(TemporalUnit unit); 70 71 /** 72 * Returns the list of units uniquely defining the value of this TemporalAmount. 73 * The list of {@code TemporalUnits} is defined by the implementation class. 74 * The list is a snapshot of the units at the time {@code getUnits} 75 * is called and is not mutable. 76 * The units are ordered from longest duration to the shortest duration 77 * of the unit. 78 * 79 * @implSpec 80 * The list of units completely and uniquely represents the 81 * state of the object without omissions, overlaps or duplication. 82 * The units are _in order from longest duration to shortest. 83 * 84 * @return the List of {@code TemporalUnits}; not null 85 */ 86 List!(TemporalUnit) getUnits(); 87 88 /** 89 * Adds to the specified temporal object. 90 * !(p) 91 * Adds the amount to the specified temporal object using the logic 92 * encapsulated _in the implementing class. 93 * !(p) 94 * There are two equivalent ways of using this method. 95 * The first is to invoke this method directly. 96 * The second is to use {@link Temporal#plus(TemporalAmount)}: 97 * !(pre) 98 * // These two lines are equivalent, but the second approach is recommended 99 * dateTime = amount.addTo(dateTime); 100 * dateTime = dateTime.plus(adder); 101 * </pre> 102 * It is recommended to use the second approach, {@code plus(TemporalAmount)}, 103 * as it is a lot clearer to read _in code. 104 * 105 * @implSpec 106 * The implementation must take the input object and add to it. 107 * The implementation defines the logic of the addition and is responsible for 108 * documenting that logic. It may use any method on {@code Temporal} to 109 * query the temporal object and perform the addition. 110 * The returned object must have the same observable type as the input object 111 * !(p) 112 * The input object must not be altered. 113 * Instead, an adjusted copy of the original must be returned. 114 * This provides equivalent, safe behavior for immutable and mutable temporal objects. 115 * !(p) 116 * The input temporal object may be _in a calendar system other than ISO. 117 * Implementations may choose to document compatibility with other calendar systems, 118 * or reject non-ISO temporal objects by {@link TemporalQueries#chronology() querying the chronology}. 119 * !(p) 120 * This method may be called from multiple threads _in parallel. 121 * It must be thread-safe when invoked. 122 * 123 * @param temporal the temporal object to add the amount to, not null 124 * @return an object of the same observable type with the addition made, not null 125 * @throws DateTimeException if unable to add 126 * @throws ArithmeticException if numeric overflow occurs 127 */ 128 Temporal addTo(Temporal temporal); 129 130 /** 131 * Subtracts this object from the specified temporal object. 132 * !(p) 133 * Subtracts the amount from the specified temporal object using the logic 134 * encapsulated _in the implementing class. 135 * !(p) 136 * There are two equivalent ways of using this method. 137 * The first is to invoke this method directly. 138 * The second is to use {@link Temporal#minus(TemporalAmount)}: 139 * !(pre) 140 * // these two lines are equivalent, but the second approach is recommended 141 * dateTime = amount.subtractFrom(dateTime); 142 * dateTime = dateTime.minus(amount); 143 * </pre> 144 * It is recommended to use the second approach, {@code minus(TemporalAmount)}, 145 * as it is a lot clearer to read _in code. 146 * 147 * @implSpec 148 * The implementation must take the input object and subtract from it. 149 * The implementation defines the logic of the subtraction and is responsible for 150 * documenting that logic. It may use any method on {@code Temporal} to 151 * query the temporal object and perform the subtraction. 152 * The returned object must have the same observable type as the input object 153 * !(p) 154 * The input object must not be altered. 155 * Instead, an adjusted copy of the original must be returned. 156 * This provides equivalent, safe behavior for immutable and mutable temporal objects. 157 * !(p) 158 * The input temporal object may be _in a calendar system other than ISO. 159 * Implementations may choose to document compatibility with other calendar systems, 160 * or reject non-ISO temporal objects by {@link TemporalQueries#chronology() querying the chronology}. 161 * !(p) 162 * This method may be called from multiple threads _in parallel. 163 * It must be thread-safe when invoked. 164 * 165 * @param temporal the temporal object to subtract the amount from, not null 166 * @return an object of the same observable type with the subtraction made, not null 167 * @throws DateTimeException if unable to subtract 168 * @throws ArithmeticException if numeric overflow occurs 169 */ 170 Temporal subtractFrom(Temporal temporal); 171 }