From f725c23e17fe28068b509d09c1f3a7e83e2fceb9 Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Wed, 16 Jan 2013 00:22:14 -0800 Subject: [PATCH] Added format token X, that will parse/print unix timestamp with ms When parsing all of X, X.S, X.SS and X.SSS will parse timestamp plus optional millisecond (1-3 digits), but when formatting will display as expected. --- moment.js | 16 +++++++++++++++- test/moment/create.js | 18 +++++++++++++++++- test/moment/format.js | 12 ++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/moment.js b/moment.js index 201a4d4fc..eb72570e5 100644 --- a/moment.js +++ b/moment.js @@ -23,7 +23,7 @@ aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g, + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?)/g, // parsing tokens @@ -38,6 +38,7 @@ parseTokenWord = /[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i, // any word (or two) characters or numbers including two word month in arabic. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z parseTokenT = /T/i, // T (ISO seperator) + parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 // preliminary iso regex // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 @@ -161,6 +162,9 @@ b = "-"; } return b + leftZeroFill(~~(10 * a / 6), 4); + }, + X : function () { + return this.unix(); } }; @@ -577,6 +581,8 @@ case 'a': case 'A': return parseTokenWord; + case 'X': + return parseTokenTimestampMs; case 'Z': case 'ZZ': return parseTokenTimezone; @@ -668,6 +674,10 @@ case 'SSS' : datePartArray[6] = ~~ (('0.' + input) * 1000); break; + // UNIX TIMESTAMP WITH MS + case 'X': + config._d = new Date(parseFloat(input) * 1000); + break; // TIMEZONE case 'Z' : // fall through to ZZ case 'ZZ' : @@ -700,6 +710,10 @@ function dateFromArray(config) { var i, date, input = []; + if (config._d) { + return; + } + for (i = 0; i < 7; i++) { config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } diff --git a/test/moment/create.js b/test/moment/create.js index 641d5dc3f..85240c6e7 100644 --- a/test/moment/create.js +++ b/test/moment/create.js @@ -138,7 +138,8 @@ exports.create = { ['HH:mm:ss SSS', '00:30:00 123'], ['HH:mm:ss S', '00:30:00 7'], ['HH:mm:ss SS', '00:30:00 78'], - ['HH:mm:ss SSS', '00:30:00 789'] + ['HH:mm:ss SSS', '00:30:00 789'], + ['X.SSS', '1234567890.123'] ], i; @@ -149,6 +150,21 @@ exports.create = { test.done(); }, + "unix timestamp format" : function(test) { + var formats = ['X', 'X.S', 'X.SS', 'X.SSS']; + + test.expect(formats.length * 4); + for (var i = 0; i < formats.length; i++) { + var format = formats[i]; + test.equal(moment('1234567890', format).valueOf(), 1234567890 * 1000, format + " matches timestamp without milliseconds"); + test.equal(moment('1234567890.1', format).valueOf(), 1234567890 * 1000 + 100, format + " matches timestamp with deciseconds"); + test.equal(moment('1234567890.12', format).valueOf(), 1234567890 * 1000 + 120, format + " matches timestamp with centiseconds"); + test.equal(moment('1234567890.123', format).valueOf(), 1234567890 * 1000 + 123, format + " matches timestamp with milliseconds"); + } + + test.done(); + }, + "string with format no separators" : function(test) { moment.lang('en'); var a = [ diff --git a/test/moment/format.js b/test/moment/format.js index 769f26b01..c26613dfe 100644 --- a/test/moment/format.js +++ b/test/moment/format.js @@ -87,6 +87,18 @@ exports.format = { test.done(); }, + "unix timestamp" : function(test) { + test.expect(4); + + var m = moment('1234567890.123', 'X'); + test.equals(m.format('X'), '1234567890', 'unix timestamp without milliseconds'); + test.equals(m.format('X.S'), '1234567890.1', 'unix timestamp with deciseconds'); + test.equals(m.format('X.SS'), '1234567890.12', 'unix timestamp with centiseconds'); + test.equals(m.format('X.SSS'), '1234567890.123', 'unix timestamp with milliseconds'); + + test.done(); + }, + "zone" : function(test) { test.expect(3); -- 2.47.2