1 package edu.iris.Fissures.model;
2
3 import java.text.DateFormat;
4 import java.text.DecimalFormat;
5 import java.text.ParsePosition;
6 import java.text.SimpleDateFormat;
7 import java.util.Calendar;
8 import java.util.Date;
9 import java.util.TimeZone;
10
11 /***
12 * ISOTime.java Created: Fri Jul 9 13:45:39 1999
13 *
14 * @author Philip Crotwell
15 * @version
16 */
17 public class ISOTime {
18
19 /***
20 * parses a ISO8601 string into its component parts. Currently we only
21 * support the 4 month based, full formats, <break>
22 * yyyy-mm-ddThh:mm:ss.ddddZTD <BREAK>yyyy-mm-ddThhmmss.ddddZTD <BREAK>
23 * yyyymmddThh:mm:ss.ddddZTD <BREAK>yyyymmddThhmmss.ddddZTD, <BREAK>plus the
24 * similar julian day formats, <BREAK>yyyyjjjThh:mm:ss.ddddZTD and
25 * yyyyjjjThhmmss.ddddZTD. The time zone part, ZTD, is either Z for zulu, ie
26 * UTC, or a offset from UTC in the form of +hh:mm or -hh:mm.
27 */
28 public ISOTime(String s) throws UnsupportedFormat {
29 orig = s;
30
31 if(s.equals(edu.iris.Fissures.TIME_UNKNOWN.value)
32 || s.equals("25991231235959.0000GMT")) {
33 date = TimeUtils.future;
34 } else {
35 String clean = cleanDate(s);
36 Date d = null;
37 for(int i = 0; i < dateFormats.length; i++) {
38 synchronized(dateFormats[i]) {
39 d = dateFormats[i].parse(clean, new ParsePosition(0));
40 }
41 if(d != null) {
42 break;
43 }
44 }
45 if(d == null) {
46
47 throw new UnsupportedFormat(s);
48 }
49 date = new MicroSecondDate(d);
50 }
51 }
52
53 public ISOTime(int year, int jday, int hour, int minute, float second) {
54 this(getISOString(year, jday, hour, minute, second));
55 }
56
57 public static String getISOString(int year,
58 int jday,
59 int hour,
60 int minute,
61 float second) {
62 DecimalFormat xxFormat = new DecimalFormat("00");
63 DecimalFormat xxxFormat = new DecimalFormat("000");
64 DecimalFormat floatFormat = new DecimalFormat("00.000#");
65 return xxxFormat.format(year) + xxxFormat.format(jday) + "T"
66 + xxFormat.format(hour) + xxFormat.format(minute)
67 + floatFormat.format(second) + "Z";
68 }
69
70 private static final DateFormat[] dateFormats;
71
72 public static final String[] patterns = {"yyyyDDD'J'HHmmss.SSSz",
73 "yyyyMMddHHmmss.SSSz",
74 "yyyyMMdd'T'HH:mm:ss.SSSz",
75 "yyyy-MM-dd'T'HH:mm:ss.SSSz",
76 "yyyyDDD'J'HH:mm:ss.SSSz",
77 "yyyyMMdd'T'HHmmss.SSSz",
78 "yyyy-MM-dd'T'HHmmss.SSSz",
79 "yyyyMMdd HH:mm:ss.SSSz",
80 "yyyyMMdd HHmmss.SSSz",
81 "yyyy-MM-dd HH:mm:ss.SSSz",
82 "yyyy-MM-dd HHmmss.SSSz",
83 "yyyyDDD'J'HH:mm:ssz",
84 "yyyyDDD'J'HHmmssz",
85 "yyyyMMdd'T'HH:mm:ssz",
86 "yyyyMMdd'T'HHmmssz",
87 "yyyy-MM-dd'T'HH:mm:ssz",
88 "yyyy-MM-dd'T'HHmmssz",
89 "yyyyMMdd HH:mm:ssz",
90 "yyyyMMdd HHmmssz",
91 "yyyy-MM-dd HH:mm:ssz",
92 "yyyy-MM-dd HHmmssz",
93 "yyyyMMddHHmmssz"};
94
95 static int[] matches = new int[patterns.length];
96 static {
97 dateFormats = new DateFormat[patterns.length];
98 TimeZone gmt = TimeZone.getTimeZone("GMT");
99 for(int i = 0; i < patterns.length; i++) {
100 dateFormats[i] = new SimpleDateFormat(patterns[i]);
101 dateFormats[i].setTimeZone(gmt);
102 }
103 }
104
105 protected String cleanDate(String s) {
106 int zoneIndex = s.indexOf('Z');
107 if(zoneIndex == -1) {
108
109 zoneIndex = s.indexOf('+');
110 if(zoneIndex == -1) {
111
112
113 zoneIndex = s.indexOf('-', 8);
114 }
115 }
116 if(zoneIndex == -1) {
117
118 zoneIndex = s.length();
119 }
120
121
122 int endIndex;
123 if(s.lastIndexOf('.') == -1) {
124
125 endIndex = zoneIndex;
126 } else if(zoneIndex - s.lastIndexOf('.') > 3) {
127 endIndex = s.lastIndexOf('.') + 4;
128 } else {
129 endIndex = zoneIndex;
130 }
131 String out = s.substring(0, endIndex);
132
133
134
135 if(zoneIndex - s.lastIndexOf('.') == 3) {
136 out += "0";
137 } else if(zoneIndex - s.lastIndexOf('.') == 2) {
138 out += "00";
139 } else if(zoneIndex - s.lastIndexOf('.') == 1) {
140 out += "000";
141 }
142
143
144 if(out.indexOf('T') == 7) {
145 out = out.replace('T', 'J');
146 }
147 if(zoneIndex == s.length()) {
148
149 out += "GMT";
150
151
152 } else if(s.charAt(zoneIndex) == 'Z') {
153
154 out += "GMT";
155 } else {
156 String tzString = s.substring(zoneIndex);
157 if(tzString.length() == 3) {
158
159
160
161 tzString += ":00";
162 }
163 out += "GMT" + tzString;
164 }
165 return out;
166 }
167
168 protected MicroSecondDate date;
169
170 protected String orig;
171
172 public String getOrigString() {
173 return orig;
174 }
175
176 /***
177 * Get a java.unil.Calendar object initialized to be this ISOTime. Note that
178 * a reduction of precision may occur as the default GregorianCalendar only
179 * supports millisecond precision.
180 */
181 public Calendar getCalendar() {
182 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
183 cal.setTime(date);
184 return cal;
185 }
186
187 public MicroSecondDate getDate() {
188 return date;
189 }
190
191 public static String getISOString(MicroSecondDate ms) {
192 SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss.SSS");
193 df.setTimeZone(TimeZone.getTimeZone("GMT"));
194 String s = df.format(ms);
195 long micros = ms.getMicroSeconds();
196 if(micros == 0) {
197
198 } else if(micros < 10) {
199 s += "00" + micros;
200 } else if(micros < 100) {
201 if(micros % 10 == 0) {
202 s += "0" + (micros % 10);
203 } else {
204 s += "0" + micros;
205 }
206 } else {
207 if(micros % 100 == 0) {
208 s += micros % 100;
209 } else if(micros % 10 == 0) {
210 s += micros % 10;
211 } else {
212 s += micros;
213 }
214 }
215 return s + "Z";
216 }
217
218 public static String getISOString(Date ms) {
219 if(ms instanceof MicroSecondDate) { return getISOString((MicroSecondDate)ms); }
220 SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss.SSSz");
221 df.setTimeZone(TimeZone.getTimeZone("GMT"));
222 return df.format(ms);
223 }
224
225 public String toString() {
226 java.text.DateFormat df = java.text.DateFormat.getDateTimeInstance(java.text.DateFormat.FULL,
227 java.text.DateFormat.FULL);
228 df.setTimeZone(TimeZone.getTimeZone("GMT"));
229 return df.format(getCalendar().getTime());
230
231
232 }
233
234 /***
235 * just for testing, parses and outputs a few ISO8601 strings.
236 */
237 public static void main(String[] args) {
238 String[] s = {"19990101T120030.1111Z",
239 "1999-01-01T000030.1111Z",
240 "19990101T00:00:30.1111Z",
241 "1999-01-01T00:00:30.1111Z",
242 "1999001T00:00:30.1111Z",
243 "1999001T000030.1111Z",
244 "1999-12-21T00:00:30.1234Z",
245 "2048-01-01T16:00:30.1111+01",
246 "1999-01-01T00:59:30.1111+01:30",
247 "1999-01-01T23:59:59.999-01:30",
248 "19990101T120030Z"};
249 try {
250 for(int i = 0; i < s.length; i++) {
251 ISOTime iso = new ISOTime(s[i]);
252 System.out.println(iso + " = " + iso.getOrigString());
253 }
254 System.out.println(ISOTime.getISOString(1999, 1, 2, 3, 3.456f));
255 } catch(Exception e) {
256 System.out.println(e);
257 e.printStackTrace();
258 }
259 }
260 }