Skip to content

Instantly share code, notes, and snippets.

@anvoz
Created August 7, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anvoz/6b69860b360dd8bad1be to your computer and use it in GitHub Desktop.
Save anvoz/6b69860b360dd8bad1be to your computer and use it in GitHub Desktop.
Tell the time
labnotes.org
example.com
mathforum.org
slack.com
github.com
facebook.com
twitter.com
const File = require('fs');
const HTTP = require('http');
const FILENAME = 'hostnames.txt';
// Tell the time.
getHostnames(FILENAME)
.then(getDatesFromHostnames)
.then(convertDatesToTime)
.then(selectTime)
.then(printTime)
.catch(console.log);
// Returns a promise that resolves to an array of hostnames getting from file.
function getHostnames(filename) {
return new Promise(function(resolve, reject) {
File.readFile(filename, 'utf-8', function(error, data) {
if (error)
reject(error);
else {
const hostnames = data.trim().split('\n');
resolve(hostnames);
}
});
});
}
// Returns a promise that resolves to the Date header of a given host.
function getDateHeader(host) {
return new Promise(function(resolve, reject) {
// Make a HEAD request because we don't need the response body.
const options = { method: 'HEAD', host };
const request = HTTP.request(options, function(response) {
resolve(response.headers.date);
});
request.on('error', reject);
request.end();
});
}
// Returns a promise that resolves to an array of date headers from the given
// list of hostnames.
function getDatesFromHostnames(hostnames) {
return new Promise(function(resolve, reject) {
const promises = hostnames.map(getDateHeader);
Promise.all(promises).then(resolve).catch(reject);
});
}
// Take an array of date strings, returns an array of valid dates in
// milliseconds.
function convertDatesToTime(dates) {
return dates
.filter(function(date) {
return date;
})
.map(function(date) {
return new Date(date).getTime();
});
}
// Returns the current time from a list of times to guess.
function selectTime(times) {
// Should have at least two values to be able to select the correct time.
if (times.length <= 1)
return null;
// All of the time values should not have more than one second diff unless:
// - The response time from one of the servers was too long.
// - The date header from one of the servers was not correct.
// When all values are good, we can assume the max value is the closest to the
// current time.
times.sort();
const now = times[times.length - 1];
return (now - times[0] <= 1000) ? now : null;
}
// Print the time in ISO 8601 format to the console.
function printTime(time) {
if (time) {
const output = (new Date(time)).toISOString();
console.log(output);
} else
console.log('Could not tell the time.');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment