diff --git a/.jshintrc b/.jshintrc index bce0e3a..aa97aba 100644 --- a/.jshintrc +++ b/.jshintrc @@ -16,6 +16,7 @@ "unused": "vars", "laxbreak": true, "laxcomma": false, + "loopfunc": true, "onevar": false, "bitwise": false, "forin": false, diff --git a/src/values/TimeValue.js b/src/values/TimeValue.js index 7e53967..1484962 100644 --- a/src/values/TimeValue.js +++ b/src/values/TimeValue.js @@ -29,17 +29,17 @@ var SELF = dv.TimeValue = util.inherit( 'DvTimeValue', PARENT, function( timesta this._time = {}; try { - var matches = /^([-+]?\d+)-(\d+)-(\d+)T(\d{2}):(\d{2}):(\d{2})Z$/.exec( timestamp ); + var matches = /^([-+]?\d+)-(\d+)-(\d+)T(?:(\d+):(\d+)(?::(\d+))?Z?)?$/.exec( timestamp ); // Strip additional leading zeros from the year, but keep 4 digits. this._time.year = matches[1].replace( /\b0+(?=\d{4})/, '' ); this._time.month = parseInt( matches[2], 10 ); this._time.day = parseInt( matches[3], 10 ); - this._time.hour = parseInt( matches[4], 10 ); - this._time.minute = parseInt( matches[5], 10 ); - this._time.second = parseInt( matches[6], 10 ); + this._time.hour = parseInt( matches[4] || 0, 10 ); + this._time.minute = parseInt( matches[5] || 0, 10 ); + this._time.second = parseInt( matches[6] || 0, 10 ); } catch( e ) { - throw new Error( 'Unable to process supposed timestamp string' ); + throw new Error( 'Unable to process timestamp "' + timestamp + '"' ); } this._options = { diff --git a/tests/src/values/TimeValue.tests.js b/tests/src/values/TimeValue.tests.js index 7545c8a..bffb19a 100644 --- a/tests/src/values/TimeValue.tests.js +++ b/tests/src/values/TimeValue.tests.js @@ -36,6 +36,19 @@ define( [ getConstructorArguments: function() { return [ ['+0000000000001942-04-01T00:00:00Z'], + + // Optional parts + ['+0000000000001942-04-01T00:00:00'], + ['+0000000000001942-04-01T00:00'], + ['+0000000000001942-04-01T'], + ['0000000000001942-04-01T'], + ['1942-04-01T'], + + // Minimal and maximal length + ['+1-1-1T1:1:1Z'], + ['+9999999999999999-12-31T23:59:59Z'], + + // Options ['+0000000000001400-01-01T00:00:00Z', { calendarModel: 'http://www.wikidata.org/entity/Q1985786' } ], @@ -45,6 +58,46 @@ define( [ ]; }, + /** + * Tests if the constructor fails as expected for invalid and unsupported timestamp values. + * + * @since 0.7 + * + * @param {QUnit} assert + */ + testConstructorThrowsException: function( assert ) { + var invalidTimestamps = [ + // Non-strings + undefined, + null, + 1, + 0.1, + + // The "T" is required + '', + '1', + '1942-04-01', + '+0000000000002015-01-01 01:01:01Z', + + // Unsupported time zones + '+0000000000002015-01-01T01:01:01A', + '+0000000000002015-01-01T01:01:01+0000', + '+0000000000002015-01-01T01:01:01+00:00' + ]; + var i, invalidTimestamp; + + for ( i = 0; i < invalidTimestamps.length; i++ ) { + invalidTimestamp = invalidTimestamps[i]; + + assert.throws( + function() { + dv.TimeValue( invalidTimestamp ); + }, + '"' + invalidTimestamp + '" is not a valid TimeValue timestamp' + ); + } + }, + /** * Tests if the equals method is able to return false. *