]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/data/Timestamp.java
ac144bb8c59e8247deb67438a9f5c8504c258ca9
[GpsPrune.git] / src / tim / prune / data / Timestamp.java
1 package tim.prune.data;
2
3
4 import java.text.DateFormat;
5 import java.text.SimpleDateFormat;
6 import java.util.Calendar;
7 import java.util.TimeZone;
8
9
10 /**
11  * Superclass of all timestamp implementations
12  */
13 public abstract class Timestamp
14 {
15         private static final DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateInstance();
16         private static final DateFormat DEFAULT_TIME_FORMAT = DateFormat.getTimeInstance();
17
18         protected static final DateFormat DEFAULT_DATETIME_FORMAT = DateFormat.getDateTimeInstance();
19
20         protected static final DateFormat ISO_8601_FORMAT
21                 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
22         protected static final DateFormat ISO_8601_FORMAT_WITH_MILLIS
23                 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
24
25         private static boolean MillisAddedToTimeFormat = false;
26
27
28         /** Possible formats for parsing and displaying timestamps */
29         public enum Format
30         {
31                 ORIGINAL,
32                 LOCALE,
33                 ISO8601
34         }
35
36
37         // Static block to initialise date formats
38         static
39         {
40                 // Set timezone for output
41                 TimeZone gmtZone = TimeZone.getTimeZone("GMT");
42                 ISO_8601_FORMAT.setTimeZone(gmtZone);
43                 ISO_8601_FORMAT_WITH_MILLIS.setTimeZone(gmtZone);
44                 DEFAULT_DATETIME_FORMAT.setTimeZone(gmtZone);
45         }
46
47
48         /**
49          * @return true if valid
50          */
51         public abstract boolean isValid();
52
53         /**
54          * Get a calendar representing this timestamp
55          */
56         public abstract Calendar getCalendar(TimeZone inZone);
57
58         /**
59          * @return the milliseconds according to the given timezone
60          */
61         public abstract long getMilliseconds(TimeZone inZone);
62
63         /**
64          * @return true if this timestamp is after the other one
65          */
66         public boolean isAfter(Timestamp inOther)
67         {
68                 return getMillisecondsSince(inOther) > 0;
69         }
70
71         /**
72          * @return true if this timestamp is before the other one
73          */
74         public boolean isBefore(Timestamp inOther)
75         {
76                 return getMillisecondsSince(inOther) < 0;
77         }
78
79         /**
80          * @return true if this timestamp is equal to the other one
81          */
82         public boolean isEqual(Timestamp inOther)
83         {
84                 return getMillisecondsSince(inOther) == 0;
85         }
86
87         /**
88          * @return the number of seconds since the other timestamp
89          */
90         public long getSecondsSince(Timestamp inOther)
91         {
92                 return getMillisecondsSince(inOther) / 1000L;
93         }
94
95         /**
96          * Calculate the difference between two Timestamps in milliseconds
97          * @param inOther other, earlier Timestamp
98          * @return number of milliseconds since other timestamp
99          */
100         public long getMillisecondsSince(Timestamp inOther)
101         {
102                 return getMilliseconds(null) - inOther.getMilliseconds(null);
103         }
104
105         /**
106          * @return the number of seconds since the other timestamp using the given timezone
107          */
108         public long getSecondsSince(Timestamp inOther, TimeZone inTimezone)
109         {
110                 return (getMilliseconds(inTimezone) - inOther.getMilliseconds(inTimezone)) / 1000L;
111         }
112
113         /**
114          * Add the given number of seconds offset
115          * @param inOffset number of seconds to add/subtract
116          */
117         public abstract void addOffsetSeconds(long inOffset);
118
119         /**
120          * @return true if the timestamp has non-zero milliseconds
121          */
122         protected abstract boolean hasMilliseconds();
123
124
125         /**
126          * @return date part of timestamp in locale-specific format
127          */
128         public String getDateText(TimeZone inTimezone)
129         {
130                 if (!isValid()) return "";
131                 return format(DEFAULT_DATE_FORMAT, inTimezone);
132         }
133
134         /**
135          * @return Description of time part of timestamp in locale-specific format
136          */
137         public String getTimeText(TimeZone inTimezone)
138         {
139                 if (!isValid()) return "";
140                 // Maybe we should add milliseconds to this format?
141                 if (hasMilliseconds() && !MillisAddedToTimeFormat)
142                 {
143                         try
144                         {
145                                 SimpleDateFormat sdf = (SimpleDateFormat) DEFAULT_TIME_FORMAT;
146                                 String pattern = sdf.toPattern();
147                                 if (pattern.indexOf("ss") > 0 && pattern.indexOf("SS") < 0)
148                                 {
149                                         sdf.applyPattern(pattern.replaceFirst("s+", "$0.SSS"));
150                                         MillisAddedToTimeFormat = true;
151                                 }
152                         }
153                         catch (ClassCastException cce) {}
154                 }
155                 return format(DEFAULT_TIME_FORMAT, inTimezone);
156         }
157
158         /**
159          * Utility method for formatting dates / times
160          */
161         protected abstract String format(DateFormat inFormat, TimeZone inTimezone);
162
163
164         /**
165          * @return Description of timestamp in locale-specific format
166          */
167         public String getText(TimeZone inTimezone)
168         {
169                 return getText(Format.LOCALE, inTimezone);
170         }
171
172         /**
173          * @param inFormat format of timestamp
174          * @return Description of timestamp in required format
175          */
176         public String getText(Format inFormat, TimeZone inTimezone)
177         {
178                 if (!isValid()) {
179                         return "";
180                 }
181                 switch (inFormat)
182                 {
183                         case ORIGINAL:
184                         case LOCALE:
185                         default:
186                                 return format(DEFAULT_DATETIME_FORMAT, inTimezone);
187                         case ISO8601:
188                                 return format(hasMilliseconds() ? ISO_8601_FORMAT_WITH_MILLIS : ISO_8601_FORMAT,
189                                         inTimezone);
190                 }
191         }
192
193 }