Skip to main content
Code Review

Return to Question

Notice removed Draw attention by Community Bot
Bounty Ended with no winning answer by Community Bot
code update
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35

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'
 ]
 }
});
updated code with formatting possibilities
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
'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;
 }
};
Tweeted twitter.com/#!/StackCodeReview/status/582672479790985217
added 28 characters in body
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
'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;
 }
};
Notice added Draw attention by Kid Diamond
Bounty Started worth 50 reputation by Kid Diamond
code update
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
code update
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
update code, fixed time cache issue
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
added 80 characters in body
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
added 1 character in body
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
added 266 characters in body
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
edited tags
Link
200_success
  • 145.5k
  • 22
  • 190
  • 478
Loading
updated code
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
Source Link
Kid Diamond
  • 2.6k
  • 17
  • 35
Loading
default

AltStyle によって変換されたページ (->オリジナル) /