1 package edu.iris.Fissures.model;
2
3 import java.io.Serializable;
4 import java.sql.Timestamp;
5 import java.text.SimpleDateFormat;
6 import java.util.Date;
7 import java.util.TimeZone;
8 import edu.iris.Fissures.Time;
9
10 /***
11 * subclass of the java.util.Date class to extend the precision to microseconds
12 * and to eventually handle leap seconds.
13 *
14 * @author H. Philip Crotwell
15 */
16 public class MicroSecondDate extends Date implements Serializable {
17
18 protected long microseconds;
19
20 protected int leapSecondVersion;
21
22 protected LeapSecondHistory leapHistory;
23
24 public MicroSecondDate() {
25 super();
26 this.leapSecondVersion = 0;
27 this.microseconds = 0;
28 }
29
30 public MicroSecondDate(long microseconds) {
31 this(microseconds, 0);
32 }
33
34 public MicroSecondDate(long microseconds, int leapSeconds) {
35 super(microseconds / 1000);
36 this.microseconds = microseconds % 1000;
37 this.leapSecondVersion = leapSeconds;
38 }
39
40 public MicroSecondDate(Date d) {
41 this(d.getTime() * 1000, 0);
42 }
43
44 public MicroSecondDate(MicroSecondDate d) {
45 this(d.getMicroSecondTime());
46 }
47
48 public MicroSecondDate(Timestamp ts, int leapSeconds) {
49
50
51
52
53 this(fixTimestamp(ts), leapSeconds);
54 }
55
56 /***
57 * fixBadJavaDatabaseTimestampNanos13Vs14Bug
58 *
59 * @returns microseconds from the timestamp
60 */
61 static long fixTimestamp(Timestamp ts) {
62 long tsFracSeconds = ts.getTime() % 1000;
63 if(tsFracSeconds == 0) {
64
65 return ts.getTime() * 1000 + ts.getNanos() / 1000;
66 } else {
67
68 return ts.getTime() * 1000 + (ts.getNanos() / 1000) % 1000;
69 }
70 }
71
72 public MicroSecondDate(Timestamp ts) {
73 this(ts, 0);
74 }
75
76 public MicroSecondDate(Time t) {
77 this(new ISOTime(t.date_time).getDate().getMicroSecondTime(),
78 t.leap_seconds_version);
79 }
80
81 public long getMicroSecondTime() {
82 return super.getTime() * 1000 + microseconds;
83 }
84
85 /***
86 * Returns the microseconds as a number between 0 and 999, the milliseconds
87 * are kept in the Date superclass.
88 *
89 * @return the microseconds as a number between 0 and 999.
90 */
91 public long getMicroSeconds() {
92 return microseconds;
93 }
94
95 public Timestamp getTimestamp() {
96 Timestamp t = new Timestamp(getTime());
97 int nanos = t.getNanos();
98 nanos += microseconds * 1000;
99 t.setNanos(nanos);
100 return t;
101 }
102
103 public edu.iris.Fissures.Time getFissuresTime() {
104 return new Time(ISOTime.getISOString(this), this.leapSecondVersion);
105 }
106
107 public MicroSecondDate add(TimeInterval interval) {
108 if(interval == null) { throw new IllegalArgumentException("Cannot add() a null TimeInterval"); }
109 return new MicroSecondDate(getMicroSecondTime()
110 + Math.round(interval.convertTo(UnitImpl.MICROSECOND)
111 .getValue()));
112 }
113
114 public MicroSecondDate subtract(TimeInterval interval) {
115 if(interval == null) { throw new IllegalArgumentException("Cannot subtract() a null TimeInterval"); }
116 return new MicroSecondDate(getMicroSecondTime()
117 - Math.round(interval.convertTo(UnitImpl.MICROSECOND)
118 .getValue()));
119 }
120
121 /***
122 * Returns the timewidth of this - otherDate.
123 */
124 public TimeInterval subtract(MicroSecondDate otherDate) {
125 if(otherDate == null) { throw new IllegalArgumentException("Cannot difference() a null MicroSecondDate"); }
126 return new TimeInterval(getMicroSecondTime()
127 - otherDate.getMicroSecondTime(), UnitImpl.MICROSECOND);
128 }
129
130 /***
131 * Returns the TimeInterval between the two times. It is always positive
132 * regardless of which time comes before the other.
133 */
134 public TimeInterval difference(MicroSecondDate otherDate) {
135 if(otherDate == null) { throw new IllegalArgumentException("Cannot difference() a null MicroSecondDate"); }
136 long otherTime = otherDate.getMicroSecondTime();
137 long myTime = getMicroSecondTime();
138 if(before(otherDate)) { return new TimeInterval(otherTime - myTime,
139 UnitImpl.MICROSECOND); }
140 return new TimeInterval(myTime - otherTime, UnitImpl.MICROSECOND);
141 }
142
143 public boolean equals(Object otherDate) {
144 if(otherDate == this) { return true; }
145 if(super.equals(otherDate)) {
146
147 if(otherDate instanceof MicroSecondDate) {
148 MicroSecondDate oMSD = (MicroSecondDate)otherDate;
149 return getMicroSecondTime() == oMSD.getMicroSecondTime()
150 && leapSecondVersion == oMSD.leapSecondVersion;
151 }
152
153
154 return true;
155 }
156 return false;
157 }
158
159
160
161
162
163 public int hashCode() {
164 return super.hashCode();
165 }
166
167 public boolean after(Date otherDate) {
168 if(super.after(otherDate)) { return true; }
169 if(super.equals(otherDate) && otherDate instanceof MicroSecondDate) {
170 if(getMicroSecondTime() > ((MicroSecondDate)otherDate).getMicroSecondTime()) return true;
171 }
172 return false;
173 }
174
175 public boolean before(Date otherDate) {
176 if(super.before(otherDate)) { return true; }
177 if(super.equals(otherDate) && otherDate instanceof MicroSecondDate) {
178 if(getMicroSecondTime() < ((MicroSecondDate)otherDate).getMicroSecondTime()) return true;
179 }
180 return false;
181 }
182
183 public String toString() {
184 SimpleDateFormat df = new SimpleDateFormat("G yyyy.MM.dd HH:mm:ss.SSS zzz");
185
186
187 df.setTimeZone(TimeZone.getTimeZone("GMT"));
188 return df.format(this);
189 }
190 }