]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/data/Timestamp.java
ddb380818fc45d091c92ccd57111b5ae40d34eee
[GpsPrune.git] / tim / prune / data / Timestamp.java
1 package tim.prune.data;
2
3 import java.text.DateFormat;
4 import java.text.ParseException;
5 import java.text.SimpleDateFormat;
6 import java.util.Calendar;
7 import java.util.Date;
8
9 /**
10  * Class to hold the timestamp of a track point
11  * and provide conversion functions
12  */
13 public class Timestamp
14 {
15         private boolean _valid = false;
16         private long _seconds = 0L;
17         private String _text = null;
18
19         private static DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateTimeInstance();
20         private static DateFormat[] ALL_DATE_FORMATS = null;
21         private static Calendar CALENDAR = null;
22         private static long SECS_SINCE_1970 = 0L;
23         private static long SECS_SINCE_GARTRIP = 0L;
24         private static long MSECS_SINCE_1970 = 0L;
25         private static long MSECS_SINCE_1990 = 0L;
26         private static long TWENTY_YEARS_IN_SECS = 0L;
27
28         private static final long GARTRIP_OFFSET = 631065600L;
29
30         // Static block to initialise offsets
31         static
32         {
33                 CALENDAR = Calendar.getInstance();
34                 MSECS_SINCE_1970 = CALENDAR.getTimeInMillis();
35                 SECS_SINCE_1970 = MSECS_SINCE_1970 / 1000L;
36                 SECS_SINCE_GARTRIP = SECS_SINCE_1970 - GARTRIP_OFFSET;
37                 CALENDAR.add(Calendar.YEAR, -20);
38                 MSECS_SINCE_1990 = CALENDAR.getTimeInMillis();
39                 TWENTY_YEARS_IN_SECS = (MSECS_SINCE_1970 - MSECS_SINCE_1990) / 1000L;
40                 // Date formats
41                 ALL_DATE_FORMATS = new DateFormat[] {
42                         DEFAULT_DATE_FORMAT,
43                         new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy"),
44                         new SimpleDateFormat("HH:mm:ss dd MMM yyyy"),
45                         new SimpleDateFormat("dd MMM yyyy HH:mm:ss"),
46                         new SimpleDateFormat("yyyy MMM dd HH:mm:ss")
47                 };
48         }
49
50
51         /**
52          * Constructor
53          */
54         public Timestamp(String inString)
55         {
56                 // TODO: Does it really help to store timestamps in seconds rather than ms?
57                 if (inString != null && !inString.equals(""))
58                 {
59                         // Try to parse into a long
60                         try
61                         {
62                                 long rawValue = Long.parseLong(inString.trim());
63                                 // check for each format possibility and pick nearest
64                                 long diff1 = Math.abs(SECS_SINCE_1970 - rawValue);
65                                 long diff2 = Math.abs(MSECS_SINCE_1970 - rawValue);
66                                 long diff3 = Math.abs(MSECS_SINCE_1990 - rawValue);
67                                 long diff4 = Math.abs(SECS_SINCE_GARTRIP - rawValue);
68
69                                 // Start off with "seconds since 1970" format
70                                 long smallestDiff = diff1;
71                                 _seconds = rawValue;
72                                 // Now check millis since 1970
73                                 if (diff2 < smallestDiff)
74                                 {
75                                         // milliseconds since 1970
76                                         _seconds = rawValue / 1000L;
77                                         smallestDiff = diff2;
78                                 }
79                                 // Now millis since 1990
80                                 if (diff3 < smallestDiff)
81                                 {
82                                         // milliseconds since 1990
83                                         _seconds = rawValue / 1000L + TWENTY_YEARS_IN_SECS;
84                                         smallestDiff = diff3;
85                                 }
86                                 // Lastly, check garmin offset
87                                 if (diff4 < smallestDiff)
88                                 {
89                                         // seconds since garmin offset
90                                         _seconds = rawValue + GARTRIP_OFFSET;
91                                 }
92                                 _valid = true;
93                         }
94                         catch (NumberFormatException nfe)
95                         {
96                                 // String is not a long, so try a date/time string instead
97                                 // try each of the date formatters in turn
98                                 Date date = null;
99                                 for (int i=0; i<ALL_DATE_FORMATS.length && !_valid; i++)
100                                 {
101                                         try
102                                         {
103                                                 date = ALL_DATE_FORMATS[i].parse(inString);
104                                                 CALENDAR.setTime(date);
105                                                 _seconds = CALENDAR.getTimeInMillis() / 1000L;
106                                                 _valid = true;
107                                         }
108                                         catch (ParseException e) {}
109                                 }
110                         }
111                 }
112         }
113
114
115         /**
116          * Constructor giving each field value individually
117          * @param inYear year
118          * @param inMonth month, beginning with 1
119          * @param inDay day of month, beginning with 1
120          * @param inHour hour of day, 0-24
121          * @param inMinute minute
122          * @param inSecond seconds
123          */
124         public Timestamp(int inYear, int inMonth, int inDay, int inHour, int inMinute, int inSecond)
125         {
126                 Calendar cal = Calendar.getInstance();
127                 cal.set(Calendar.YEAR, inYear);
128                 cal.set(Calendar.MONTH, inMonth - 1);
129                 cal.set(Calendar.DAY_OF_MONTH, inDay);
130                 cal.set(Calendar.HOUR_OF_DAY, inHour);
131                 cal.set(Calendar.MINUTE, inMinute);
132                 cal.set(Calendar.SECOND, inSecond);
133                 cal.set(Calendar.MILLISECOND, 0);
134                 _seconds = cal.getTimeInMillis() / 1000;
135                 _valid = true;
136         }
137
138
139         /**
140          * Constructor giving millis since 1970
141          * @param inMillis
142          */
143         public Timestamp(long inMillis)
144         {
145                 _seconds = inMillis / 1000;
146                 _valid = true;
147         }
148
149
150         /**
151          * @return true if timestamp is valid
152          */
153         public boolean isValid()
154         {
155                 return _valid;
156         }
157
158
159         /**
160          * Calculate the difference between two Timestamps in seconds
161          * @param inOther other, earlier Timestamp
162          * @return number of seconds since other timestamp
163          */
164         public long getSecondsSince(Timestamp inOther)
165         {
166                 return _seconds - inOther._seconds;
167         }
168
169
170         /**
171          * @return Description of timestamp in locale-specific format
172          */
173         public String getText()
174         {
175                 if (_text == null)
176                 {
177                         if (_valid)
178                         {
179                                 CALENDAR.setTimeInMillis(_seconds * 1000L);
180                                 _text = DEFAULT_DATE_FORMAT.format(CALENDAR.getTime());
181                         }
182                         else _text = "";
183                 }
184                 return _text;
185         }
186 }