My AJAX LiveDateTimeLiveDate Object
The following JS codeLiveDate
object displays the live current date and time and updates whenever it changes. It has a sendAjaxRequest()
function dependency to send the AJAX requests.
I'd like to have a full review onof any aspects of my code:
- OOP
- Readability (naming in particular)
- Performance
- Usability
- JS conventions
- Error handling
'use strict';
function sendAjaxRequest(url, callback, postData) {
var XHR_FACTORIES = [
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject("Msxml3'Msxml3.XMLHTTP"XMLHTTP'); },
function () { return new ActiveXObject("Msxml2'Msxml2.XMLHTTP.6.0"0'); },
function () { return new ActiveXObject("Msxml2'Msxml2.XMLHTTP.3.0"0'); },
function () { return new ActiveXObject("Msxml2'Msxml2.XMLHTTP"XMLHTTP'); },
function () { return new ActiveXObject("Microsoft'Microsoft.XMLHTTP"XMLHTTP'); }
];
for (var i = 0; i < XHR_FACTORIES.length; i++) {
try {
var xhr = XHR_FACTORIES[i]();
} catch (e) {
continue;
}
break;
}
if (typeof xhr === 'undefined') {
throw {
name: 'AjaxSupportException',
context: 'Trying to instantiate an XMLHttpRequest object from one of the pre-definedpredefined factories.',
problem: 'No XMLHttpRequest object available for the current client.',
solution: 'Use a major client that does support AJAX.',
toString: function () { return this.name; }
};
}
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return;
}
callback.apply(xhr);
}
xhr.open(postData ? 'POST' : 'GET', url, true);
xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); // Raises a Chrome refusal notice.
if (postData) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.send();
};
LiveDateTimeLiveDate.js
'use strict';
function LiveDateTimeLiveDate(timeUrl, dateElement, timeElementelement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
// Required arguments.
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.optionselement = options || {};element;
// Optional arguments.
this.format = options.format || 'l j F Y - H:i:s';
this.offset = options.offset || 0;
this.weekdayNames = {};
this.monthNames = {};
this.weekdayNames.long = options.weekdayNames.long || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.optionsweekdayNames.monthNamesshort = options.weekdayNames.short || [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
];
this.monthNames.long = options.monthNames.long || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.monthNames.short = options.monthNames.short || [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
];
this._date; //private
this.start();
}
LiveDateTimeLiveDate.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
var requestTime = new Date().getTime(),
previousTime = new Date().getTime(),
serverTime = parseInt(this.responseText);
if (this.status !== 200) {
self.element.innerHTML = '<span style="color: red;"><b>Live Date Error</b></span>';
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' insteadwas returned but expected HTTP 200.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system this.currentDatedate changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Introducing a delay toparticularly preventfor aPC's net::ERR_NETWORK_IO_SUSPENDEDthat've errorjust onbeen awoken to
// PC'stry thatand justprevent wokean upAjaxRequestException andfrom havebeing notthrown yetdue reinitializedto their // Internet connection not being reinitialized yet.
setTimeout(function () {
self.start();
}, 10000);
return;
}
self.currentDate_date = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElementelement.innerHTML = self.formatformatAs('l j F Y');
self.timeElement.innerHTML = self.format('H:i:s');
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
},
formatformatAs: function (format) {
var string = '',
self = this;
var dateFormatter = {
// Day
// A full textual representation of the day of the week, e.g. Monday.
l: function () { return self.optionsweekdayNames.weekdayNames[selflong[self.currentDate_date.getUTCDay()]; },
//Month
// A full textual representation of a month, e.g. January.
F: function () { return self.optionsmonthNames.monthNames[selflong[self.currentDate_date.getUTCMonth()]; },
// Day of the month without leading zeros.
j: function () { return self.currentDate_date.getUTCDate(); },
// Year
// A full numeric representation of a year, e.g. 2015.
Y: function () { return self.currentDate_date.getUTCFullYear(); },
// Time
// 24-hour format of an hour with leading zeros.
H: function () { return ('0' + self.currentDate_date.getUTCHours()).slice(-2); },
// Minutes with leading zeros.
i: function () { return ('0' + self.currentDate_date.getUTCMinutes()).slice(-2); },
// Seconds with leading zeros.
s: function () { return ('0' + self.currentDate_date.getUTCSeconds()).slice(-2); }
};
for (var i = 0; i < format.length;// i++)More {
formatting methods to be added in the future.
var char = format.charAt(i)};
ifreturn format.replace(/(\\?)([a-z]/i.test(char) &&/gi, typeoffunction dateFormatter[char](match, ===isEscaped, 'function'char) {
return !isEscaped && stringdateFormatter[char] +=? dateFormatter[char]();
} else {
string +=: char;
});
},
getTime: function () {
return string;this._date.getTime();
},
toStringstop: function () {
returnclearInterval(this.tickIntervalId);
this.currentDate;tickIntervalId = null;
}
};
var liveDateTime = new LiveDateTimeLiveDate('time.php', document.getElementById('date'), document.getElementById('time'), {
format: 'l j F Y - <\\b>H:i:s</\\b>',
offset: 36000007200000, //paris Paris
weekdayNames: ['dimanche'{
long: [
'dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'] 'samedi'
]
},
monthNames: ['janvier'{
long: [
'janvier', 'fèvrier', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'] 'décembre'
]
}
});
My AJAX LiveDateTime Object
The following JS code object displays the date and time and updates whenever it changes. It has a sendAjaxRequest()
function dependency to send the AJAX requests.
I'd like to have a full review on any aspects of my code:
- OOP
- Readability (naming in particular)
- Performance
- Usability
- JS conventions
'use strict';
function sendAjaxRequest(url, callback, postData) {
var XHR_FACTORIES = [
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject("Msxml3.XMLHTTP"); },
function () { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); },
function () { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); },
function () { return new ActiveXObject("Msxml2.XMLHTTP"); },
function () { return new ActiveXObject("Microsoft.XMLHTTP"); }
];
for (var i = 0; i < XHR_FACTORIES.length; i++) {
try {
var xhr = XHR_FACTORIES[i]();
} catch (e) {
continue;
}
break;
}
if (typeof xhr === 'undefined') {
throw {
name: 'AjaxSupportException',
context: 'Trying to instantiate an XMLHttpRequest object from one of the pre-defined factories.',
problem: 'No XMLHttpRequest object available for the current client.',
solution: 'Use a major client that does support AJAX.',
toString: function () { return this.name; }
};
}
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return;
}
callback.apply(xhr);
}
xhr.open(postData ? 'POST' : 'GET', url, true);
xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); // Raises a Chrome refusal notice.
if (postData) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.send();
};
LiveDateTime.js
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system this.currentDate changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Introducing a delay to prevent a net::ERR_NETWORK_IO_SUSPENDED error on
// PC's that just woke up and have not yet reinitialized their connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
self.currentDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.format('l j F Y');
self.timeElement.innerHTML = self.format('H:i:s');
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
},
format: function (format) {
var string = '',
self = this;
var dateFormatter = {
// A full textual representation of the day of the week, e.g. Monday.
l: function () { return self.options.weekdayNames[self.currentDate.getUTCDay()]; },
// A full textual representation of a month, e.g. January.
F: function () { return self.options.monthNames[self.currentDate.getUTCMonth()]; },
// Day of the month without leading zeros.
j: function () { return self.currentDate.getUTCDate(); },
// A full numeric representation of a year, e.g. 2015.
Y: function () { return self.currentDate.getUTCFullYear(); },
// 24-hour format of an hour with leading zeros.
H: function () { return ('0' + self.currentDate.getUTCHours()).slice(-2); },
// Minutes with leading zeros.
i: function () { return ('0' + self.currentDate.getUTCMinutes()).slice(-2); },
// Seconds with leading zeros.
s: function () { return ('0' + self.currentDate.getUTCSeconds()).slice(-2); }
};
for (var i = 0; i < format.length; i++) {
var char = format.charAt(i);
if (/[a-z]/i.test(char) && typeof dateFormatter[char] === 'function') {
string += dateFormatter[char]();
} else {
string += char;
}
}
return string;
},
toString: function () {
return this.currentDate;
}
};
var liveDateTime = new LiveDateTime('time.php', document.getElementById('date'), document.getElementById('time'), {
offset: 3600000, //paris
weekdayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
monthNames: ['janvier', 'fèvrier', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']
});
My AJAX LiveDate Object
The LiveDate
object displays the live current date and has a sendAjaxRequest()
function dependency to send the AJAX requests.
I'd like to have a full review of any aspects of my code:
- OOP
- Readability
- Performance
- Usability
- JS conventions
- Error handling
'use strict';
function sendAjaxRequest(url, callback, postData) {
var XHR_FACTORIES = [
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject('Msxml3.XMLHTTP'); },
function () { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); },
function () { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); },
function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
function () { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
for (var i = 0; i < XHR_FACTORIES.length; i++) {
try {
var xhr = XHR_FACTORIES[i]();
} catch (e) {
continue;
}
break;
}
if (typeof xhr === 'undefined') {
throw {
name: 'AjaxSupportException',
context: 'Trying to instantiate an XMLHttpRequest object from one of the predefined factories.',
problem: 'No XMLHttpRequest object available for the current client.',
solution: 'Use a major client that does support AJAX.',
toString: function () { return this.name; }
};
}
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return;
}
callback.apply(xhr);
}
xhr.open(postData ? 'POST' : 'GET', url);
xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); // Raises a Chrome refusal notice.
if (postData) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.send();
};
LiveDate.js
'use strict';
function LiveDate(timeUrl, element, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
// Required arguments.
this.timeUrl = timeUrl;
this.element = element;
// Optional arguments.
this.format = options.format || 'l j F Y - H:i:s';
this.offset = options.offset || 0;
this.weekdayNames = {};
this.monthNames = {};
this.weekdayNames.long = options.weekdayNames.long || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.weekdayNames.short = options.weekdayNames.short || [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
];
this.monthNames.long = options.monthNames.long || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.monthNames.short = options.monthNames.short || [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
];
this._date; //private
this.start();
}
LiveDate.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
var requestTime = new Date().getTime(),
previousTime = new Date().getTime(),
serverTime = parseInt(this.responseText);
if (this.status !== 200) {
self.element.innerHTML = '<span style="color: red;"><b>Live Date Error</b></span>';
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP ' + this.status + ' was returned but expected HTTP 200.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system date changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Introducing a delay particularly for PC's that've just been awoken to
// try and prevent an AjaxRequestException from being thrown due to their // Internet connection not being reinitialized yet.
setTimeout(function () {
self.start();
}, 10000);
return;
}
self._date = new Date(serverTime + currentTime - requestTime + self.offset);
self.element.innerHTML = self.formatAs(self.format);
previousTime = currentTime;
return tick;
}(), 200);
});
},
formatAs: function (format) {
var self = this;
var dateFormatter = {
// Day
// A full textual representation of the day of the week, e.g. Monday.
l: function () { return self.weekdayNames.long[self._date.getUTCDay()]; },
//Month
// A full textual representation of a month, e.g. January.
F: function () { return self.monthNames.long[self._date.getUTCMonth()]; },
// Day of the month without leading zeros.
j: function () { return self._date.getUTCDate(); },
// Year
// A full numeric representation of a year, e.g. 2015.
Y: function () { return self._date.getUTCFullYear(); },
// Time
// 24-hour format of an hour with leading zeros.
H: function () { return ('0' + self._date.getUTCHours()).slice(-2); },
// Minutes with leading zeros.
i: function () { return ('0' + self._date.getUTCMinutes()).slice(-2); },
// Seconds with leading zeros.
s: function () { return ('0' + self._date.getUTCSeconds()).slice(-2); }
// More formatting methods to be added in the future.
};
return format.replace(/(\\?)([a-z])/gi, function (match, isEscaped, char) {
return !isEscaped && dateFormatter[char] ? dateFormatter[char]() : char;
});
},
getTime: function () {
return this._date.getTime();
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
}
};
new LiveDate('time.php', document.getElementById('date'), {
format: 'l j F Y - <\\b>H:i:s</\\b>',
offset: 7200000, // Paris
weekdayNames: {
long: [
'dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'
]
},
monthNames: {
long: [
'janvier', 'fèvrier', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'
]
}
});
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function dependency.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system datethis.currentDate changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// PreventingIntroducing a delay to prevent a net::ERR_NETWORK_IO_SUSPENDED error when a PC juston
// PC's that just woke up and hashave not yet reinitialized its Internettheir connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
var localizedDateself.currentDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.options.weekdayNames[localizedDate.getUTCDay()] + ' '
+ localizedDate.getUTCDate() + ' '
+ self.options.monthNames[localizedDate.getUTCMonth()] + ' '
+ localizedDate.getUTCFullYear();
self.timeElementdateElement.innerHTML = ('0' + localizedDate.getUTCHours())self.sliceformat(-2) + ':'
+'l ('0'j +F localizedDate.getUTCMinutes()).slice(-2Y') + ':';
+ ('0'self.timeElement.innerHTML += localizedDate.getUTCSeconds())self.sliceformat(-2'H:i:s');
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
},
format: function (format) {
var string = '',
self = this;
var dateFormatter = {
// A full textual representation of the day of the week, e.g. Monday.
l: function () { return self.options.weekdayNames[self.currentDate.getUTCDay()]; },
// A full textual representation of a month, e.g. January.
F: function () { return self.options.monthNames[self.currentDate.getUTCMonth()]; },
// Day of the month without leading zeros.
j: function () { return self.currentDate.getUTCDate(); },
// A full numeric representation of a year, e.g. 2015.
Y: function () { return self.currentDate.getUTCFullYear(); },
// 24-hour format of an hour with leading zeros.
H: function () { return ('0' + self.currentDate.getUTCHours()).slice(-2); },
// Minutes with leading zeros.
i: function () { return ('0' + self.currentDate.getUTCMinutes()).slice(-2); },
// Seconds with leading zeros.
s: function () { return ('0' + self.currentDate.getUTCSeconds()).slice(-2); }
};
for (var i = 0; i < format.length; i++) {
var char = format.charAt(i);
if (/[a-z]/i.test(char) && typeof dateFormatter[char] === 'function') {
string += dateFormatter[char]();
} else {
string += char;
}
}
return string;
},
toString: function () {
return this.currentDate;
}
};
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function dependency.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system date changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Preventing a net::ERR_NETWORK_IO_SUSPENDED error when a PC just
// woke up and has not yet reinitialized its Internet connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
var localizedDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.options.weekdayNames[localizedDate.getUTCDay()] + ' '
+ localizedDate.getUTCDate() + ' '
+ self.options.monthNames[localizedDate.getUTCMonth()] + ' '
+ localizedDate.getUTCFullYear();
self.timeElement.innerHTML = ('0' + localizedDate.getUTCHours()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCMinutes()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCSeconds()).slice(-2);
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
}
};
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system this.currentDate changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Introducing a delay to prevent a net::ERR_NETWORK_IO_SUSPENDED error on
// PC's that just woke up and have not yet reinitialized their connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
self.currentDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.format('l j F Y');
self.timeElement.innerHTML = self.format('H:i:s');
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
},
format: function (format) {
var string = '',
self = this;
var dateFormatter = {
// A full textual representation of the day of the week, e.g. Monday.
l: function () { return self.options.weekdayNames[self.currentDate.getUTCDay()]; },
// A full textual representation of a month, e.g. January.
F: function () { return self.options.monthNames[self.currentDate.getUTCMonth()]; },
// Day of the month without leading zeros.
j: function () { return self.currentDate.getUTCDate(); },
// A full numeric representation of a year, e.g. 2015.
Y: function () { return self.currentDate.getUTCFullYear(); },
// 24-hour format of an hour with leading zeros.
H: function () { return ('0' + self.currentDate.getUTCHours()).slice(-2); },
// Minutes with leading zeros.
i: function () { return ('0' + self.currentDate.getUTCMinutes()).slice(-2); },
// Seconds with leading zeros.
s: function () { return ('0' + self.currentDate.getUTCSeconds()).slice(-2); }
};
for (var i = 0; i < format.length; i++) {
var char = format.charAt(i);
if (/[a-z]/i.test(char) && typeof dateFormatter[char] === 'function') {
string += dateFormatter[char]();
} else {
string += char;
}
}
return string;
},
toString: function () {
return this.currentDate;
}
};
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function dependency.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Make'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system date changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Preventing a net::ERR_NETWORK_IO_SUSPENDED error when a PC just
// woke up and has not yet reinitialized its Internet connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
var localizedDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.options.weekdayNames[localizedDate.getUTCDay()] + ' '
+ localizedDate.getUTCDate() + ' '
+ self.options.monthNames[localizedDate.getUTCMonth()] + ' '
+ localizedDate.getUTCFullYear();
self.timeElement.innerHTML = ('0' + localizedDate.getUTCHours()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCMinutes()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCSeconds()).slice(-2);
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
}
};
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function dependency.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Make the URL reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system date changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Preventing a net::ERR_NETWORK_IO_SUSPENDED error when a PC just
// woke up and has not yet reinitialized its Internet connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
var localizedDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.options.weekdayNames[localizedDate.getUTCDay()] + ' '
+ localizedDate.getUTCDate() + ' '
+ self.options.monthNames[localizedDate.getUTCMonth()] + ' '
+ localizedDate.getUTCFullYear();
self.timeElement.innerHTML = ('0' + localizedDate.getUTCHours()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCMinutes()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCSeconds()).slice(-2);
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
}
};
'use strict';
function LiveDateTime(timeUrl, dateElement, timeElement, options) {
if (typeof sendAjaxRequest !== 'function') {
throw {
name: 'DependencyException',
context: 'Checking the availability of the sendAjaxRequest function dependency.',
problem: 'The function is not available.',
solution: 'Load / include the sendAjaxRequest function.',
toString: function () { return this.name; }
};
}
this.timeUrl = timeUrl;
this.dateElement = dateElement;
this.timeElement = timeElement;
this.options = options || {};
this.options.weekdayNames = this.options.weekdayNames || [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
this.options.monthNames = this.options.monthNames || [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
this.start();
}
LiveDateTime.prototype = {
start: function () {
var self = this;
sendAjaxRequest(this.timeUrl + '?nocache=' + Math.random(), function () {
if (this.status !== 200) {
throw {
name: 'AjaxRequestException',
context: 'Sending an AJAX request to: ' + this.timeUrl + '.',
problem: 'HTTP status 200 was not returned, but ' + this.status + ' instead.',
solution: 'Double check the URL and make sure it\'s reachable.',
toString: function () { return this.name; }
};
}
var previousTime = self.requestTime = new Date().getTime();
self.serverTime = parseInt(this.responseText);
self.tickIntervalId = setInterval(function tick() {
var currentTime = new Date().getTime();
// Detecting client's system date changes to keep ours unaffected.
// Interval delay increment taken into account as well (+500 ms).
if ((currentTime - previousTime) < 0 || (currentTime - previousTime) >= 1500) {
self.stop();
// Preventing a net::ERR_NETWORK_IO_SUSPENDED error when a PC just
// woke up and has not yet reinitialized its Internet connection.
setTimeout(function () {
self.start();
}, 10000);
return;
}
var localizedDate = new Date(self.serverTime + currentTime - self.requestTime + (self.options.offset || 0));
self.dateElement.innerHTML = self.options.weekdayNames[localizedDate.getUTCDay()] + ' '
+ localizedDate.getUTCDate() + ' '
+ self.options.monthNames[localizedDate.getUTCMonth()] + ' '
+ localizedDate.getUTCFullYear();
self.timeElement.innerHTML = ('0' + localizedDate.getUTCHours()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCMinutes()).slice(-2) + ':'
+ ('0' + localizedDate.getUTCSeconds()).slice(-2);
previousTime = currentTime;
return tick;
}(), 200);
});
},
stop: function () {
clearInterval(this.tickIntervalId);
this.tickIntervalId = null;
},
getTime: function () {
return this.serverTime + new Date().getTime() - this.requestTime;
}
};