0

I'm attempting to grab a timestamp off an nist.gov server using the code below.

InetAddress addr = InetAddress.getByName("129.6.15.30");
DatagramSocket s = new DatagramSocket();
System.out.println("Connected to: "+addr.getHostName());

byte[] buf = new byte[4];
DatagramPacket p = new DatagramPacket(buf, buf.length, addr, 37);
s.send(p);
System.out.println("message sent");

DatagramPacket dp = new DatagramPacket(buf, buf.length);
s.receive(dp);
String data = new String(dp.getData(), 0, dp.getLength());
System.out.println("Received: "+data);

When I run this on Eclipse, I get the following back in the console.

Connected to: time-c.nist.gov
message sent
Received: ÛÏÌ<

Good news is, I'm connecting to the correct server and getting back a packet. However, I just can't seem to turn that packet's data into a comprehensible representation of that data. What am I missing?

MP12389
  • 305
  • 1
  • 3
  • 10

1 Answers1

0

The response from the Time Protocol is a 32 bit integer in network byte order - this is not a string.

To read it you need to use something like DataInputStream:

DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dp.getData(), 0, dp.getLength()));

int time = dis.readInt();

dis.close();

The time value returned is the number of seconds since 1st Jan 1900, to get a Java Instant from this we need to convert the unsigned integer to the standard Java 'epoch' which is the number of seconds since 1st Jan 1970:

long secondsSince1Jan1900 = Integer.toUnsignedLong(time);

long differenceBetweenEpochs = 2208988800L;

long secondsSince1Jan1970 = secondsSince1Jan1900 - differenceBetweenEpochs;

Instant instant = Instant.ofEpochSecond(secondsSince1Jan1970);
greg-449
  • 109,219
  • 232
  • 102
  • 145
  • This definitely helped, as my new received output was Received: -607100146. Now, to figure out how to convert that to a standard-format timestamp. – MP12389 Nov 11 '16 at 15:33
  • Added the conversion to `Instant` – greg-449 Nov 11 '16 at 16:41
  • Thank you, Greg, as this worked and I got the followed output for instant: 2016-11-11T18:27:50Z. And while I thank you for this answer, I don't want to just say, "Great! This guy did it for me!" What I'm curious about is what the 'L' means after 2208988800. I understand that 2208988800 is the number of seconds between 1/1/1900 and 1/1/1970, but what is the L (forgive me, I've only been coding in Java for 4.5 months and small details like this escape me sometimes). – MP12389 Nov 11 '16 at 18:32
  • It just says that this is a `long` value rather than an `int` (lower case `l` is also allowed). `2208988800` is too big to be an `int`. – greg-449 Nov 11 '16 at 18:36
  • That's what I figured. Pretty simple in the end. Just part of the learning process. Thank you, again, for your help. – MP12389 Nov 11 '16 at 18:43