1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.oodt.commons.date;
20
21
22 import java.text.DecimalFormat;
23 import java.text.ParseException;
24 import java.text.SimpleDateFormat;
25 import java.util.Calendar;
26 import java.util.GregorianCalendar;
27 import java.util.SimpleTimeZone;
28 import java.util.TimeZone;
29
30
31
32
33
34
35
36 public class DateUtils {
37
38 public static enum FormatType { UTC_FORMAT, LOCAL_FORMAT, TAI_FORMAT };
39
40 public static Calendar tai93epoch = new GregorianCalendar(1993, GregorianCalendar.JANUARY, 1);
41
42 public static Calendar julianEpoch = new GregorianCalendar(1970, GregorianCalendar.JANUARY, 1);
43
44 private static SimpleDateFormat utcFormat = new SimpleDateFormat(
45 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
46 private static SimpleDateFormat taiFormat = new SimpleDateFormat(
47 "yyyy-MM-dd'T'HH:mm:ss.SSS");
48 private static SimpleDateFormat localFormat = new SimpleDateFormat(
49 "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
50
51 static {
52 utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
53 taiFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
54 }
55
56 static enum IndexType {
57 DATE(0),
58 LEAP_SECS(1);
59
60 public int index;
61
62 IndexType(int index) {
63 this.index = index;
64 }
65 }
66
67
68 static long[][] dateAndLeapSecs = {
69 { 0 , 10 },
70 { new GregorianCalendar(1972, GregorianCalendar.JULY, 1).getTimeInMillis() , 11 },
71 { new GregorianCalendar(1973, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 12 },
72 { new GregorianCalendar(1974, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 13 },
73 { new GregorianCalendar(1975, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 14 },
74 { new GregorianCalendar(1976, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 15 },
75 { new GregorianCalendar(1977, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 16 },
76 { new GregorianCalendar(1978, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 17 },
77 { new GregorianCalendar(1979, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 18 },
78 { new GregorianCalendar(1980, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 19 },
79 { new GregorianCalendar(1981, GregorianCalendar.JULY, 1).getTimeInMillis() , 20 },
80 { new GregorianCalendar(1982, GregorianCalendar.JULY, 1).getTimeInMillis() , 21 },
81 { new GregorianCalendar(1983, GregorianCalendar.JULY, 1).getTimeInMillis() , 22 },
82 { new GregorianCalendar(1985, GregorianCalendar.JULY, 1).getTimeInMillis() , 23 },
83 { new GregorianCalendar(1988, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 24 },
84 { new GregorianCalendar(1990, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 25 },
85 { new GregorianCalendar(1991, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 26 },
86 { new GregorianCalendar(1992, GregorianCalendar.JULY, 1).getTimeInMillis() , 27 },
87 { new GregorianCalendar(1993, GregorianCalendar.JULY, 1).getTimeInMillis() , 28 },
88 { new GregorianCalendar(1994, GregorianCalendar.JULY, 1).getTimeInMillis() , 29 },
89 { new GregorianCalendar(1996, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 30 },
90 { new GregorianCalendar(1997, GregorianCalendar.JULY, 1).getTimeInMillis() , 31 },
91 { new GregorianCalendar(1999, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 32 },
92 { new GregorianCalendar(2006, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 33 },
93 { new GregorianCalendar(2009, GregorianCalendar.JANUARY, 1).getTimeInMillis() , 34 },
94 };
95
96 private DateUtils() {}
97
98 public static int getLeapSecsForDate(Calendar utcCal) throws Exception {
99 long timeInMillis = utcCal.getTimeInMillis();
100 for (int i = dateAndLeapSecs.length - 1; i >= 0; i--) {
101 if (dateAndLeapSecs[i][IndexType.DATE.index] < timeInMillis)
102 return (int) dateAndLeapSecs[i][IndexType.LEAP_SECS.index];
103 }
104 throw new Exception("No Leap Second found for given date!");
105 }
106
107 public static synchronized Calendar toTai(Calendar cal) throws Exception {
108 Calendar taiCal = Calendar.getInstance(createTaiTimeZone(getLeapSecsForDate(cal)));
109 taiCal.setTimeInMillis(cal.getTimeInMillis() + getLeapSecsForDate(cal) * 1000);
110 return taiCal;
111 }
112
113 private static synchronized Calendar taiToUtc(Calendar taiCal) throws Exception {
114 Calendar calUtc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
115 calUtc.setTimeInMillis(taiCal.getTimeInMillis() - taiCal.getTimeZone().getRawOffset());
116 return calUtc;
117 }
118
119 private static Calendar taiToLocal(Calendar taiCal) throws Exception {
120 return toLocal(taiToUtc(taiCal));
121 }
122
123 public static synchronized Calendar toLocal(Calendar cal) throws Exception {
124 if (cal.getTimeZone().getID().equals("TAI")) {
125 return taiToLocal(cal);
126 } else {
127 Calendar calLocal = Calendar.getInstance();
128 calLocal.setTimeInMillis(cal.getTimeInMillis());
129 return calLocal;
130 }
131 }
132
133 public static synchronized Calendar toUtc(Calendar cal) throws Exception {
134 if (cal.getTimeZone().getID().equals("TAI")) {
135 return taiToUtc(cal);
136 } else {
137 Calendar calUtc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
138 calUtc.setTimeInMillis(cal.getTimeInMillis());
139 return calUtc;
140 }
141 }
142
143 public static Calendar getCurrentUtcTime() throws Exception {
144 return toUtc(getCurrentLocalTime());
145 }
146
147 public static Calendar getCurrentLocalTime() throws Exception {
148 return Calendar.getInstance();
149 }
150
151 public static Calendar getCurrentTaiTime() throws Exception {
152 return toTai(getCurrentUtcTime());
153 }
154
155 public static String toCustomLocalFormat(Calendar cal, String format) {
156 return new SimpleDateFormat(format).format(cal.getTime());
157 }
158
159 public static String toString(Calendar cal) {
160 String timeZoneId = cal.getTimeZone().getID();
161 if (timeZoneId.equals("UTC")) {
162 return utcFormat.format(cal.getTime());
163 }else if (timeZoneId.equals("TAI")) {
164 return taiFormat.format(cal.getTime()) + "-0000"
165 + (cal.getTimeZone().getRawOffset() / 1000);
166 }else {
167 return localFormat.format(cal.getTime());
168 }
169 }
170
171 public static synchronized Calendar toLocalCustomFormatCalendar(String calString, String format) throws ParseException {
172 Calendar localCal = Calendar.getInstance();
173 localCal.setTime(new SimpleDateFormat(format).parse(calString));
174 return localCal;
175 }
176
177 public static synchronized Calendar toCalendar(String calString, FormatType formatType)
178 throws ParseException {
179 Calendar cal = Calendar.getInstance();
180 switch (formatType) {
181 case LOCAL_FORMAT:
182 cal.setTimeInMillis(localFormat.parse(calString).getTime());
183 break;
184 case TAI_FORMAT:
185 cal.setTimeZone(createTaiTimeZone(Integer.parseInt(calString
186 .substring(calString.length() - 2))));
187 calString = calString.substring(0, calString.length() - 5);
188 cal.setTimeInMillis(taiFormat.parse(calString).getTime());
189 break;
190 case UTC_FORMAT:
191 cal.setTimeZone(TimeZone.getTimeZone("UTC"));
192 cal.setTimeInMillis(utcFormat.parse(calString).getTime());
193 break;
194 default:
195 cal.setTimeInMillis(localFormat.parse(calString).getTime());
196 }
197 return cal;
198 }
199
200 public static double getTimeInSecs(Calendar cal, Calendar epoch) throws Exception {
201 return getTimeInMillis(cal, epoch) / 1000.0;
202 }
203
204 public static String toString(double seconds) {
205 return new DecimalFormat("#.000").format(seconds);
206 }
207
208 public static long getTimeInMillis(Calendar cal, Calendar epoch) throws Exception {
209 long epochDiffInMilli;
210
211
212
213 if(julianEpoch.getTimeZone().getID().equals("Europe/London")){
214 epochDiffInMilli = epoch.getTimeInMillis() - (julianEpoch.getTimeInMillis()+julianEpoch.getTimeZone().getOffset(julianEpoch.getTimeInMillis())) ;
215 }else {
216 epochDiffInMilli = epoch.getTimeInMillis() - julianEpoch.getTimeInMillis() ;
217 }
218 if (cal.getTimeZone().getID().equals("TAI"))
219 epochDiffInMilli += getLeapSecsForDate(epoch) * 1000;
220 long milliseconds = cal.getTimeInMillis();
221 return milliseconds - epochDiffInMilli;
222 }
223
224 private static TimeZone createTaiTimeZone(int leapSecs) {
225 return new SimpleTimeZone(leapSecs * 1000, "TAI");
226 }
227
228 public static void main(String[] args) throws Exception {
229 Calendar curTime = getCurrentLocalTime();
230 System.out.println("Test Time: " + toString(toCalendar(toString(toTai(toCalendar("2008-01-20T16:29:55.000Z",
231 FormatType.UTC_FORMAT))), FormatType.TAI_FORMAT)));
232 System.out.println("Current Local Time: " + toString(curTime) + " " + curTime.getTimeInMillis());
233 System.out.println("Current UTC Time: " + toString((curTime = toCalendar("2008-01-20T16:29:55.000Z",
234 FormatType.UTC_FORMAT))) + " " + toString(getTimeInSecs(curTime, tai93epoch)));
235 System.out.println("Current TAI Time: " + toString((curTime = toTai(toCalendar("2008-01-20T16:29:55.000Z",
236 FormatType.UTC_FORMAT)))) + " " + toString(getTimeInSecs(curTime, tai93epoch)));
237 System.out.println("Current UTC Time: " + toString(taiToUtc(curTime)));
238 }
239
240 }