Subramanya Sastry has submitted this change and it was merged. Change subject: Hard-code date during parser tests (like PHP does). ......................................................................
Hard-code date during parser tests (like PHP does). Also touched up Date implementation: no more monkey patching Date, added support for using a time zone different from the current local timezone on the server. Change-Id: Iaff211bd5890d1c30f652fdf93837b82e48f38d8 --- M js/lib/ext.core.ParserFunctions.js M js/tests/parserTests.js 2 files changed, 88 insertions(+), 37 deletions(-) Approvals: Subramanya Sastry: Verified; Looks good to me, approved jenkins-bot: Checked diff --git a/js/lib/ext.core.ParserFunctions.js b/js/lib/ext.core.ParserFunctions.js index 40e5eba..70eb3db 100644 --- a/js/lib/ext.core.ParserFunctions.js +++ b/js/lib/ext.core.ParserFunctions.js @@ -487,6 +487,8 @@ // // First (very rough) approximation below based on // http://jacwright.com/projects/javascript/date_format/, MIT licensed. +// check out https://github.com/mde/timezone-js if we ever get serious about +// timezones & etc. ParserFunctions.prototype['pf_#time'] = function ( token, frame, cb, args ) { cb ( { tokens: this._pf_time( args[0].k, args.slice(1) ) } ); }; @@ -504,20 +506,38 @@ //} catch ( e ) { // this.env.dp( 'ERROR: #time ' + e ); - try { - res = [ new Date().format ( tpl ) ]; - } catch ( e2 ) { - this.env.dp( 'ERROR: #time ' + e2 ); - res = [ new Date().toString() ]; - } - return res; + var date = new ParsoidDate(this.env); + try { + res = [ date.format ( tpl ) ]; + } catch ( e2 ) { + this.env.dp( 'ERROR: #time ' + e2 ); + res = [ date.toString() ]; + } + return res; }; // Simulates PHP's date function -// FIXME: don't patch Date.prototype! -Date.prototype.format = function(format) { +var ParsoidDate = function(env) { + var date = new Date(); + var offset = date.getTimezoneOffset(); + // when testing, look aside to other date? + if (typeof(env.conf.wiki.fakeTimestamp)==='number') { + // php time stamps are in seconds; js timestamps are in milliseconds + date.setTime(env.conf.wiki.fakeTimestamp * 1000); + } + if (typeof(env.conf.wiki.timezoneOffset)==='number') { + offset = env.conf.wiki.timezoneOffset; + } + this._date = date; + // _localdate is a date object which is, in UTC, the desired local time. + // for example, if _date is 'Tue, 02 Apr 2013 21:30:44 GMT-0400 (EDT)' + // then _localdate is 'Tue, 02 Apr 2013 21:30:44 GMT' + offset *= 60 * 1000; /* convert from minutes to milliseconds */ + this._localdate = new Date(date.getTime() - offset); +}; +ParsoidDate.prototype.format = function(format) { var returnStr = ''; - var replace = Date.replaceChars; + var replace = ParsoidDate.replaceChars; for (var i = 0; i < format.length; i++) { var curChar = format.charAt(i); if (i - 1 >= 0 && format.charAt(i - 1) === "\\") { @@ -531,9 +551,55 @@ } return returnStr; }; +ParsoidDate.prototype.toString = function() { + return this.format('D, d M Y H:i:s O'); +}; +ParsoidDate.prototype.getTimezoneOffset = function() { + return (this._date.getTime() - this._localdate.getTime())/(60*1000); +}; +var getJan1 = function(d) { + d = new Date(d.getTime()); + d.setUTCMonth(0); + d.setUTCDate(1); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return d; +} +ParsoidDate.prototype.getWeek = function() { + var start = getJan1(this._localdate); + return Math.ceil((((this._localdate.valueOf() - start.valueOf()) / 86400000) + start.getUTCDay() + 1) / 7); +}; +ParsoidDate.prototype.getWeekYear = function() { // ISO-8601 week year + var d = new Date(this._localdate); + d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 6) % 7) + 3); + return d.getUTCFullYear(); +}; +ParsoidDate.prototype.getDayOfYear = function() { + var start = getJan1(this._localdate); + return Math.ceil((this._localdate.valueOf() - start.valueOf()) / 86400000); +}; +// proxy certain methods of _date into ParsoidDate. +['getUTCHours','getUTCMinutes','getUTCSeconds', + 'getTime','valueOf'].forEach(function(f) { + ParsoidDate.prototype[f] = function() { + var d = this._date; + return d[f].apply(d, arguments); + }; +}); +// local dates use UTC methods, but on _localdate +['getHours', 'getMinutes', 'getSeconds', 'getMilliseconds', + 'getDate', 'getDay', 'getMonth', 'getFullYear'].forEach(function(f) { + var ff = f.replace('get', 'getUTC'); + ParsoidDate.prototype[f] = function() { + var d = this._localdate; + return d[ff].apply(d, arguments); + }; +}); // XXX: support localization -Date.replaceChars = { +ParsoidDate.replaceChars = { shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], longMonths: ['January', 'February', 'March', 'April', 'May', 'June', @@ -544,9 +610,9 @@ // Day d: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); }, - D: function() { return Date.replaceChars.shortDays[this.getDay()]; }, + D: function() { return ParsoidDate.replaceChars.shortDays[this.getDay()]; }, j: function() { return this.getDate(); }, - l: function() { return Date.replaceChars.longDays[this.getDay()]; }, + l: function() { return ParsoidDate.replaceChars.longDays[this.getDay()]; }, N: function() { return this.getDay() + 1; }, S: function() { return (this.getDate() % 10 === 1 && @@ -555,34 +621,23 @@ this.getDate() !== 13 ? 'rd' : 'th'))); }, w: function() { return this.getDay(); }, - z: function() { - var d = new Date(this.getFullYear(),0,1); - return Math.ceil((this - d) / 86400000); - }, + z: function() { return this.getDayOfYear(); }, // Week - W: function() { - var d = new Date(this.getFullYear(), 0, 1); - return Math.ceil((((this - d) / 86400000) + d.getDay() + 1) / 7); - }, + W: function() { return this.getWeek(); }, // Month - F: function() { return Date.replaceChars.longMonths[this.getMonth()]; }, + F: function() { return ParsoidDate.replaceChars.longMonths[this.getMonth()]; }, m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); }, - M: function() { return Date.replaceChars.shortMonths[this.getMonth()]; }, + M: function() { return ParsoidDate.replaceChars.shortMonths[this.getMonth()]; }, n: function() { return this.getMonth() + 1; }, t: function() { - var d = new Date(); - return new Date(d.getFullYear(), d.getMonth(), 0).getDate(); + return new Date(this.getFullYear(), this.getMonth()+1, 0).getDate(); }, // Year L: function() { var year = this.getFullYear(); return (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)); }, - o: function() { - var d = new Date(this.valueOf()); - d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); - return d.getFullYear(); - }, + o: function() { return this.getWeekYear(); }, Y: function() { return this.getFullYear(); }, y: function() { return ('' + this.getFullYear()).substr(2); }, // Time @@ -619,13 +674,7 @@ (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + ':00'; }, - T: function() { - var m = this.getMonth(); - this.setMonth(0); - var result = this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); - this.setMonth(m); - return result; - }, + T: function() { return "Not Yet Supported"; }, Z: function() { return -this.getTimezoneOffset() * 60; }, // Full Date/Time c: function() { return this.format("Y-m-d\\TH:i:sP"); }, diff --git a/js/tests/parserTests.js b/js/tests/parserTests.js index 0ee409a..9a5502b 100644 --- a/js/tests/parserTests.js +++ b/js/tests/parserTests.js @@ -644,6 +644,8 @@ // adjust config to match that used for PHP tests // see core/tests/parser/parserTest.inc:setupGlobals() for // full set of config normalizations done. + this.env.conf.wiki.fakeTimestamp = 123; + this.env.conf.wiki.timezoneOffset = 0; // force utc for parsertests this.env.conf.wiki.server = 'http://example.org'; this.env.conf.wiki.wgScriptPath = '/'; this.env.conf.wiki.script = '/index.php'; -- To view, visit https://gerrit.wikimedia.org/r/57249 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iaff211bd5890d1c30f652fdf93837b82e48f38d8 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Parsoid Gerrit-Branch: master Gerrit-Owner: Cscott <[email protected]> Gerrit-Reviewer: GWicke <[email protected]> Gerrit-Reviewer: MarkTraceur <[email protected]> Gerrit-Reviewer: Subramanya Sastry <[email protected]> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
