Skip to content
Snippets Groups Projects
Commit 18f259d0 authored by Brutzman, Don's avatar Brutzman, Don
Browse files

change epochLvc to java.time.Instant

parent 8b5df70e
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;
/**
......@@ -75,7 +76,7 @@ import java.util.*;
* rollover, instead getting only a monotonically increasing timestamp value.</p>
*
* <p><b>TODO: timestamp normalization to an initial reference time.</b>
* Functionality is needed to define a shared common time origin (epoch) and also to
* Functionality is needed to define a shared common time origin (epochLvc) and also to
* precisely adjust stream timestamps when coordinating recorded PDU playback within LVC applications.
* We think the ability to "start at time 0.0", or normalizing initial time to zero
* for a recorded PDU stream, is actually a pretty common use case.
......@@ -121,11 +122,18 @@ public class DisTime
*/
private static boolean hostClockSynchronized = true;
/** Reference starting time for current timestamps
/** Whether to apply epochLvc as baseline starting time for DIS timestamps, enabling time normalization of LVC streams.
* Distinct from Unix timestamp EPOCH.
* <a href="https://en.wikipedia.org/wiki/Epoch_(computing)" target="_blank">https://en.wikipedia.org/wiki/Epoch_(computing)</a>.
*/
private static int epoch = 0;
private static boolean applyEpochLvc = false;
/** Reference starting time for current DIS timestamps, enabling time normalization of LVC streams.
* Distinct from Unix timestamp EPOCH.
* <a href="https://en.wikipedia.org/wiki/Epoch_(computing)" target="_blank">https://en.wikipedia.org/wiki/Epoch_(computing)</a>.
*/
private static Instant epochLvc = Instant.now(); // initialized at start
/** We can marshal the PDU with a timestamp set to any of several styles.
* Remember, you MUST set a timestamp. DIS will regard multiple packets sent
* with the same timestamp as duplicates and may discard them.
......@@ -141,8 +149,11 @@ public class DisTime
/** calendar instance */
private static GregorianCalendar calendar;
// private LocalDateTime todayDateTime = new LocalDateTime();
// private Instant todayInstant = new Instant();
private static String dateFormatPattern = "HH:mm:ss";
private static String dateFormatPattern = "yyyy-mm-dd";
private static String timeFormatPattern = "HH:mm:ss";
// public static DisTime disTime = null;
......@@ -167,7 +178,7 @@ public class DisTime
/**
* For current system time, returns the number of DIS time units since the top of the hour, or else
* number of DIS time units since previously set epoch timestamp (for time-zero-based streams).
* number of DIS time units since previously set epochLvc timestamp (for time-zero-based streams).
* Note that there are 2^31-1 DIS time units per hour.
* @return integer DIS time units since the start of the hour.
*/
......@@ -194,13 +205,14 @@ public class DisTime
double differenceValue;
int differenceTimestamp;
if (epoch == 0)
if (!hasEpochLvc())
{
timeDifferenceMsec = currentTime - topOfHourMsec;
}
else // normalized time reference having 00:00 at start
{
timeDifferenceMsec = currentTime - epoch;
Duration d = java.time.Duration.between(epochLvc, Instant.now());
timeDifferenceMsec = d.toMillis();
}
differenceValue = (timeDifferenceMsec / (3600.0 * 1000.0)) * Integer.MAX_VALUE;
differenceTimestamp = (int) differenceValue;
......@@ -292,7 +304,7 @@ public class DisTime
/**
* Convert timestamp value to string for logging and diagnostics,
* taking into account epoch and TimeStampStyle (DIS absolute/relative, Unix or Year).
* taking into account epochLvc and TimeStampStyle (DIS absolute/relative, Unix or Year).
* TODO consider different formats for different timestampStyle values.
* @param timestamp value in milliseconds
* @see GregorianCalendar
......@@ -302,13 +314,13 @@ public class DisTime
public static String convertToString(int timestamp)
{
GregorianCalendar newCalendar = new GregorianCalendar();
DateFormat formatter = new SimpleDateFormat(dateFormatPattern);
DateFormat formatter = new SimpleDateFormat(dateFormatPattern + " " + timeFormatPattern);
if ((timestampStyle == TimestampStyle.IEEE_ABSOLUTE) ||
(timestampStyle == TimestampStyle.IEEE_RELATIVE))
{
// if epoch is not set, this is regular DIS value
newCalendar.setTimeInMillis(timestamp - epoch);
// if epochLvc is not set, this is regular DIS value
newCalendar.setTimeInMillis(timestamp); // - epochLvc
return formatter.format(newCalendar.getTime());
}
else if (timestampStyle == TimestampStyle.UNIX) // TODO
......@@ -401,46 +413,95 @@ public class DisTime
return hostClockSynchronized;
}
/** Set epoch using current time for zero-based clock, meaning timestamps are normalized to "time zero" of simulation
/** Reset epochLvc using current time for zero-based clock, meaning timestamps are normalized to "time zero" of simulation
* as initial starting time
*/
public static void setEpochCurrentTimestamp()
public static void setEpochLvcNow()
{
setEpoch(getCurrentDisAbsoluteTimestamp());
applyEpochLvc = true;
setEpochLvc(Instant.now()); // getCurrentDisAbsoluteTimestamp());
}
/** Set initial timestamp as epoch for zero-based clock, meaning timestamps normalized to 0 as initial starting time
* @param initialTimestamp first timestamp in series, considered time zero
/** Set Instant value as epochLvc for zero-based clock, meaning timestamps normalized to 0 at that initial starting time
* @param newEpoch Instant corresponding to first PDU in series, considered time zero
*/
public static void setEpoch(int initialTimestamp)
public static void setEpochLvc(java.time.Instant newEpoch)
{
epoch = initialTimestamp;
epochLvc = newEpoch;
}
/** Get initial timestamp for zero-based clock, meaning all timestamps are measured with resepct to given starting time
/** Get initial timestamp for zero-based clock, meaning all timestamps are measured with respect to given starting time
* @return whether localhost is synchronized to time reference
*/
public static int getEpoch()
public static java.time.Instant getEpochLvc()
{
return epochLvc;
}
/** Whether epochLvc is currently applied
* @return whether epochLvc is active
*/
public static boolean hasEpochLvc()
{
return applyEpochLvc;
}
/** Reset epochLvc so it is no longer active
*/
public static void clearEpochLvc()
{
return epoch;
applyEpochLvc = false;
}
private void sleep(long ms) {
sleep(ms, 0);
}
private void sleep(long ms, int ns)
{
try {
Thread.sleep(ms, ns);
}
catch (InterruptedException ex) {}
}
/** Self-test for basic smoke testing */
private void selfTest()
{
DisTime.initializeTimestampMethod();
System.out.println("=== legacy java.util.Date, calendar methods ===");
System.out.println("DisTime.getTimestampStyle() = " + DisTime.getTimestampStyle());
System.out.println(" = " + dateFormatPattern);
System.out.println("patterns = " + dateFormatPattern + " " + timeFormatPattern);
int initialTimestamp = DisTime.getTimestamp();
System.out.println("DisTime.getTimestamp() initialTimestamp = " + convertToString(initialTimestamp) + " = " + Integer.toUnsignedString(initialTimestamp) + " = " + initialTimestamp + " (unsigned vs signed output)");
System.out.println("DisTime.getTimestamp() = " + convertToString(DisTime.getTimestamp()) + " = " + Integer.toUnsignedString(DisTime.getTimestamp()) + " = " + DisTime.getTimestamp()+ " (unsigned vs signed output)");
System.out.println("DisTime.getCurrentDisAbsoluteTimestamp() = " + convertToString(DisTime.getCurrentDisAbsoluteTimestamp()) + " = " + Integer.toUnsignedString(DisTime.getCurrentDisAbsoluteTimestamp()));
System.out.println("DisTime.getCurrentDisRelativeTimestamp() = " + convertToString(DisTime.getCurrentDisRelativeTimestamp()) + " = " + Integer.toUnsignedString(DisTime.getCurrentDisRelativeTimestamp()));
System.out.println("DisTime.getCurrentDisTimeUnitsSinceTopOfHour() = " + convertToString(DisTime.getCurrentDisTimeUnitsSinceTopOfHour()) + " = " + DisTime.getCurrentDisTimeUnitsSinceTopOfHour());
System.out.println("DisTime.getEpoch() = " + convertToString(DisTime.getEpoch()) + " = " + DisTime.getEpoch());
setEpochCurrentTimestamp();
System.out.println("DisTime.setEpochCurrentTimestamp();");
System.out.println("DisTime.getEpoch() = " + convertToString(DisTime.getEpoch()) + " = " + DisTime.getEpoch());
System.out.println("DisTime.getCurrentDisTimeUnitsSinceTopOfHour() = " + convertToString(DisTime.getCurrentDisTimeUnitsSinceTopOfHour()) + " = " + DisTime.getCurrentDisTimeUnitsSinceTopOfHour());
}
System.out.println();
System.out.println("=== modern java.time methods ===");
System.out.println("note that LocalDateTime is current time zone while default Instant is UTC with time zone Z appended");
System.out.println("java.time.LocalDateTime.now(), Instant.now() = " + java.time.LocalDateTime.now() + ", " + java.time.Instant.now());
System.out.println("java.time.LocalDateTime.now(), Instant.now() = " + java.time.LocalDateTime.now() + ", " + java.time.Instant.now());
System.out.println("java.time.LocalDateTime.now(), Instant.now() = " + java.time.LocalDateTime.now() + ", " + java.time.Instant.now());
System.out.println("sleep for 1000 msec...");
sleep(1000l); // hold on a second
System.out.println("java.time.LocalDateTime.now(), Instant.now() = " + java.time.LocalDateTime.now() + ", " + java.time.Instant.now());
System.out.println("java.time.LocalDateTime.now(), Instant.now() = " + java.time.LocalDateTime.now() + ", " + java.time.Instant.now());
System.out.println("java.time.LocalDateTime.now(), Instant.now() = " + java.time.LocalDateTime.now() + ", " + java.time.Instant.now());
System.out.println("DisTime.hasEpochLvc() = " + DisTime.hasEpochLvc());
System.out.println("DisTime.setEpochLvcNow()...");
setEpochLvcNow();
System.out.println("DisTime.hasEpochLvc(), = " + DisTime.hasEpochLvc());
Instant now = Instant.now();
System.out.println("DisTime.getEpochLvc(), Instant.now(), duration = " + DisTime.getEpochLvc() + ", " + now + ", " +
java.time.Duration.between(getEpochLvc(), now).toMillis() + " msec");
System.out.println("sleep for 1000 msec...");
sleep(1000l); // hold on a second
now = Instant.now();
System.out.println("DisTime.getEpochLvc(), Instant.now(), duration = " + DisTime.getEpochLvc() + ", " + now + ", " +
java.time.Duration.between(getEpochLvc(), now).toMillis() + " msec");
// System.out.println("DisTime.getCurrentDisTimeUnitsSinceTopOfHour() = " + convertToString(DisTime.getCurrentDisTimeUnitsSinceTopOfHour()) + " = " + DisTime.getCurrentDisTimeUnitsSinceTopOfHour());
}
/**
* Main method for testing.
......
......@@ -7,15 +7,29 @@ Compiling 1 source file to C:\x3d-github\open-dis7-java\build\classes
compile-single:
run-single:
*** DisTime.main() self test started...
=== legacy java.util.Date, calendar methods ===
DisTime.getTimestampStyle() = IEEE_ABSOLUTE
DisTime.getTimestamp() initialTimestamp = 08:52:40 = 1011160571 = 1011160571 (unsigned vs signed output)
DisTime.getTimestamp() = 08:52:59 = 1011180853 = 1011180853 (unsigned vs signed output)
DisTime.getCurrentDisAbsoluteTimestamp() = 08:53:00 = 1011180853
DisTime.getCurrentDisRelativeTimestamp() = 08:53:03 = 1011184430
DisTime.getCurrentDisTimeUnitsSinceTopOfHour() = 12:26:32 = 505592215
DisTime.getEpoch() = 16:00:00 = 0
DisTime.setEpochCurrentTimestamp();
DisTime.getEpoch() = 16:00:00 = 1011184431
DisTime.getCurrentDisTimeUnitsSinceTopOfHour() = 19:38:19 = 2147483647
patterns = yyyy-mm-dd HH:mm:ss
DisTime.getTimestamp() initialTimestamp = 1970-10-02 08:10:52 = 144652113 = 144652113 (unsigned vs signed output)
DisTime.getTimestamp() = 1970-11-02 08:11:01 = 144662849 = 144662849 (unsigned vs signed output)
DisTime.getCurrentDisAbsoluteTimestamp() = 1970-11-02 08:11:02 = 144662849
DisTime.getCurrentDisRelativeTimestamp() = 1970-11-02 08:11:02 = 144662848
DisTime.getCurrentDisTimeUnitsSinceTopOfHour() = 1970-05-01 12:05:31 = 72331424
=== modern java.time methods ===
note that LocalDateTime is current time zone while default Instant is UTC with time zone Z appended
java.time.LocalDateTime.now(), Instant.now() = 2022-01-23T20:02:01.267763900, 2022-01-24T04:02:01.269764Z
java.time.LocalDateTime.now(), Instant.now() = 2022-01-23T20:02:01.270748500, 2022-01-24T04:02:01.270748500Z
java.time.LocalDateTime.now(), Instant.now() = 2022-01-23T20:02:01.271426100, 2022-01-24T04:02:01.271426100Z
sleep for 1000 msec...
java.time.LocalDateTime.now(), Instant.now() = 2022-01-23T20:02:02.277595700, 2022-01-24T04:02:02.277595700Z
java.time.LocalDateTime.now(), Instant.now() = 2022-01-23T20:02:02.277735400, 2022-01-24T04:02:02.277735400Z
java.time.LocalDateTime.now(), Instant.now() = 2022-01-23T20:02:02.277735400, 2022-01-24T04:02:02.277735400Z
DisTime.hasEpochLvc() = false
DisTime.setEpochLvcNow()...
DisTime.hasEpochLvc(), = true
DisTime.getEpochLvc(), Instant.now(), duration = 2022-01-24T04:02:02.279866100Z, 2022-01-24T04:02:02.279866100Z, 0 msec
sleep for 1000 msec...
DisTime.getEpochLvc(), Instant.now(), duration = 2022-01-24T04:02:02.279866100Z, 2022-01-24T04:02:03.289787Z, 1009 msec
*** DisTime.main() self test complete.
BUILD SUCCESSFUL (total time: 0 seconds)
BUILD SUCCESSFUL (total time: 2 seconds)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment