]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/data/Timestamp.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / data / Timestamp.java
diff --git a/src/tim/prune/data/Timestamp.java b/src/tim/prune/data/Timestamp.java
new file mode 100644 (file)
index 0000000..ac144bb
--- /dev/null
@@ -0,0 +1,193 @@
+package tim.prune.data;
+
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+
+/**
+ * Superclass of all timestamp implementations
+ */
+public abstract class Timestamp
+{
+       private static final DateFormat DEFAULT_DATE_FORMAT = DateFormat.getDateInstance();
+       private static final DateFormat DEFAULT_TIME_FORMAT = DateFormat.getTimeInstance();
+
+       protected static final DateFormat DEFAULT_DATETIME_FORMAT = DateFormat.getDateTimeInstance();
+
+       protected static final DateFormat ISO_8601_FORMAT
+               = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+       protected static final DateFormat ISO_8601_FORMAT_WITH_MILLIS
+               = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+
+       private static boolean MillisAddedToTimeFormat = false;
+
+
+       /** Possible formats for parsing and displaying timestamps */
+       public enum Format
+       {
+               ORIGINAL,
+               LOCALE,
+               ISO8601
+       }
+
+
+       // Static block to initialise date formats
+       static
+       {
+               // Set timezone for output
+               TimeZone gmtZone = TimeZone.getTimeZone("GMT");
+               ISO_8601_FORMAT.setTimeZone(gmtZone);
+               ISO_8601_FORMAT_WITH_MILLIS.setTimeZone(gmtZone);
+               DEFAULT_DATETIME_FORMAT.setTimeZone(gmtZone);
+       }
+
+
+       /**
+        * @return true if valid
+        */
+       public abstract boolean isValid();
+
+       /**
+        * Get a calendar representing this timestamp
+        */
+       public abstract Calendar getCalendar(TimeZone inZone);
+
+       /**
+        * @return the milliseconds according to the given timezone
+        */
+       public abstract long getMilliseconds(TimeZone inZone);
+
+       /**
+        * @return true if this timestamp is after the other one
+        */
+       public boolean isAfter(Timestamp inOther)
+       {
+               return getMillisecondsSince(inOther) > 0;
+       }
+
+       /**
+        * @return true if this timestamp is before the other one
+        */
+       public boolean isBefore(Timestamp inOther)
+       {
+               return getMillisecondsSince(inOther) < 0;
+       }
+
+       /**
+        * @return true if this timestamp is equal to the other one
+        */
+       public boolean isEqual(Timestamp inOther)
+       {
+               return getMillisecondsSince(inOther) == 0;
+       }
+
+       /**
+        * @return the number of seconds since the other timestamp
+        */
+       public long getSecondsSince(Timestamp inOther)
+       {
+               return getMillisecondsSince(inOther) / 1000L;
+       }
+
+       /**
+        * Calculate the difference between two Timestamps in milliseconds
+        * @param inOther other, earlier Timestamp
+        * @return number of milliseconds since other timestamp
+        */
+       public long getMillisecondsSince(Timestamp inOther)
+       {
+               return getMilliseconds(null) - inOther.getMilliseconds(null);
+       }
+
+       /**
+        * @return the number of seconds since the other timestamp using the given timezone
+        */
+       public long getSecondsSince(Timestamp inOther, TimeZone inTimezone)
+       {
+               return (getMilliseconds(inTimezone) - inOther.getMilliseconds(inTimezone)) / 1000L;
+       }
+
+       /**
+        * Add the given number of seconds offset
+        * @param inOffset number of seconds to add/subtract
+        */
+       public abstract void addOffsetSeconds(long inOffset);
+
+       /**
+        * @return true if the timestamp has non-zero milliseconds
+        */
+       protected abstract boolean hasMilliseconds();
+
+
+       /**
+        * @return date part of timestamp in locale-specific format
+        */
+       public String getDateText(TimeZone inTimezone)
+       {
+               if (!isValid()) return "";
+               return format(DEFAULT_DATE_FORMAT, inTimezone);
+       }
+
+       /**
+        * @return Description of time part of timestamp in locale-specific format
+        */
+       public String getTimeText(TimeZone inTimezone)
+       {
+               if (!isValid()) return "";
+               // Maybe we should add milliseconds to this format?
+               if (hasMilliseconds() && !MillisAddedToTimeFormat)
+               {
+                       try
+                       {
+                               SimpleDateFormat sdf = (SimpleDateFormat) DEFAULT_TIME_FORMAT;
+                               String pattern = sdf.toPattern();
+                               if (pattern.indexOf("ss") > 0 && pattern.indexOf("SS") < 0)
+                               {
+                                       sdf.applyPattern(pattern.replaceFirst("s+", "$0.SSS"));
+                                       MillisAddedToTimeFormat = true;
+                               }
+                       }
+                       catch (ClassCastException cce) {}
+               }
+               return format(DEFAULT_TIME_FORMAT, inTimezone);
+       }
+
+       /**
+        * Utility method for formatting dates / times
+        */
+       protected abstract String format(DateFormat inFormat, TimeZone inTimezone);
+
+
+       /**
+        * @return Description of timestamp in locale-specific format
+        */
+       public String getText(TimeZone inTimezone)
+       {
+               return getText(Format.LOCALE, inTimezone);
+       }
+
+       /**
+        * @param inFormat format of timestamp
+        * @return Description of timestamp in required format
+        */
+       public String getText(Format inFormat, TimeZone inTimezone)
+       {
+               if (!isValid()) {
+                       return "";
+               }
+               switch (inFormat)
+               {
+                       case ORIGINAL:
+                       case LOCALE:
+                       default:
+                               return format(DEFAULT_DATETIME_FORMAT, inTimezone);
+                       case ISO8601:
+                               return format(hasMilliseconds() ? ISO_8601_FORMAT_WITH_MILLIS : ISO_8601_FORMAT,
+                                       inTimezone);
+               }
+       }
+
+}