This class does not support the optional authentication protocol, and ignores the key ID and message digest fields.
For convenience, this class exposes message values as native Java types, not the NTP-specified data formats. For example, timestamps are stored as doubles (as opposed to the NTP unsigned 64-bit fixed point format).
However, the constructor NtpMessage(byte[]) and the method toByteArray() allow the import and export of the raw NTP message format.
Usage example
// Send message DatagramSocket socket = new DatagramSocket(); InetAddress address = InetAddress.getByName("ntp.cais.rnp.br"); byte[] buf = new NtpMessage().toByteArray(); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123); socket.send(packet);
// Get response socket.receive(packet); System.outprintln(msg.toString());
Comments for member variables are taken from RFC2030 by David Mills, University of Delaware.
Number format conversion code in NtpMessage(byte[] array) and toByteArray() inspired by the Jussieu networks course NTPMessage.java which is copyright (c) 2003 by Juliusz Chroboczek
Year 2036 compliance
Prior to 0.9.50, this supported years 1900-2035. As of 0.9.50, this supports years 1968-2104 and is year-2036 compliant. All double timestamps are the actual seconds since 1900. We use a "pivot" of January 1968. NTP-format dates before 1968 are converted to 2036+. So this code handles the last half of era 0 and the first half of era 1, i.e. 1968-2104. All math and comparisons on timestamps must be on the double values, never on the raw NTP-format byte arrays.
refs: https://docs.ntpsec.org/latest/rollover.html https://www.eecis.udel.edu/~mills/y2k.html https://www.eecis.udel.edu/~mills/time.html https://tools.ietf.org/html/rfc4330 sec. 3
Field Summary
Modifier and TypeFieldDescriptionprivate static final ThreadLocal<DateFormat> Returns a timestamp (number of seconds since 00:00 1-Jan-1900) as a formatted date/time string.byteThis is a two-bit code warning of an impending leap second to be inserted/deleted in the last minute of the current day.final byteThis value indicates the mode, with values defined as follows:doubleThis is the time at which the request departed the client for the server, in seconds since 00:00 1-Jan-1900.byteThis value indicates the maximum interval between successive messages, in seconds to the nearest power of two.byteThis value indicates the precision of the local clock, in seconds to the nearest power of two.doubleThis is the time at which the request arrived at the server, in seconds since 00:00 1-Jan-1900.final byte[]This is a 4-byte array identifying the particular reference source.doubleThis is the time at which the local clock was last set or corrected, in seconds since 00:00 1-Jan-1900.doubleThis value indicates the total roundtrip delay to the primary reference source, in seconds.doubleThis value indicates the nominal error relative to the primary reference source, in seconds.private static final doubleSeconds since Jan.private static final doubleSeconds in one NTP era: Feb.private static final doubleSeconds since Jan.shortThis value indicates the stratum level of the local clock, with values defined as follows:final doubleThis is the time at which the reply departed the server for the client, in seconds since 00:00 1-Jan-1900.byteThis value indicates the NTP/SNTP version number.Constructor Summary
ConstructorsConstructorDescriptionA client-mode NtpMessage with the transmit timestamp set to the current time.NtpMessage(byte[] array) Parses a new NtpMessage from an array of bytes.Method Summary
Modifier and TypeMethodDescriptionprivate static doubledecodeTimestamp(byte[] array, int pointer) Will read 8 bytes of a message beginning atpointerand return it as a double, according to the NTP 64-bit timestamp format.static voidencodeTimestamp(byte[] array, int pointer, double timestamp) Encodes a timestamp in the specified position in the message.Convert the reference identifier to a human-readable string.private static StringreferenceIdentifierToString(byte[] ref, short stratum, byte version) Returns a string representation of a reference identifier according to the rules set out in RFC 2030.private static StringtimestampToString(double timestamp) Formats an NTP timestamp for display.byte[]This method constructs the data bytes of a raw NTP packet.toString()Returns a string representation of a NtpMessage.private static shortunsignedByteToShort(byte b) Converts an unsigned byte to a short.
Field Details
SECONDS_PIVOT
private static final double SECONDS_PIVOTSeconds since Jan. 1 1900 at the pivot: Jan. 19, 1968, halfway through era 0, the earliest date we can handle, where dates switch from the 21st to the 20th century.- See Also:
SECONDS_ERA
private static final double SECONDS_ERASeconds in one NTP era: Feb. 8, 2036, the start of era 1.- See Also:
SECONDS_END
private static final double SECONDS_ENDSeconds since Jan. 1 1900 at the end: Feb. 26, 2104, halfway through era 1, the latest date we can handle, where dates switch back to the 21st century.- See Also:
leapIndicator
public byte leapIndicatorThis is a two-bit code warning of an impending leap second to be inserted/deleted in the last minute of the current day. Its values may be as follows:Value Meaning ----- ------- 0 no warning 1 last minute has 61 seconds 2 last minute has 59 seconds) 3 alarm condition (clock not synchronized).
version
public byte versionThis value indicates the NTP/SNTP version number. The version number is 3 for Version 3 (IPv4 only) and 4 for Version 4 (IPv4, IPv6 and OSI). If necessary to distinguish between IPv4, IPv6 and OSI, the encapsulating context must be inspected.mode
public final byte modeThis value indicates the mode, with values defined as follows:Mode Meaning ---- ------- 0 reserved 1 symmetric active 2 symmetric passive 3 client 4 server 5 broadcast 6 reserved for NTP control message 7 reserved for private use
In unicast and anycast modes, the client sets this field to 3 (client) in the request and the server sets it to 4 (server) in the reply. In multicast mode, the server sets this field to 5 (broadcast).
stratum
public short stratumThis value indicates the stratum level of the local clock, with values defined as follows:Stratum Meaning ---------------------------------------------- 0 unspecified or unavailable 1 primary reference (e.g., radio clock) 2-15 secondary reference (via NTP or SNTP) 16-255 reserved.
pollInterval
public byte pollIntervalThis value indicates the maximum interval between successive messages, in seconds to the nearest power of two. The values that can appear in this field presently range from 4 (16 s) to 14 (16284 s). However, most applications use only the sub-range 6 (64 s) to 10 (1024 s).precision
public byte precisionThis value indicates the precision of the local clock, in seconds to the nearest power of two. The values that normally appear in this field range from -6 for mains-frequency clocks to -20 for microsecond clocks found in some workstations.rootDelay
public double rootDelayThis value indicates the total roundtrip delay to the primary reference source, in seconds. Note that this variable can take on both positive and negative values, depending on the relative time and frequency offsets. The values that normally appear in this field range from negative values of a few milliseconds to positive values of several hundred milliseconds.rootDispersion
public double rootDispersionThis value indicates the nominal error relative to the primary reference source, in seconds. The values that normally appear in this field range from 0 to several hundred milliseconds.referenceIdentifier
public final byte[] referenceIdentifierThis is a 4-byte array identifying the particular reference source. In the case of NTP Version 3 or Version 4 stratum-0 (unspecified) or stratum-1 (primary) servers, this is a four-character ASCII string, left justified and zero padded to 32 bits. In NTP Version 3 secondary servers, this is the 32-bit IPv4 address of the reference source. In NTP Version 4 secondary servers, this is the low order 32 bits of the latest transmit timestamp of the reference source. NTP primary (stratum 1) servers should set this field to a code identifying the external reference source according to the following list. If the external reference is one of those listed, the associated code should be used. Codes for sources not listed can be contrived as appropriate.Code External Reference Source ---- ------------------------- LOCL uncalibrated local clock used as a primary reference for a subnet without external means of synchronization PPS atomic clock or other pulse-per-second source individually calibrated to national standards ACTS NIST dialup modem service USNO USNO modem service PTB PTB (Germany) modem service TDF Allouis (France) Radio 164 kHz DCF Mainflingen (Germany) Radio 77.5 kHz MSF Rugby (UK) Radio 60 kHz WWV Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz WWVB Boulder (US) Radio 60 kHz WWVH Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz CHU Ottawa (Canada) Radio 3330, 7335, 14670 kHz LORC LORAN-C radionavigation system OMEG OMEGA radionavigation system GPS Global Positioning Service GOES Geostationary Orbit Environment Satellite.
referenceTimestamp
public double referenceTimestampThis is the time at which the local clock was last set or corrected, in seconds since 00:00 1-Jan-1900.originateTimestamp
public double originateTimestampThis is the time at which the request departed the client for the server, in seconds since 00:00 1-Jan-1900.receiveTimestamp
public double receiveTimestampThis is the time at which the request arrived at the server, in seconds since 00:00 1-Jan-1900.transmitTimestamp
public final double transmitTimestampThis is the time at which the reply departed the server for the client, in seconds since 00:00 1-Jan-1900._DATE_FORMAT
Returns a timestamp (number of seconds since 00:00 1-Jan-1900) as a formatted date/time string.
Constructor Details
NtpMessage
public NtpMessage(byte[] array) Parses a new NtpMessage from an array of bytes.- Parameters:
array- 48 bytes minimum
NtpMessage
public NtpMessage()A client-mode NtpMessage with the transmit timestamp set to the current time.
Method Details
toByteArray
public byte[] toByteArray()This method constructs the data bytes of a raw NTP packet.- Returns:
- 48 bytes
toString
unsignedByteToShort
private static short unsignedByteToShort(byte b) Converts an unsigned byte to a short. By default, Java assumes that a byte is signed.- Parameters:
b- the byte to widen- Returns:
- the same bit pattern read as an unsigned value, 0-255
decodeTimestamp
private static double decodeTimestamp(byte[] array, int pointer) Will read 8 bytes of a message beginning atpointerand return it as a double, according to the NTP 64-bit timestamp format.2036-compliant as of 0.9.50.
- Parameters:
array- 8 bytes starting at pointerpointer- the index in array where the timestamp begins- Returns:
- the time since 1900 (NOT Java time)
encodeTimestamp
public static void encodeTimestamp(byte[] array, int pointer, double timestamp) Encodes a timestamp in the specified position in the message.2036-compliant as of 0.9.50. Timestamps before 1968 will be encoded as Jan. 1968. Timestamps after Feb. 2104 will be encoded as Feb. 2104.
- Parameters:
array- output 8 bytes starting at pointerpointer- the index in array where the timestamp is writtentimestamp- the time to encode (since 1900, NOT Java time)
timestampToString
Formats an NTP timestamp for display.- Parameters:
timestamp- the timestamp in seconds since 1900- Returns:
- the date and time as text
referenceIdentifierToString
Convert the reference identifier to a human-readable string.- Returns:
- non-null, "" if unset
referenceIdentifierToString
Returns a string representation of a reference identifier according to the rules set out in RFC 2030.- Parameters:
ref- the 4-byte reference identifier field from the packetstratum- the packet's stratum, 0 or 1 renders ref as ASCII textversion- the NTP version from the packet, 3 renders ref as an IPv4 address and 4 as a fractional timestamp- Returns:
- non-null, "" if unset, or for a version other than 3 or 4