1 package org.djunits.quantity;
2
3 import org.djunits.quantity.def.AbsQuantity;
4 import org.djunits.quantity.def.AbstractReference;
5 import org.djunits.quantity.def.Quantity;
6
7 /**
8 * Time is the absolute equivalent of Duration, and can, e.g., represent a calendar date with a zero. Note that built-in time
9 * references are independent; DJUNITS does not embed calendar calculations.
10 * <p>
11 * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
12 * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
13 * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
14 * @author Alexander Verbraeck
15 */
16 public class Time extends AbsQuantity<Time, Duration, Time.Reference>
17 {
18 /** */
19 private static final long serialVersionUID = 600L;
20
21 /**
22 * Instantiate a Time quantity with a unit and a reference point.
23 * @param valueInUnit the duration value, expressed in a duration unit
24 * @param unit the duration unit in which the value is expressed, relative to the reference point
25 * @param reference the reference point of this time
26 */
27 public Time(final double valueInUnit, final Duration.Unit unit, final Reference reference)
28 {
29 super(new Duration(valueInUnit, unit), reference);
30 }
31
32 /**
33 * Instantiate a Time instance based on an duration and a reference point.
34 * @param duration the duration, relative to the reference point
35 * @param reference the reference point of this time
36 */
37 public Time(final Duration duration, final Reference reference)
38 {
39 super(duration, reference);
40 }
41
42 /**
43 * Return a Time instance based on an SI value and a reference point.
44 * @param si the duration si value, relative to the reference point
45 * @param reference the reference point of this time
46 * @return the Time instance based on an SI value
47 */
48 public static Time ofSi(final double si, final Reference reference)
49 {
50 return new Time(si, Duration.Unit.SI, reference);
51 }
52
53 @Override
54 public Time instantiate(final Duration duration, final Reference reference)
55 {
56 return new Time(duration, reference);
57 }
58
59 /**
60 * Returns a Time representation of a textual representation of a value with a unit. The String representation that can be
61 * parsed is the double value in the unit, followed by a localized or English abbreviation of the unit. Spaces are allowed,
62 * but not required, between the value and the unit.
63 * @param text the textual representation to parse into a Time
64 * @param reference the reference point of this time
65 * @return the Scalar representation of the value in its unit
66 * @throws IllegalArgumentException when the text cannot be parsed
67 * @throws NullPointerException when the text argument is null
68 */
69 public static Time valueOf(final String text, final Reference reference)
70 {
71 return new Time(Quantity.valueOf(text, Duration.ZERO), reference);
72 }
73
74 /**
75 * Returns a Time based on a value and the textual representation of the unit, which can be localized.
76 * @param valueInUnit the value, expressed in the unit as given by unitString
77 * @param unitString the textual representation of the unit
78 * @param reference the reference point of this time
79 * @return the Scalar representation of the value in its unit
80 * @throws IllegalArgumentException when the unit cannot be parsed or is incorrect
81 * @throws NullPointerException when the unitString argument is null
82 */
83 public static Time of(final double valueInUnit, final String unitString, final Reference reference)
84 {
85 return new Time(Quantity.of(valueInUnit, unitString, Duration.ZERO), reference);
86 }
87
88 @Override
89 public Duration subtract(final Time other)
90 {
91 var otherRef = other.relativeTo(getReference());
92 return Duration.ofSi(si() - otherRef.si()).setDisplayUnit(getDisplayUnit());
93 }
94
95 @Override
96 public Time add(final Duration other)
97 {
98 return new Time(Duration.ofSi(si() + other.si()).setDisplayUnit(getDisplayUnit()), getReference());
99 }
100
101 @Override
102 public Time subtract(final Duration other)
103 {
104 return new Time(Duration.ofSi(si() - other.si()).setDisplayUnit(getDisplayUnit()), getReference());
105 }
106
107 /**
108 * The reference class to define a reference point for the time. Note that built-in time references are independent; DJUNITS
109 * does not embed calendar calculations.
110 */
111 public static final class Reference extends AbstractReference<Reference, Time, Duration>
112 {
113 /** Gregorian. */
114 public static final Reference GREGORIAN = new Reference("GREGORIAN", "Gregorian time origin (1-1-0001)");
115
116 /** Unix. */
117 public static final Reference UNIX = new Reference("UNIX", "UNIX epoch, 1-1-1970, 00:00 GMT");
118
119 /** GPS. */
120 public static final Reference GPS = new Reference("GPS", "GPS epoch, 6-1-1980");
121
122 /**
123 * Define a new reference point for the time, with an offset value to another reference.
124 * @param id the id
125 * @param name the name or explanation
126 * @param offset the offset w.r.t. offsetReference
127 * @param offsetReference the reference to which the offset is relative
128 */
129 public Reference(final String id, final String name, final Duration offset, final Reference offsetReference)
130 {
131 super(id, name, offset, offsetReference);
132 }
133
134 /**
135 * Define a new reference point for the time without an offset to a base reference.
136 * @param id the id
137 * @param name the name or explanation
138 */
139 public Reference(final String id, final String name)
140 {
141 super(id, name, Duration.ZERO, null);
142 }
143
144 /**
145 * Define a new reference point for the time, with an offset value to another reference.
146 * @param id the id
147 * @param name the name or explanation
148 * @param offset the offset w.r.t. offsetReference
149 * @param offsetReference the reference to which the offset is relative
150 */
151 public static void add(final String id, final String name, final Duration offset, final Reference offsetReference)
152 {
153 new Reference(id, name, offset, offsetReference);
154 }
155
156 /**
157 * Define a new reference point for the time without an offset to a base reference.
158 * @param id the id
159 * @param name the name or explanation
160 */
161 public static void add(final String id, final String name)
162 {
163 new Reference(id, name);
164 }
165
166 /**
167 * Get a reference point for the time, based on its id. Return null when the id could not be found.
168 * @param id the id
169 * @return the TimeReference object
170 */
171 public static Reference get(final String id)
172 {
173 return AbstractReference.get(Time.Reference.class, id);
174 }
175
176 @Override
177 public Time instantiate(final Duration duration)
178 {
179 return new Time(duration, this);
180 }
181 }
182 }