Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Pure Javascript implementation of the NTP Client Protocol
## Getting Started
Install the module with: `npm install ntp-client`

## Examples
### Get just the time
```javascript
var ntpClient = require('ntp-client');

Expand All @@ -19,9 +21,28 @@ ntpClient.getNetworkTime("pool.ntp.org", 123, function(err, date) {
});
```

### Get the time and the server's stratum
Get the server's startum:
```javascript
var ntpClient = require('ntp-client');

ntpClient.getNetworkTime("pool.ntp.org", 123, function(err, date, stratum) {
if(err) {
console.error(err);
return;
}

console.log("Current time : ");
console.log(date); // Mon Jul 08 2013 21:31:31 GMT+0200 (Paris, Madrid (heure d’été))
console.log("Current stratum : ");
console.log(stratum); // 3
});
```

## Contributors
* Clément Bourgeois (https://github.com/moonpyk)
* Callan Bryant (https://github.com/naggie)
* SomKen (https://github.com/somken)

## License
Copyright (c) 2014 Clément Bourgeois
Expand Down
26 changes: 15 additions & 11 deletions lib/ntp-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
exports.ntpReplyTimeout = 10000;

/**
* Fetches the current NTP Time from the given server and port.
* Fetches the current NTP Time from the given server and port, including stratum.
* @param {string} server IP/Hostname of the remote NTP Server
* @param {number} port Remote NTP Server port number
* @param {function(Object, Date)} callback(err, date) Async callback for
* the result date or eventually error.
* @param {function(Object, Date, number)} callback(err, date, stratum) Async callback for the result date, stratum, or error.
*/
exports.getNetworkTime = function (server, port, callback) {
if (callback === null || typeof callback !== "function") {
Expand All @@ -36,7 +35,7 @@
port = port || exports.defaultNtpPort;

var client = dgram.createSocket("udp4"),
ntpData = new Buffer(48);
ntpData = Buffer.alloc(48);

// RFC 2030 -> LI = 0 (no warning, 2 bits), VN = 3 (IPv4 only, 3 bits), Mode = 3 (Client Mode, 3 bits) -> 1 byte
// -> rtol(LI, 6) ^ rotl(VN, 3) ^ rotl(Mode, 0)
Expand All @@ -49,7 +48,7 @@

var timeout = setTimeout(function () {
client.close();
callback("Timeout waiting for NTP response.", null);
callback("Timeout waiting for NTP response.", null, null);
}, exports.ntpReplyTimeout);

// Some errors can happen before/after send() or cause send() to was impossible.
Expand All @@ -63,7 +62,7 @@
return;
}

callback(err, null);
callback(err, null, null);
errorFired = true;

clearTimeout(timeout);
Expand All @@ -75,7 +74,7 @@
return;
}
clearTimeout(timeout);
callback(err, null);
callback(err, null, null);
errorFired = true;
client.close();
return;
Expand All @@ -85,8 +84,11 @@
clearTimeout(timeout);
client.close();

// Extract Stratum (byte 1)
var stratum = msg[1];

// Offset to get to the "Transmit Timestamp" field (time at which the reply
// departed the server for the client, in 64-bit timestamp format."
// departed the server for the client, in 64-bit timestamp format)
var offsetTransmitTime = 40,
intpart = 0,
fractpart = 0;
Expand All @@ -107,7 +109,8 @@
var date = new Date("Jan 01 1900 GMT");
date.setUTCMilliseconds(date.getUTCMilliseconds() + milliseconds);

callback(null, date);
// Return date and stratum in callback
callback(null, date, stratum);
});
});
};
Expand All @@ -116,13 +119,14 @@
exports.getNetworkTime(
exports.defaultNtpServer,
exports.defaultNtpPort,
function (err, date) {
function (err, date, stratum) {
if (err) {
console.error(err);
return;
}

console.log(date);
console.log('NTP Date:', date);
console.log('Stratum:', stratum);
});
};
}(exports));
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ntp-client",
"description": "Pure Javascript implementation of the NTP Client Protocol",
"version": "0.5.3",
"version": "0.5.4",
"homepage": "https://github.com/moonpyk/node-ntp-client",
"author": {
"name": "Clément Bourgeois",
Expand Down
20 changes: 20 additions & 0 deletions test/ntp-client_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@

};

exports.validNTPServerStratum = function (test) {
ntpClient.getNetworkTime(ntpClient.defaultNtpServer, ntpClient.defaultNtpPort, function (err, date, stratum) {
console.log();
console.log("System reported : %s", new Date());

test.ok(err === null);
test.ok(date !== null);
test.ok(stratum !== null);
test.ok(stratum >= 0);

console.log("NTP Reported : %s", date);
console.log("Stratum Reported : %s", stratum);

// I won't test returned datetime against the system datetime
// this is the whole purpose of NTP : putting clocks in sync.
test.done();
});

};

exports.invalidNTPServer = function (test) {
// I'm pretty sure there is no NTP Server listening at google.com
ntpClient.getNetworkTime("google.com", 123, function (err, date) {
Expand Down