From 82555fe192bed72a0963afde18f2e05c6ccd7259 Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Wed, 3 Feb 2016 18:19:15 +0000 Subject: [PATCH 1/8] 2.0.0 --- bower.json | 2 +- build/kairos-debug.js | 862 +++++++++++++++++--------- build/kairos-min.js | 9 +- build/kairos-node.js | 855 ++++++++++++++++--------- build/kairos.js | 862 +++++++++++++++++--------- examples/calc/calc.js | 4 +- examples/usecase/index.html | 31 +- examples/usecase/index.js | 34 +- examples/usecase/jumbotron-narrow.css | 79 --- examples/usecase/task.js | 14 +- gulpfile.js | 3 +- karma.conf.js | 6 +- package.json | 12 +- src/Engine.js | 394 ++++++++++++ src/Lexicon.js | 182 ++++++ src/engine/Gnomon.js | 365 ----------- src/kairos.js | 264 ++++---- test/browser/{gnomon.js => engine.js} | 210 +++---- test/browser/kairos.js | 63 +- test/browser/lexicon.js | 0 test/browser/test.html | 3 +- 21 files changed, 2667 insertions(+), 1587 deletions(-) delete mode 100644 examples/usecase/jumbotron-narrow.css create mode 100644 src/Engine.js create mode 100644 src/Lexicon.js delete mode 100644 src/engine/Gnomon.js rename test/browser/{gnomon.js => engine.js} (50%) create mode 100644 test/browser/lexicon.js diff --git a/bower.json b/bower.json index 47d1c0f..b4720a4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "kairos", - "version": "1.1.0", + "version": "2.0.0", "description": "A non date-based time calculator", "homepage": "https://github.com/kairos", "repository": { diff --git a/build/kairos-debug.js b/build/kairos-debug.js index 96c4a01..c4cd1a9 100644 --- a/build/kairos-debug.js +++ b/build/kairos-debug.js @@ -1,17 +1,26 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v1.1.0 + * @version v2.0.0 * @link https://github.com/kairos * @license BSD-2-Clause */ /** * @module Kairos */ -(function () { +;(function () { + 'use strict'; var Kairos = {}; + Kairos._locales = {}; + + // Set default locale + Kairos._locale = Kairos._locales.en; + // Set default pattern + Kairos._pattern = '#hh:mm:ss.SSS'; + // Set default regex + Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; // global on the server, window in the browser var previous_Kairos; @@ -28,11 +37,11 @@ } /** - * Avoid conflict in case of another instance of Kairos is already in the scope + * Avoid conflict in case of another instance of Kairos is already in the scope. * * @memberof module:Kairos * @method noConflict - * @returns {Object} + * @returns {Object} Previous Kairos object */ Kairos.noConflict = function () { root.Kairos = previous_Kairos; @@ -40,234 +49,296 @@ }; /** - * Validates if the given expression is valid. + * Sets Kairos locale. + * + * @param {String|Object} locale A locale from Kairos.locales or a compatible locale object + * @example Kairos.setLocale('en'); + */ + Kairos.setLocale = function (locale) { + if (typeof locale === 'string') { + return Kairos._locale = Kairos._locales[locale]; + } + if (typeof locale === 'object') { + return Kairos._locale = locale; + } + }; + + /** + * Gets Kairos current locale. + * + * @returns {String} Current locale + */ + Kairos.getLocale = function () { + return Kairos._locale; + }; + + /** + * Sets Kairos time expression pattern. + * Pattern structure is the following: + * # -> sign + * h -> hours + * m -> minutes + * s -> seconds + * S -> milliseconds + * + * @param {String} pattern The pattern to parse and format time expressions + * @example Kairos.setPattern('hh:mm:ss.fff'); + */ + Kairos.setPattern = function (pattern) { + Kairos._pattern = pattern; + Kairos._validator = Kairos.Lexicon.getValidator(pattern); + }; + + /** + * Gets current Kairos pattern. + * + * @returns {String} Current Kairos pattern + */ + Kairos.getPattern = function () { + return Kairos._pattern; + }; + + /** + * Validates the give expression with the current or given pattern. + * + * @param {String} expression Time expression to validate + * @param {String} pattern Pattern to test the expression + * @example Kairos.validate('10:30', 'hh:mm'); + * @returns {Boolean} True if valid, false if invalid + */ + Kairos.validate = function (expression, pattern) { + return Kairos.Lexicon.validate(expression, pattern); + }; + + /** + * Returns a new Kairos.Engine instance. * * @memberof module:Kairos - * @method validateExpression - * @param {String|Number} expression Time expression - * @returns {Boolean} + * @method new + * @param {String|Number|kairos.Engine} time Time expression to create an instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ - Kairos.validateExpression = function (expression) { - var regex = /^[+-]?\d+(?::?\d{1,2}(?::\d{1,2}(?::\d{1,3})?)?)?$/; - return regex.test(expression); + Kairos.new = function (time, pattern) { + return new Kairos.Engine(time, pattern); }; /** - * Return a Kairos.Gnomon instance. - * + * Returns an instance of Kairos.Engine with absolute time. + * * @memberof module:Kairos - * @method with - * @param {String|Number} expression Time expression - * @returns {Kairos.Gnomon} + * @method absolute + * @param {String|Number|kairos.Engine} time Time expression to get its absolute value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ - Kairos.with = function (expression) { - return new Kairos.Gnomon(expression); + Kairos.absolute = function (time, pattern) { + return Kairos.new(time, pattern).toAbsolute(); }; /** - * Sums augend time with addend time + * Sums augend time with addend time. * * @memberof module:Kairos * @method plus - * @param {String|Number} augend Augend time expression - * @param {String|Number} addend Addend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} augend Augend time expression + * @param {String|Number|kairos.Engine} addend Addend time expression + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ - Kairos.plus = function (augend, addend) { - return Kairos.with(augend).plus(addend).toExpression(); + Kairos.plus = function (augend, addend, pattern) { + return Kairos.new(augend, pattern).plus(addend, pattern); }; /** - * Subtracts minuend time with subtrahend time + * Subtracts minuend time with subtrahend time. * * @memberof module:Kairos * @method minus - * @param {String|Number} minuend Minuend time expression - * @param {String|Number} subtrahend Subtrahend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} minuend Minuend time expression + * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ - Kairos.minus = function (minuend, subtrahend) { - return Kairos.with(minuend).minus(subtrahend).toExpression(); + Kairos.minus = function (minuend, subtrahend, pattern) { + return Kairos.new(minuend, pattern).minus(subtrahend, pattern); }; /** - * Multiplies multiplier by the multiplicand + * Multiplies multiplier by the multiplicand. * * @memberof module:Kairos * @method multiply - * @param {String|Number} multiplier Multiplier time expression - * @param {String|Number} multiplicand Multiplicand number - * @returns {String} + * @param {String|Number|kairos.Engine} multiplier Multiplier time expression + * @param {Number} multiplicand Multiplicand value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ - Kairos.multiply = function (multiplier, multiplicand) { - return Kairos.with(multiplier).multiply(multiplicand).toExpression(); + Kairos.multiply = function (multiplier, multiplicand, pattern) { + return Kairos.new(multiplier, pattern).multiply(multiplicand); }; /** - * Divides dividend by the divisor + * Divides dividend by the divisor. * * @memberof module:Kairos * @method divide - * @param {String|Number} dividend Dividend time expression - * @param {Number} divisor Dividor number - * @returns {String} + * @param {String|Number|kairos.Engine} dividend Dividend time expression + * @param {Number} divisor Divisor value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with division result */ - Kairos.divide = function (dividend, divisor) { - return Kairos.with(dividend).divide(divisor).toExpression(); + Kairos.divide = function (dividend, divisor, pattern) { + return Kairos.new(dividend, pattern).divide(divisor); }; /** - * Returns a fraction of the current time + * Returns a fraction of the current time. * * @memberof module:Kairos * @method getFraction - * @param {String|Number} time - * @param {Number} numerator - * @param {Number} denominator - * @returns {String} + * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction + * @param {Number} numerator Numerator value + * @param {Number} denominator Denominator value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ - Kairos.getFraction = function (time, numerator, denominator) { + Kairos.getFraction = function (time, numerator, denominator, pattern) { if (numerator > denominator) { throw new Error('Improper fraction'); } - return Kairos.with(time).multiply(numerator).divide(denominator).toExpression(); + return Kairos.new(time, pattern).multiply(numerator).divide(denominator); }; /** - * Returns a time expression representing the time between starting time and ending time + * Returns a time expression representing the time between starting time and ending time. * * @memberof module:Kairos * @method getInterval - * @param {String|Number} time1 time expression representing the starting time - * @param {String|Number} time2 time expression representing the ending time - * @returns {String} - */ - Kairos.getInterval = function (starting, ending) { - var st = new Kairos.Gnomon(starting); - var en = new Kairos.Gnomon(ending); - if (st.compareTo(en) > 0) { - throw new Error('Starting time must be bigger than ending time'); - } - return en.minus(st).toExpression(); + * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 + */ + Kairos.getInterval = function (time1, time2, pattern) { + return Kairos.new(time1, pattern).minus(time2, pattern).toAbsolute(); }; /** - * Converts the given time expression to milliseconds + * Converts the given time expression to milliseconds. * * @memberof module:Kairos * @method toMilliseconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total milliseconds in the time expression */ - Kairos.toMilliseconds = function (expression) { - return Kairos.with(expression).toMilliseconds(); + Kairos.toMilliseconds = function (time, pattern) { + return Kairos.new(time, pattern).toMilliseconds(); }; /** - * Converts the given time expression to seconds + * Converts the given time expression to seconds. * * @memberof module:Kairos * @method toSeconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total seconds in the time expression */ - Kairos.toSeconds = function (expression) { - return Kairos.with(expression).toSeconds(); + Kairos.toSeconds = function (time, pattern) { + return Kairos.new(time, pattern).toSeconds(); }; /** - * Converts the given time expression to minutes + * Converts the given time expression to minutes. * * @memberof module:Kairos * @method toMinutes - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total minutes in the time expression */ - Kairos.toMinutes = function (expression) { - return Kairos.with(expression).toMinutes(); + Kairos.toMinutes = function (time, pattern) { + return Kairos.new(time, pattern).toMinutes(); }; /** - * Converts the given time expression to hours + * Converts the given time expression to hours. * * @memberof module:Kairos * @method toHours - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total hours in the time expression */ - Kairos.toHours = function (expression) { - return Kairos.with(expression).toHours(); + Kairos.toHours = function (time, pattern) { + return Kairos.new(time, pattern).toHours(); }; /** * Compares first time with second time and returns -1, 0 or 1 if first value - * is smaller, equals or bigger than second value + * is smaller, equals or bigger than second value. * * @memberof module:Kairos * @method compare - * @param {String|Number} time1 Time expression - * @param {String|Number} time2 Time expression for comparation - * @returns {Number} + * @param {String|Number} comparand Time to compare with + * @param {String|Number} comparator Time to be compared with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.compare = function (time1, time2) { - return Kairos.with(time1).compareTo(time2); + Kairos.compare = function (comparand, comparator, pattern) { + return Kairos.new(comparand, pattern).compareTo(comparator, pattern); }; /** - * Returns the minimum value from the given values + * Returns the minimum value from the given values. * * @memberof module:Kairos * @method min - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ - Kairos.min = function (values) { + Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() < current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; }); - - return (min instanceof Kairos.Gnomon) ? min.toExpression() : new Kairos.Gnomon(min).toExpression(); + + return Kairos.new(min, pattern); }; /** - * Returns the maximum value from the given values + * Returns the maximum value from the given values. * * @memberof module:Kairos * @method max - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {String} Kairos.Engine instance with the greatest value found in the list */ - Kairos.max = function (values) { + Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var max = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() > current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) > 0 ? previous : current; }); - return (max instanceof Kairos.Gnomon) ? max.toExpression() : new Kairos.Gnomon(max).toExpression(); + return Kairos.new(max, pattern); }; // Node.js if (typeof module === 'object' && module.exports) { - //=include /engine/Gnomon.js + //=include /locales/en.js + //=include /locales/pt-BR.js + //=include /Lexicon.js + //=include /Engine.js module.exports = Kairos; } // AMD / RequireJS @@ -289,8 +360,210 @@ (function () { 'use strict'; + Kairos.locales.en = { + HOURS: { singular: 'hour', plural: 'hours' }, + MINUTES: { singular: 'minute', plural: 'minutes' }, + SECONDS: { singular: 'second', plural: 'seconds' }, + MILLISECONDS: { singular: 'millisecond', plural: 'milliseconds' } + }; +}()); +(function () { + 'use strict'; + + Kairos.locales['pt-BR'] = { + HOURS: { singular: 'hora', plural: 'horas' }, + MINUTES: { singular: 'minuto', plural: 'minutos' }, + SECONDS: { singular: 'segundo', plural: 'segundos' }, + MILLISECONDS: { singular: 'milissegundo', plural: 'milissegundos' } + }; +}()); +/** + * @module Kairos.Lexicon + */ +;(function () { + + 'use strict'; + + /** + * @type {{HOURS: string, MINUTES: string, SECONDS: string, MILLISECONDS: string}} + */ + var TOKENS = { + SIGN: '#', HOURS: 'h', MINUTES: 'm', + SECONDS: 's', MILLISECONDS: 'S' + }; + + Kairos.Lexicon = {}; + + /** + * Gets a regex from a pattern. + * + * @param {String} [Kairos pattern] pattern Pattern to convert + * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); + * @returns {RegExp} + */ + Kairos.Lexicon.getValidator = function (pattern) { + if (typeof pattern !== 'string') { + pattern = Kairos._pattern; + } + if (pattern === Kairos._pattern) { + return Kairos._validator; + } + + var regex = ''; + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + regex += '^[+-]?'; + break; + case TOKENS.HOURS: + case TOKENS.MINUTES: + case TOKENS.SECONDS: + case TOKENS.MILLISECONDS: + regex += '\\d'; + break; + default: + regex += cur.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + } + + return new RegExp(regex); + }; + + /** + * Validates if given expression matches the current pattern. + * + * @param {String} expression Time expression to be validated + * @param {String} [Kairos pattern] pattern Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @returns {Boolean} True if expression is valid, false if expression is invalid + */ + Kairos.Lexicon.validate = function (expression, pattern) { + return Kairos.Lexicon.getValidator(pattern).test(expression); + }; + + /** + * Parses given time expression to a Kairos.Engine instance. + * + * @param {String} expression Time expression to be parsed + * @param {String} [Kairos pattern] pattern Pattern to parse + * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); + * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine + */ + Kairos.Lexicon.parse = function (expression, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + if (!Kairos.Lexicon.validate(expression, pattern)) { + throw new Error('Cannot parse expression. Time format doesn\'t match the current time pattern.'); + } + + var sign = true, hours = '', minutes = '', seconds = '', milliseconds = ''; + + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + var validSign = (['+', '-'].indexOf(expression[i]) !== -1); + if (!validSign) { + pattern = pattern.slice(0, i) + pattern.slice(i + 1); + len--; + i--; + } else { + sign = expression[i] === '+'; + } + break; + case TOKENS.HOURS: + hours += expression[i]; + break; + case TOKENS.MINUTES: + minutes += expression[i]; + break; + case TOKENS.SECONDS: + seconds += expression[i]; + break; + case TOKENS.MILLISECONDS: + milliseconds += expression[i]; + break; + } + } + + var result = Kairos.new() + .setHours(hours ? +hours : 0) + .setMinutes(minutes ? +minutes : 0) + .setSeconds(seconds ? +seconds : 0) + .setMilliseconds(milliseconds ? +milliseconds : 0); + + if (!sign) { + result.milliseconds =- result.milliseconds; + } + + return result; + }; + + /** + * Returns a formated string from an Kairos.Engine instance. + * + * @param {Kairos.Engine} instance The instance to format + * @param {String} [Kairos pattern] pattern Pattern to format + * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); + * @returns {String} Formated time expression + */ + Kairos.Lexicon.format = function (instance, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + + var sign = instance.milliseconds >= 0, + hours = String(instance.getHours()), + minutes = String(instance.getMinutes()), + seconds = String(instance.getSeconds()), + milliseconds = String(instance.getMilliseconds()); + + var result = ''; + for (var i = pattern.length - 1; i >= 0; i--) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + result = (sign ? '+' : '-') + result; + break; + case TOKENS.HOURS: + result = (hours.slice(-1) || '0') + result; + if (hours.length > 0) { + hours = hours.slice(0, hours.length - 1); + } + break; + case TOKENS.MINUTES: + result = (minutes.slice(-1) || '0') + result; + if (minutes.length > 0) { + minutes = minutes.slice(0, minutes.length - 1); + } + break; + case TOKENS.SECONDS: + result = (seconds.slice(-1) || '0') + result; + if (seconds.length > 0) { + seconds = seconds.slice(0, seconds.length - 1); + } + break; + case TOKENS.MILLISECONDS: + result = (milliseconds.slice(-1) || '0') + result; + if (milliseconds.length > 0) { + milliseconds = milliseconds.slice(0, milliseconds.length - 1); + } + break; + default: + result = cur + result; + } + } + + return result; + }; +}()); +;(function () { + + 'use strict'; + /** - * * @type {{SECOND: number, MINUTE: number, HOUR: number}} */ var MILLIS = { @@ -300,73 +573,56 @@ }; /** - * Gnomon is the time engine for Kairos. It's name references the first solar clock ever made. + * Kairos time engine. * - * @param {String|Number} expression Time expression + * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance + * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ - Kairos.Gnomon = function (expression) { - if (typeof expression === 'number') { + Kairos.Engine = function (expression, pattern) { + if (!expression) { + return; + } - this.milliseconds = expression; + if (expression instanceof Kairos.Engine) { + return expression; + } - } else if (typeof expression === 'string' && expression.length > 0) { - - if (!Kairos.validateExpression(expression)) { - throw new Error('Invalid time expression'); - } + if (typeof expression === 'number') { + return this.milliseconds = expression; + } - var timeSteps = expression.split(':'); - var positive = expression.slice(0, 1)[0] !== '-'; - - for (var i = 0, len = timeSteps.length; i < len; i++) { - var timeStep = timeSteps[i]; - - timeStep = Math.abs(timeStep); - switch (i) { - case 0: - this.milliseconds = _parse(this, MILLIS.HOUR, timeStep); - break; - case 1: - this.milliseconds = _parse(this, MILLIS.MINUTE, timeStep); - break; - case 2: - this.milliseconds = _parse(this, MILLIS.SECOND, timeStep); - break; - case 3: - this.milliseconds = _parse(this, 1, timeStep); - break; - } - } - if (!positive) { - this.milliseconds = -Math.abs(this.milliseconds); - } + if (typeof expression === 'string' && expression.length > 0) { + return new Kairos.Lexicon.parse(expression, pattern); } + + throw new Error('Invalid arguments'); }; /** - * @param {Kairos.Gnomon} instance + * @param {Kairos.Engine} instance * @param {Number} millis * @param {Number} time * @returns {Number} * @private */ - var _parse = function (instance, millis, time) { + Kairos.Engine.prototype._resolveStep = function (millis, time) { switch (millis) { case 1: - instance.removeMilliseconds(instance.getMilliseconds()); + this.removeMilliseconds(this.getMilliseconds()); break; case MILLIS.SECOND: - instance.removeSeconds(instance.getSeconds()); + this.removeSeconds(this.getSeconds()); break; case MILLIS.MINUTE: - instance.removeMinutes(instance.getMinutes()); + this.removeMinutes(this.getMinutes()); break; case MILLIS.HOUR: - instance.removeHours(instance.getHours()); + this.removeHours(this.getHours()); break; } - return instance.milliseconds + (time * millis); + return this.milliseconds + (time * millis); }; /** @@ -374,271 +630,305 @@ * @default 0 * @protected */ - Kairos.Gnomon.prototype.milliseconds = 0; + Kairos.Engine.prototype.milliseconds = 0; /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * Sets hours fraction in the current instance. + * + * @param {Number} hours Hours to set + * @example new Kairos.Engine('01:00').setHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setHours = function (hours) { - this.milliseconds = _parse(this, MILLIS.HOUR, hours); + Kairos.Engine.prototype.setHours = function (hours) { + this.milliseconds = this._resolveStep(MILLIS.HOUR, hours); return this; }; /** - * - * @returns {*|Number} + * Gets hours fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getHours(); + * @returns {Number} Hours fraction from the instance */ - Kairos.Gnomon.prototype.getHours = function () { + Kairos.Engine.prototype.getHours = function () { return Math.trunc(this.milliseconds / MILLIS.HOUR); }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Sets minutes fraction in the current instance. + * + * @param {Number} minutes Minutes to set + * @example new Kairos.Engine('01:00').setMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setMinutes = function (minutes) { - this.milliseconds = _parse(this, MILLIS.MINUTE, minutes); + Kairos.Engine.prototype.setMinutes = function (minutes) { + this.milliseconds = this._resolveStep(MILLIS.MINUTE, minutes); return this; }; /** - * - * @returns {*|Number} + * Gets minutes fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMinutes(); + * @returns {Number} Minutes fraction from the instance */ - Kairos.Gnomon.prototype.getMinutes = function () { + Kairos.Engine.prototype.getMinutes = function () { return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toHours()) * MILLIS.HOUR)) / MILLIS.MINUTE); }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Sets seconds fraction in the current instance. + * + * @param {Number} seconds Seconds to set + * @example new Kairos.Engine('01:00').setSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setSeconds = function (seconds) { - this.milliseconds = _parse(this, MILLIS.SECOND, seconds); + Kairos.Engine.prototype.setSeconds = function (seconds) { + this.milliseconds = this._resolveStep(MILLIS.SECOND, seconds); return this; }; /** - * - * @returns {*|Number} + * Gets seconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getSeconds(); + * @returns {Number} Seconds fraction from the instance */ - Kairos.Gnomon.prototype.getSeconds = function () { + Kairos.Engine.prototype.getSeconds = function () { return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toMinutes()) * MILLIS.MINUTE)) / MILLIS.SECOND); }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Sets milliseconds fraction in the current instance. + * + * @param {Number} milliseconds Milliseconds to set + * @example new Kairos.Engine('01:00').setMilliseconds(200); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setMilliseconds = function (milliseconds) { - this.milliseconds = _parse(this, 1, milliseconds); + Kairos.Engine.prototype.setMilliseconds = function (milliseconds) { + this.milliseconds = this._resolveStep(1, milliseconds); return this; }; /** - * - * @returns {Number|*} + * Gets milliseconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMilliseconds(); + * @returns {Number} Milliseconds fraction from the instance */ - Kairos.Gnomon.prototype.getMilliseconds = function () { + Kairos.Engine.prototype.getMilliseconds = function () { return Math.trunc(this.milliseconds - (Math.trunc(this.toSeconds()) * MILLIS.SECOND)); }; /** + * Adds hours to the current instance. * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * @param {Number} hours Hours to add + * @example new Kairos.Engine('01:00').addHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addHours = function (hours) { + Kairos.Engine.prototype.addHours = function (hours) { this.milliseconds += (MILLIS.HOUR * hours); return this; }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Adds minutes to the current instance. + * + * @param {Number} minutes Minutes to add + * @example new Kairos.Engine('01:00').addMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addMinutes = function (minutes) { + Kairos.Engine.prototype.addMinutes = function (minutes) { this.milliseconds += (MILLIS.MINUTE * minutes); return this; }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Adds seconds in the current instance. + * + * @param {Number} seconds Seconds to add + * @example new Kairos.Engine('01:00').addSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addSeconds = function (seconds) { + Kairos.Engine.prototype.addSeconds = function (seconds) { this.milliseconds += (MILLIS.SECOND * seconds); return this; }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Adds milliseconds in the current instance. + * + * @param {Number} milliseconds Milliseconds to add + * @example new Kairos.Engine('01:00').addMilliseconds(500); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addMilliseconds = function (milliseconds) { + Kairos.Engine.prototype.addMilliseconds = function (milliseconds) { this.milliseconds += milliseconds; return this; }; /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * Removes hours from the current instance. + * + * @param {Number} hours Hours to remove + * @example new Kairos.Engine('01:00').removeHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeHours = function (hours) { + Kairos.Engine.prototype.removeHours = function (hours) { this.milliseconds -= (MILLIS.HOUR * hours); return this; }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Removes minutes from the current instance. + * + * @param {Number} minutes Minutes to remove + * @example new Kairos.Engine('01:00').removeMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeMinutes = function (minutes) { + Kairos.Engine.prototype.removeMinutes = function (minutes) { this.milliseconds -= (MILLIS.MINUTE * minutes); return this; }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Removes seconds from the current instance. + * + * @param {Number} seconds Seconds to remove + * @example new Kairos.Engine('01:00').removeSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeSeconds = function (seconds) { + Kairos.Engine.prototype.removeSeconds = function (seconds) { this.milliseconds -= (MILLIS.SECOND * seconds); return this; }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Removes milliseconds from the current instance. + * + * @example new Kairos.Engine('01:00').removeMilliseconds(50); + * @param {Number} milliseconds Milliseconds to remove + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeMilliseconds = function (milliseconds) { + Kairos.Engine.prototype.removeMilliseconds = function (milliseconds) { this.milliseconds -= milliseconds; return this; }; /** - * - * @returns {Number} hours within the time expression + * Returns total hours within the current instance. + * + * @example new Kairos.Engine('01:00').toHours(); + * @returns {Number} Hours within the current instance */ - Kairos.Gnomon.prototype.toHours = function () { + Kairos.Engine.prototype.toHours = function () { return (this.milliseconds / MILLIS.HOUR); }; /** - * - * @returns {Number} minutes within the time expression + * Returns total minutes within the current instance. + * + * @example new Kairos.Engine('01:00').toMinutes(); + * @returns {Number} Minutes within the current instance */ - Kairos.Gnomon.prototype.toMinutes = function () { + Kairos.Engine.prototype.toMinutes = function () { return (this.milliseconds / MILLIS.MINUTE); }; /** - * - * @returns {Number} seconds within the time expression + * Returns total seconds within the current instance. + * + * @example new Kairos.Engine('01:00').toSeconds(); + * @returns {Number} Seconds within the current instance */ - Kairos.Gnomon.prototype.toSeconds = function () { + Kairos.Engine.prototype.toSeconds = function () { return (this.milliseconds / MILLIS.SECOND); }; /** - * - * @returns {Number} milliseconds within the time expression + * Returns total milliseconds within the current instance. + * + * @example new Kairos.Engine('01:00').toMilliseconds(); + * @returns {Number} Milliseconds within the current instance */ - Kairos.Gnomon.prototype.toMilliseconds = function () { + Kairos.Engine.prototype.toMilliseconds = function () { return this.milliseconds; }; /** - * - * @returns {String} - */ - Kairos.Gnomon.prototype.toExpression = function () { - var expression = ''; - // Hours - var hours = Math.trunc(Math.abs(this.getHours())); - expression += ((String(hours).length > 1) ? '' : '0') + hours + ':'; - // Minutes - expression += ('00' + Math.trunc(Math.abs(this.getMinutes()))).slice(-2); - // Seconds - if (this.getSeconds() !== 0 || this.getMilliseconds() !== 0) { - expression += ':' + ('00' + Math.trunc(Math.abs(this.getSeconds()))).slice(-2); - } - // Millis - if (this.getMilliseconds() !== 0) { - expression += ':' + ('000' + Math.trunc(Math.abs(this.getMilliseconds()))).slice(-3); - } - - if (this.milliseconds < 0) { - expression = '-' + expression; - } - return expression; + * Makes the current instance's value absolute. + * + * @example new Kairos.Engine('01:00').toAbsolute(); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.toAbsolute = function () { + this.milliseconds = Math.abs(this.milliseconds); + return this; }; /** - * - * @param {Number|String|Kairos.Gnomon} addend - * @returns {Kairos.Gnomon} self + * Sums the given addend. + * + * @param {Number|String|Kairos.Engine} addend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.plus = function (addend) { - addend = (addend instanceof Kairos.Gnomon) ? addend : new Kairos.Gnomon(addend); + Kairos.Engine.prototype.plus = function (addend, pattern) { + addend = new Kairos.Engine(addend, pattern); this.milliseconds += addend.toMilliseconds(); return this; }; /** + * Subtracts the given subtrahend. * - * @param {Number|String|Kairos.Gnomon} subtrahend - * @returns {Kairos.Gnomon} self + * @param {Number|String|Kairos.Engine} subtrahend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.minus = function (subtrahend) { - subtrahend = (subtrahend instanceof Kairos.Gnomon) ? subtrahend : new Kairos.Gnomon(subtrahend); + Kairos.Engine.prototype.minus = function (subtrahend, pattern) { + subtrahend = new Kairos.Engine(subtrahend, pattern); this.milliseconds -= subtrahend.toMilliseconds(); return this; }; /** - * - * @param {Number} multiplicand - * @returns {Kairos.Gnomon} self + * Multiply by the given multiplicand. + * + * @param {Number} multiplicand Multiplicand value + * @example new Kairos.Engine('01:00').multiply(2); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.multiply = function (multiplicand) { + Kairos.Engine.prototype.multiply = function (multiplicand) { this.milliseconds *= multiplicand; return this; }; /** - * - * @param {Number} dividend - * @returns {Kairos.Gnomon} self + * Divies by the given dividend. + * + * @param {Number} divisor Divisor value + * @example new Kairos.Engine('01:00').divide(2); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.divide = function (dividend) { - this.milliseconds /= dividend; + Kairos.Engine.prototype.divide = function (divisor) { + this.milliseconds /= divisor; return this; }; /** * Compares with another instance. - * Smaller -1 - * Equals 0 - * Bigger 1 * - * @param {String|Number|Kairos.Gnomon} another Expression to compare with - * @returns {Number} + * @param {String|Number|Kairos.Engine} another Expression to compare with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').compareTo('00:30'); + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.Gnomon.prototype.compareTo = function (another) { - another = (another instanceof Kairos.Gnomon) ? another : new Kairos.Gnomon(another); + Kairos.Engine.prototype.compareTo = function (another, pattern) { + another = new Kairos.Engine(another, pattern); if (this.milliseconds < another.toMilliseconds()) { return -1; @@ -650,4 +940,16 @@ return 1; } }; + + /** + * Returns a string representation of the object. + * + * @param {String} pattern Pattern to format the time expression + * @example new Kairos.Engine('22:10').toString('hh:mm'); + * @returns {String} String representing the instance time + */ + Kairos.Engine.prototype.toString = function (pattern) { + return Kairos.Lexicon.format(this, pattern); + }; + }()); \ No newline at end of file diff --git a/build/kairos-min.js b/build/kairos-min.js index 9cd7c00..d5c3e14 100644 --- a/build/kairos-min.js +++ b/build/kairos-min.js @@ -1,9 +1,12 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v1.1.0 + * @version v2.0.0 * @link https://github.com/kairos * @license BSD-2-Clause */ -!function(){"use strict";var n,o={},t="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==t&&(n=t.Kairos),o.noConflict=function(){return t.Kairos=n,o},o.validateExpression=function(n){var o=/^[+-]?\d+(?::?\d{1,2}(?::\d{1,2}(?::\d{1,3})?)?)?$/;return o.test(n)},o["with"]=function(n){return new o.Gnomon(n)},o.plus=function(n,t){return o["with"](n).plus(t).toExpression()},o.minus=function(n,t){return o["with"](n).minus(t).toExpression()},o.multiply=function(n,t){return o["with"](n).multiply(t).toExpression()},o.divide=function(n,t){return o["with"](n).divide(t).toExpression()},o.getFraction=function(n,t,e){if(t>e)throw new Error("Improper fraction");return o["with"](n).multiply(t).divide(e).toExpression()},o.getInterval=function(n,t){var e=new o.Gnomon(n),i=new o.Gnomon(t);if(e.compareTo(i)>0)throw new Error("Starting time must be bigger than ending time");return i.minus(e).toExpression()},o.toMilliseconds=function(n){return o["with"](n).toMilliseconds()},o.toSeconds=function(n){return o["with"](n).toSeconds()},o.toMinutes=function(n){return o["with"](n).toMinutes()},o.toHours=function(n){return o["with"](n).toHours()},o.compare=function(n,t){return o["with"](n).compareTo(t)},o.min=function(n){n instanceof Array||(n=Array.prototype.slice.call(arguments));var t=n.reduce(function(n,t){return n instanceof o.Gnomon||(n=new o.Gnomon(n?n:0)),t instanceof o.Gnomon||(t=new o.Gnomon(t?t:0)),n.toMilliseconds()t.toMilliseconds()?n:t});return t instanceof o.Gnomon?t.toExpression():new o.Gnomon(t).toExpression()},"object"==typeof module&&module.exports?module.exports=o:"function"==typeof define&&define.amd?define([],function(){return o}):t.Kairos=o,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); -!function(){"use strict";var o={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Gnomon=function(i){if("number"==typeof i)this.milliseconds=i;else if("string"==typeof i&&i.length>0){if(!Kairos.validateExpression(i))throw new Error("Invalid time expression");for(var t=i.split(":"),n="-"!==i.slice(0,1)[0],e=0,r=t.length;r>e;e++){var c=t[e];switch(c=Math.abs(c),e){case 0:this.milliseconds=s(this,o.HOUR,c);break;case 1:this.milliseconds=s(this,o.MINUTE,c);break;case 2:this.milliseconds=s(this,o.SECOND,c);break;case 3:this.milliseconds=s(this,1,c)}}n||(this.milliseconds=-Math.abs(this.milliseconds))}};var s=function(s,i,t){switch(i){case 1:s.removeMilliseconds(s.getMilliseconds());break;case o.SECOND:s.removeSeconds(s.getSeconds());break;case o.MINUTE:s.removeMinutes(s.getMinutes());break;case o.HOUR:s.removeHours(s.getHours())}return s.milliseconds+t*i};Kairos.Gnomon.prototype.milliseconds=0,Kairos.Gnomon.prototype.setHours=function(i){return this.milliseconds=s(this,o.HOUR,i),this},Kairos.Gnomon.prototype.getHours=function(){return Math.trunc(this.milliseconds/o.HOUR)},Kairos.Gnomon.prototype.setMinutes=function(i){return this.milliseconds=s(this,o.MINUTE,i),this},Kairos.Gnomon.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*o.HOUR)/o.MINUTE)},Kairos.Gnomon.prototype.setSeconds=function(i){return this.milliseconds=s(this,o.SECOND,i),this},Kairos.Gnomon.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*o.MINUTE)/o.SECOND)},Kairos.Gnomon.prototype.setMilliseconds=function(o){return this.milliseconds=s(this,1,o),this},Kairos.Gnomon.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*o.SECOND)},Kairos.Gnomon.prototype.addHours=function(s){return this.milliseconds+=o.HOUR*s,this},Kairos.Gnomon.prototype.addMinutes=function(s){return this.milliseconds+=o.MINUTE*s,this},Kairos.Gnomon.prototype.addSeconds=function(s){return this.milliseconds+=o.SECOND*s,this},Kairos.Gnomon.prototype.addMilliseconds=function(o){return this.milliseconds+=o,this},Kairos.Gnomon.prototype.removeHours=function(s){return this.milliseconds-=o.HOUR*s,this},Kairos.Gnomon.prototype.removeMinutes=function(s){return this.milliseconds-=o.MINUTE*s,this},Kairos.Gnomon.prototype.removeSeconds=function(s){return this.milliseconds-=o.SECOND*s,this},Kairos.Gnomon.prototype.removeMilliseconds=function(o){return this.milliseconds-=o,this},Kairos.Gnomon.prototype.toHours=function(){return this.milliseconds/o.HOUR},Kairos.Gnomon.prototype.toMinutes=function(){return this.milliseconds/o.MINUTE},Kairos.Gnomon.prototype.toSeconds=function(){return this.milliseconds/o.SECOND},Kairos.Gnomon.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Gnomon.prototype.toExpression=function(){var o="",s=Math.trunc(Math.abs(this.getHours()));return o+=(String(s).length>1?"":"0")+s+":",o+=("00"+Math.trunc(Math.abs(this.getMinutes()))).slice(-2),(0!==this.getSeconds()||0!==this.getMilliseconds())&&(o+=":"+("00"+Math.trunc(Math.abs(this.getSeconds()))).slice(-2)),0!==this.getMilliseconds()&&(o+=":"+("000"+Math.trunc(Math.abs(this.getMilliseconds()))).slice(-3)),this.milliseconds<0&&(o="-"+o),o},Kairos.Gnomon.prototype.plus=function(o){return o=o instanceof Kairos.Gnomon?o:new Kairos.Gnomon(o),this.milliseconds+=o.toMilliseconds(),this},Kairos.Gnomon.prototype.minus=function(o){return o=o instanceof Kairos.Gnomon?o:new Kairos.Gnomon(o),this.milliseconds-=o.toMilliseconds(),this},Kairos.Gnomon.prototype.multiply=function(o){return this.milliseconds*=o,this},Kairos.Gnomon.prototype.divide=function(o){return this.milliseconds/=o,this},Kairos.Gnomon.prototype.compareTo=function(o){return o=o instanceof Kairos.Gnomon?o:new Kairos.Gnomon(o),this.millisecondso.toMilliseconds()?1:void 0}}(); \ No newline at end of file +!function(){"use strict";var n={};n._locales={},n._locale=n._locales.en,n._pattern="#hh:mm:ss.SSS",n._validator=/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/;var e,t="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==t&&(e=t.Kairos),n.noConflict=function(){return t.Kairos=e,n},n.setLocale=function(e){return"string"==typeof e?n._locale=n._locales[e]:"object"==typeof e?n._locale=e:void 0},n.getLocale=function(){return n._locale},n.setPattern=function(e){n._pattern=e,n._validator=n.Lexicon.getValidator(e)},n.getPattern=function(){return n._pattern},n.validate=function(e,t){return n.Lexicon.validate(e,t)},n["new"]=function(e,t){return new n.Engine(e,t)},n.absolute=function(e,t){return n["new"](e,t).toAbsolute()},n.plus=function(e,t,o){return n["new"](e,o).plus(t,o)},n.minus=function(e,t,o){return n["new"](e,o).minus(t,o)},n.multiply=function(e,t,o){return n["new"](e,o).multiply(t)},n.divide=function(e,t,o){return n["new"](e,o).divide(t)},n.getFraction=function(e,t,o,r){if(t>o)throw new Error("Improper fraction");return n["new"](e,r).multiply(t).divide(o)},n.getInterval=function(e,t,o){return n["new"](e,o).minus(t,o).toAbsolute()},n.toMilliseconds=function(e,t){return n["new"](e,t).toMilliseconds()},n.toSeconds=function(e,t){return n["new"](e,t).toSeconds()},n.toMinutes=function(e,t){return n["new"](e,t).toMinutes()},n.toHours=function(e,t){return n["new"](e,t).toHours()},n.compare=function(e,t,o){return n["new"](e,o).compareTo(t,o)},n.min=function(e,t){e instanceof Array||(e=Array.prototype.slice.call(arguments));var o=e.reduce(function(e,o){return n["new"](e,t).compareTo(o,t)<0?e:o});return n["new"](o,t)},n.max=function(e,t){e instanceof Array||(e=Array.prototype.slice.call(arguments));var o=e.reduce(function(e,o){return n["new"](e,t).compareTo(o,t)>0?e:o});return n["new"](o,t)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):t.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); +!function(){"use strict";Kairos.locales.en={HOURS:{singular:"hour",plural:"hours"},MINUTES:{singular:"minute",plural:"minutes"},SECONDS:{singular:"second",plural:"seconds"},MILLISECONDS:{singular:"millisecond",plural:"milliseconds"}}}(); +!function(){"use strict";Kairos.locales["pt-BR"]={HOURS:{singular:"hora",plural:"horas"},MINUTES:{singular:"minuto",plural:"minutos"},SECONDS:{singular:"segundo",plural:"segundos"},MILLISECONDS:{singular:"milissegundo",plural:"milissegundos"}}}(); +!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(r){if("string"!=typeof r&&(r=Kairos._pattern),r===Kairos._pattern)return Kairos._validator;for(var a="",s=0,t=r.length;t>s;s++){var i=r[s];switch(i){case e.SIGN:a+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:a+="\\d";break;default:a+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(a)},Kairos.Lexicon.validate=function(e,r){return Kairos.Lexicon.getValidator(r).test(e)},Kairos.Lexicon.parse=function(r,a){if(a||(a=Kairos._pattern),!Kairos.Lexicon.validate(r,a))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=a.length;l>o;o++){var S=a[o];switch(S){case e.SIGN:var g=-1!==["+","-"].indexOf(r[o]);g?s="+"===r[o]:(a=a.slice(0,o)+a.slice(o+1),l--,o--);break;case e.HOURS:t+=r[o];break;case e.MINUTES:i+=r[o];break;case e.SECONDS:n+=r[o];break;case e.MILLISECONDS:c+=r[o]}}var h=Kairos["new"]().setHours(t?+t:0).setMinutes(i?+i:0).setSeconds(n?+n:0).setMilliseconds(c?+c:0);return s||(h.milliseconds=-h.milliseconds),h},Kairos.Lexicon.format=function(r,a){a||(a=Kairos._pattern);for(var s=r.milliseconds>=0,t=String(r.getHours()),i=String(r.getMinutes()),n=String(r.getSeconds()),c=String(r.getMilliseconds()),o="",l=a.length-1;l>=0;l--){var S=a[l];switch(S){case e.SIGN:o=(s?"+":"-")+o;break;case e.HOURS:o=(t.slice(-1)||"0")+o,t.length>0&&(t=t.slice(0,t.length-1));break;case e.MINUTES:o=(i.slice(-1)||"0")+o,i.length>0&&(i=i.slice(0,i.length-1));break;case e.SECONDS:o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.MILLISECONDS:o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;default:o=S+o}}return o}}(); +!function(){"use strict";var i={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Engine=function(i,t){if(i){if(i instanceof Kairos.Engine)return i;if("number"==typeof i)return this.milliseconds=i;if("string"==typeof i&&i.length>0)return new Kairos.Lexicon.parse(i,t);throw new Error("Invalid arguments")}},Kairos.Engine.prototype._resolveStep=function(t,n){switch(t){case 1:this.removeMilliseconds(this.getMilliseconds());break;case i.SECOND:this.removeSeconds(this.getSeconds());break;case i.MINUTE:this.removeMinutes(this.getMinutes());break;case i.HOUR:this.removeHours(this.getHours())}return this.milliseconds+n*t},Kairos.Engine.prototype.milliseconds=0,Kairos.Engine.prototype.setHours=function(t){return this.milliseconds=this._resolveStep(i.HOUR,t),this},Kairos.Engine.prototype.getHours=function(){return Math.trunc(this.milliseconds/i.HOUR)},Kairos.Engine.prototype.setMinutes=function(t){return this.milliseconds=this._resolveStep(i.MINUTE,t),this},Kairos.Engine.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*i.HOUR)/i.MINUTE)},Kairos.Engine.prototype.setSeconds=function(t){return this.milliseconds=this._resolveStep(i.SECOND,t),this},Kairos.Engine.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*i.MINUTE)/i.SECOND)},Kairos.Engine.prototype.setMilliseconds=function(i){return this.milliseconds=this._resolveStep(1,i),this},Kairos.Engine.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*i.SECOND)},Kairos.Engine.prototype.addHours=function(t){return this.milliseconds+=i.HOUR*t,this},Kairos.Engine.prototype.addMinutes=function(t){return this.milliseconds+=i.MINUTE*t,this},Kairos.Engine.prototype.addSeconds=function(t){return this.milliseconds+=i.SECOND*t,this},Kairos.Engine.prototype.addMilliseconds=function(i){return this.milliseconds+=i,this},Kairos.Engine.prototype.removeHours=function(t){return this.milliseconds-=i.HOUR*t,this},Kairos.Engine.prototype.removeMinutes=function(t){return this.milliseconds-=i.MINUTE*t,this},Kairos.Engine.prototype.removeSeconds=function(t){return this.milliseconds-=i.SECOND*t,this},Kairos.Engine.prototype.removeMilliseconds=function(i){return this.milliseconds-=i,this},Kairos.Engine.prototype.toHours=function(){return this.milliseconds/i.HOUR},Kairos.Engine.prototype.toMinutes=function(){return this.milliseconds/i.MINUTE},Kairos.Engine.prototype.toSeconds=function(){return this.milliseconds/i.SECOND},Kairos.Engine.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Engine.prototype.toAbsolute=function(){return this.milliseconds=Math.abs(this.milliseconds),this},Kairos.Engine.prototype.plus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds+=i.toMilliseconds(),this},Kairos.Engine.prototype.minus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds-=i.toMilliseconds(),this},Kairos.Engine.prototype.multiply=function(i){return this.milliseconds*=i,this},Kairos.Engine.prototype.divide=function(i){return this.milliseconds/=i,this},Kairos.Engine.prototype.compareTo=function(i,t){return i=new Kairos.Engine(i,t),this.millisecondsi.toMilliseconds()?1:void 0},Kairos.Engine.prototype.toString=function(i){return Kairos.Lexicon.format(this,i)}}(); \ No newline at end of file diff --git a/build/kairos-node.js b/build/kairos-node.js index c0c8a24..3064c34 100644 --- a/build/kairos-node.js +++ b/build/kairos-node.js @@ -1,17 +1,26 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v1.1.0 + * @version v2.0.0 * @link https://github.com/kairos * @license BSD-2-Clause */ /** * @module Kairos */ -(function () { +;(function () { + 'use strict'; var Kairos = {}; + Kairos._locales = {}; + + // Set default locale + Kairos._locale = Kairos._locales.en; + // Set default pattern + Kairos._pattern = '#hh:mm:ss.SSS'; + // Set default regex + Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; // global on the server, window in the browser var previous_Kairos; @@ -28,11 +37,11 @@ } /** - * Avoid conflict in case of another instance of Kairos is already in the scope + * Avoid conflict in case of another instance of Kairos is already in the scope. * * @memberof module:Kairos * @method noConflict - * @returns {Object} + * @returns {Object} Previous Kairos object */ Kairos.noConflict = function () { root.Kairos = previous_Kairos; @@ -40,229 +49,288 @@ }; /** - * Validates if the given expression is valid. + * Sets Kairos locale. + * + * @param {String|Object} locale A locale from Kairos.locales or a compatible locale object + * @example Kairos.setLocale('en'); + */ + Kairos.setLocale = function (locale) { + if (typeof locale === 'string') { + return Kairos._locale = Kairos._locales[locale]; + } + if (typeof locale === 'object') { + return Kairos._locale = locale; + } + }; + + /** + * Gets Kairos current locale. + * + * @returns {String} Current locale + */ + Kairos.getLocale = function () { + return Kairos._locale; + }; + + /** + * Sets Kairos time expression pattern. + * Pattern structure is the following: + * # -> sign + * h -> hours + * m -> minutes + * s -> seconds + * S -> milliseconds + * + * @param {String} pattern The pattern to parse and format time expressions + * @example Kairos.setPattern('hh:mm:ss.fff'); + */ + Kairos.setPattern = function (pattern) { + Kairos._pattern = pattern; + Kairos._validator = Kairos.Lexicon.getValidator(pattern); + }; + + /** + * Gets current Kairos pattern. + * + * @returns {String} Current Kairos pattern + */ + Kairos.getPattern = function () { + return Kairos._pattern; + }; + + /** + * Validates the give expression with the current or given pattern. + * + * @param {String} expression Time expression to validate + * @param {String} pattern Pattern to test the expression + * @example Kairos.validate('10:30', 'hh:mm'); + * @returns {Boolean} True if valid, false if invalid + */ + Kairos.validate = function (expression, pattern) { + return Kairos.Lexicon.validate(expression, pattern); + }; + + /** + * Returns a new Kairos.Engine instance. * * @memberof module:Kairos - * @method validateExpression - * @param {String|Number} expression Time expression - * @returns {Boolean} + * @method new + * @param {String|Number|kairos.Engine} time Time expression to create an instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ - Kairos.validateExpression = function (expression) { - var regex = /^[+-]?\d+(?::?\d{1,2}(?::\d{1,2}(?::\d{1,3})?)?)?$/; - return regex.test(expression); + Kairos.new = function (time, pattern) { + return new Kairos.Engine(time, pattern); }; /** - * Return a Kairos.Gnomon instance. - * + * Returns an instance of Kairos.Engine with absolute time. + * * @memberof module:Kairos - * @method with - * @param {String|Number} expression Time expression - * @returns {Kairos.Gnomon} + * @method absolute + * @param {String|Number|kairos.Engine} time Time expression to get its absolute value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ - Kairos.with = function (expression) { - return new Kairos.Gnomon(expression); + Kairos.absolute = function (time, pattern) { + return Kairos.new(time, pattern).toAbsolute(); }; /** - * Sums augend time with addend time + * Sums augend time with addend time. * * @memberof module:Kairos * @method plus - * @param {String|Number} augend Augend time expression - * @param {String|Number} addend Addend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} augend Augend time expression + * @param {String|Number|kairos.Engine} addend Addend time expression + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ - Kairos.plus = function (augend, addend) { - return Kairos.with(augend).plus(addend).toExpression(); + Kairos.plus = function (augend, addend, pattern) { + return Kairos.new(augend, pattern).plus(addend, pattern); }; /** - * Subtracts minuend time with subtrahend time + * Subtracts minuend time with subtrahend time. * * @memberof module:Kairos * @method minus - * @param {String|Number} minuend Minuend time expression - * @param {String|Number} subtrahend Subtrahend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} minuend Minuend time expression + * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ - Kairos.minus = function (minuend, subtrahend) { - return Kairos.with(minuend).minus(subtrahend).toExpression(); + Kairos.minus = function (minuend, subtrahend, pattern) { + return Kairos.new(minuend, pattern).minus(subtrahend, pattern); }; /** - * Multiplies multiplier by the multiplicand + * Multiplies multiplier by the multiplicand. * * @memberof module:Kairos * @method multiply - * @param {String|Number} multiplier Multiplier time expression - * @param {String|Number} multiplicand Multiplicand number - * @returns {String} + * @param {String|Number|kairos.Engine} multiplier Multiplier time expression + * @param {Number} multiplicand Multiplicand value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ - Kairos.multiply = function (multiplier, multiplicand) { - return Kairos.with(multiplier).multiply(multiplicand).toExpression(); + Kairos.multiply = function (multiplier, multiplicand, pattern) { + return Kairos.new(multiplier, pattern).multiply(multiplicand); }; /** - * Divides dividend by the divisor + * Divides dividend by the divisor. * * @memberof module:Kairos * @method divide - * @param {String|Number} dividend Dividend time expression - * @param {Number} divisor Dividor number - * @returns {String} + * @param {String|Number|kairos.Engine} dividend Dividend time expression + * @param {Number} divisor Divisor value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with division result */ - Kairos.divide = function (dividend, divisor) { - return Kairos.with(dividend).divide(divisor).toExpression(); + Kairos.divide = function (dividend, divisor, pattern) { + return Kairos.new(dividend, pattern).divide(divisor); }; /** - * Returns a fraction of the current time + * Returns a fraction of the current time. * * @memberof module:Kairos * @method getFraction - * @param {String|Number} time - * @param {Number} numerator - * @param {Number} denominator - * @returns {String} + * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction + * @param {Number} numerator Numerator value + * @param {Number} denominator Denominator value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ - Kairos.getFraction = function (time, numerator, denominator) { + Kairos.getFraction = function (time, numerator, denominator, pattern) { if (numerator > denominator) { throw new Error('Improper fraction'); } - return Kairos.with(time).multiply(numerator).divide(denominator).toExpression(); + return Kairos.new(time, pattern).multiply(numerator).divide(denominator); }; /** - * Returns a time expression representing the time between starting time and ending time + * Returns a time expression representing the time between starting time and ending time. * * @memberof module:Kairos * @method getInterval - * @param {String|Number} time1 time expression representing the starting time - * @param {String|Number} time2 time expression representing the ending time - * @returns {String} + * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 */ - Kairos.getInterval = function (starting, ending) { - var st = new Kairos.Gnomon(starting); - var en = new Kairos.Gnomon(ending); - if (st.compareTo(en) > 0) { - throw new Error('Starting time must be bigger than ending time'); - } - return en.minus(st).toExpression(); + Kairos.getInterval = function (time1, time2, pattern) { + return Kairos.new(time1, pattern).minus(time2, pattern).toAbsolute(); }; /** - * Converts the given time expression to milliseconds + * Converts the given time expression to milliseconds. * * @memberof module:Kairos * @method toMilliseconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total milliseconds in the time expression */ - Kairos.toMilliseconds = function (expression) { - return Kairos.with(expression).toMilliseconds(); + Kairos.toMilliseconds = function (time, pattern) { + return Kairos.new(time, pattern).toMilliseconds(); }; /** - * Converts the given time expression to seconds + * Converts the given time expression to seconds. * * @memberof module:Kairos * @method toSeconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total seconds in the time expression */ - Kairos.toSeconds = function (expression) { - return Kairos.with(expression).toSeconds(); + Kairos.toSeconds = function (time, pattern) { + return Kairos.new(time, pattern).toSeconds(); }; /** - * Converts the given time expression to minutes + * Converts the given time expression to minutes. * * @memberof module:Kairos * @method toMinutes - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total minutes in the time expression */ - Kairos.toMinutes = function (expression) { - return Kairos.with(expression).toMinutes(); + Kairos.toMinutes = function (time, pattern) { + return Kairos.new(time, pattern).toMinutes(); }; /** - * Converts the given time expression to hours + * Converts the given time expression to hours. * * @memberof module:Kairos * @method toHours - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total hours in the time expression */ - Kairos.toHours = function (expression) { - return Kairos.with(expression).toHours(); + Kairos.toHours = function (time, pattern) { + return Kairos.new(time, pattern).toHours(); }; /** * Compares first time with second time and returns -1, 0 or 1 if first value - * is smaller, equals or bigger than second value + * is smaller, equals or bigger than second value. * * @memberof module:Kairos * @method compare - * @param {String|Number} time1 Time expression - * @param {String|Number} time2 Time expression for comparation - * @returns {Number} + * @param {String|Number} comparand Time to compare with + * @param {String|Number} comparator Time to be compared with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.compare = function (time1, time2) { - return Kairos.with(time1).compareTo(time2); + Kairos.compare = function (comparand, comparator, pattern) { + return Kairos.new(comparand, pattern).compareTo(comparator, pattern); }; /** - * Returns the minimum value from the given values + * Returns the minimum value from the given values. * * @memberof module:Kairos * @method min - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ - Kairos.min = function (values) { + Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() < current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; }); - - return (min instanceof Kairos.Gnomon) ? min.toExpression() : new Kairos.Gnomon(min).toExpression(); + + return Kairos.new(min, pattern); }; /** - * Returns the maximum value from the given values + * Returns the maximum value from the given values. * * @memberof module:Kairos * @method max - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {String} Kairos.Engine instance with the greatest value found in the list */ - Kairos.max = function (values) { + Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var max = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() > current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) > 0 ? previous : current; }); - return (max instanceof Kairos.Gnomon) ? max.toExpression() : new Kairos.Gnomon(max).toExpression(); + return Kairos.new(max, pattern); }; // Node.js @@ -270,8 +338,210 @@ (function () { 'use strict'; + Kairos.locales.en = { + HOURS: { singular: 'hour', plural: 'hours' }, + MINUTES: { singular: 'minute', plural: 'minutes' }, + SECONDS: { singular: 'second', plural: 'seconds' }, + MILLISECONDS: { singular: 'millisecond', plural: 'milliseconds' } + }; + }()); + (function () { + 'use strict'; + + Kairos.locales['pt-BR'] = { + HOURS: { singular: 'hora', plural: 'horas' }, + MINUTES: { singular: 'minuto', plural: 'minutos' }, + SECONDS: { singular: 'segundo', plural: 'segundos' }, + MILLISECONDS: { singular: 'milissegundo', plural: 'milissegundos' } + }; + }()); + /** + * @module Kairos.Lexicon + */ + ;(function () { + + 'use strict'; + + /** + * @type {{HOURS: string, MINUTES: string, SECONDS: string, MILLISECONDS: string}} + */ + var TOKENS = { + SIGN: '#', HOURS: 'h', MINUTES: 'm', + SECONDS: 's', MILLISECONDS: 'S' + }; + + Kairos.Lexicon = {}; + + /** + * Gets a regex from a pattern. + * + * @param {String} [Kairos pattern] pattern Pattern to convert + * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); + * @returns {RegExp} + */ + Kairos.Lexicon.getValidator = function (pattern) { + if (typeof pattern !== 'string') { + pattern = Kairos._pattern; + } + if (pattern === Kairos._pattern) { + return Kairos._validator; + } + + var regex = ''; + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + regex += '^[+-]?'; + break; + case TOKENS.HOURS: + case TOKENS.MINUTES: + case TOKENS.SECONDS: + case TOKENS.MILLISECONDS: + regex += '\\d'; + break; + default: + regex += cur.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + } + + return new RegExp(regex); + }; + + /** + * Validates if given expression matches the current pattern. + * + * @param {String} expression Time expression to be validated + * @param {String} [Kairos pattern] pattern Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @returns {Boolean} True if expression is valid, false if expression is invalid + */ + Kairos.Lexicon.validate = function (expression, pattern) { + return Kairos.Lexicon.getValidator(pattern).test(expression); + }; + + /** + * Parses given time expression to a Kairos.Engine instance. + * + * @param {String} expression Time expression to be parsed + * @param {String} [Kairos pattern] pattern Pattern to parse + * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); + * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine + */ + Kairos.Lexicon.parse = function (expression, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + if (!Kairos.Lexicon.validate(expression, pattern)) { + throw new Error('Cannot parse expression. Time format doesn\'t match the current time pattern.'); + } + + var sign = true, hours = '', minutes = '', seconds = '', milliseconds = ''; + + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + var validSign = (['+', '-'].indexOf(expression[i]) !== -1); + if (!validSign) { + pattern = pattern.slice(0, i) + pattern.slice(i + 1); + len--; + i--; + } else { + sign = expression[i] === '+'; + } + break; + case TOKENS.HOURS: + hours += expression[i]; + break; + case TOKENS.MINUTES: + minutes += expression[i]; + break; + case TOKENS.SECONDS: + seconds += expression[i]; + break; + case TOKENS.MILLISECONDS: + milliseconds += expression[i]; + break; + } + } + + var result = Kairos.new() + .setHours(hours ? +hours : 0) + .setMinutes(minutes ? +minutes : 0) + .setSeconds(seconds ? +seconds : 0) + .setMilliseconds(milliseconds ? +milliseconds : 0); + + if (!sign) { + result.milliseconds =- result.milliseconds; + } + + return result; + }; + + /** + * Returns a formated string from an Kairos.Engine instance. + * + * @param {Kairos.Engine} instance The instance to format + * @param {String} [Kairos pattern] pattern Pattern to format + * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); + * @returns {String} Formated time expression + */ + Kairos.Lexicon.format = function (instance, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + + var sign = instance.milliseconds >= 0, + hours = String(instance.getHours()), + minutes = String(instance.getMinutes()), + seconds = String(instance.getSeconds()), + milliseconds = String(instance.getMilliseconds()); + + var result = ''; + for (var i = pattern.length - 1; i >= 0; i--) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + result = (sign ? '+' : '-') + result; + break; + case TOKENS.HOURS: + result = (hours.slice(-1) || '0') + result; + if (hours.length > 0) { + hours = hours.slice(0, hours.length - 1); + } + break; + case TOKENS.MINUTES: + result = (minutes.slice(-1) || '0') + result; + if (minutes.length > 0) { + minutes = minutes.slice(0, minutes.length - 1); + } + break; + case TOKENS.SECONDS: + result = (seconds.slice(-1) || '0') + result; + if (seconds.length > 0) { + seconds = seconds.slice(0, seconds.length - 1); + } + break; + case TOKENS.MILLISECONDS: + result = (milliseconds.slice(-1) || '0') + result; + if (milliseconds.length > 0) { + milliseconds = milliseconds.slice(0, milliseconds.length - 1); + } + break; + default: + result = cur + result; + } + } + + return result; + }; + }()); + ;(function () { + + 'use strict'; + /** - * * @type {{SECOND: number, MINUTE: number, HOUR: number}} */ var MILLIS = { @@ -281,73 +551,56 @@ }; /** - * Gnomon is the time engine for Kairos. It's name references the first solar clock ever made. + * Kairos time engine. * - * @param {String|Number} expression Time expression + * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance + * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ - Kairos.Gnomon = function (expression) { - if (typeof expression === 'number') { + Kairos.Engine = function (expression, pattern) { + if (!expression) { + return; + } - this.milliseconds = expression; + if (expression instanceof Kairos.Engine) { + return expression; + } - } else if (typeof expression === 'string' && expression.length > 0) { - - if (!Kairos.validateExpression(expression)) { - throw new Error('Invalid time expression'); - } + if (typeof expression === 'number') { + return this.milliseconds = expression; + } - var timeSteps = expression.split(':'); - var positive = expression.slice(0, 1)[0] !== '-'; - - for (var i = 0, len = timeSteps.length; i < len; i++) { - var timeStep = timeSteps[i]; - - timeStep = Math.abs(timeStep); - switch (i) { - case 0: - this.milliseconds = _parse(this, MILLIS.HOUR, timeStep); - break; - case 1: - this.milliseconds = _parse(this, MILLIS.MINUTE, timeStep); - break; - case 2: - this.milliseconds = _parse(this, MILLIS.SECOND, timeStep); - break; - case 3: - this.milliseconds = _parse(this, 1, timeStep); - break; - } - } - if (!positive) { - this.milliseconds = -Math.abs(this.milliseconds); - } + if (typeof expression === 'string' && expression.length > 0) { + return new Kairos.Lexicon.parse(expression, pattern); } + + throw new Error('Invalid arguments'); }; /** - * @param {Kairos.Gnomon} instance + * @param {Kairos.Engine} instance * @param {Number} millis * @param {Number} time * @returns {Number} * @private */ - var _parse = function (instance, millis, time) { + Kairos.Engine.prototype._resolveStep = function (millis, time) { switch (millis) { case 1: - instance.removeMilliseconds(instance.getMilliseconds()); + this.removeMilliseconds(this.getMilliseconds()); break; case MILLIS.SECOND: - instance.removeSeconds(instance.getSeconds()); + this.removeSeconds(this.getSeconds()); break; case MILLIS.MINUTE: - instance.removeMinutes(instance.getMinutes()); + this.removeMinutes(this.getMinutes()); break; case MILLIS.HOUR: - instance.removeHours(instance.getHours()); + this.removeHours(this.getHours()); break; } - return instance.milliseconds + (time * millis); + return this.milliseconds + (time * millis); }; /** @@ -355,271 +608,305 @@ * @default 0 * @protected */ - Kairos.Gnomon.prototype.milliseconds = 0; + Kairos.Engine.prototype.milliseconds = 0; /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * Sets hours fraction in the current instance. + * + * @param {Number} hours Hours to set + * @example new Kairos.Engine('01:00').setHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setHours = function (hours) { - this.milliseconds = _parse(this, MILLIS.HOUR, hours); + Kairos.Engine.prototype.setHours = function (hours) { + this.milliseconds = this._resolveStep(MILLIS.HOUR, hours); return this; }; /** - * - * @returns {*|Number} + * Gets hours fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getHours(); + * @returns {Number} Hours fraction from the instance */ - Kairos.Gnomon.prototype.getHours = function () { + Kairos.Engine.prototype.getHours = function () { return Math.trunc(this.milliseconds / MILLIS.HOUR); }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Sets minutes fraction in the current instance. + * + * @param {Number} minutes Minutes to set + * @example new Kairos.Engine('01:00').setMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setMinutes = function (minutes) { - this.milliseconds = _parse(this, MILLIS.MINUTE, minutes); + Kairos.Engine.prototype.setMinutes = function (minutes) { + this.milliseconds = this._resolveStep(MILLIS.MINUTE, minutes); return this; }; /** - * - * @returns {*|Number} + * Gets minutes fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMinutes(); + * @returns {Number} Minutes fraction from the instance */ - Kairos.Gnomon.prototype.getMinutes = function () { + Kairos.Engine.prototype.getMinutes = function () { return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toHours()) * MILLIS.HOUR)) / MILLIS.MINUTE); }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Sets seconds fraction in the current instance. + * + * @param {Number} seconds Seconds to set + * @example new Kairos.Engine('01:00').setSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setSeconds = function (seconds) { - this.milliseconds = _parse(this, MILLIS.SECOND, seconds); + Kairos.Engine.prototype.setSeconds = function (seconds) { + this.milliseconds = this._resolveStep(MILLIS.SECOND, seconds); return this; }; /** - * - * @returns {*|Number} + * Gets seconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getSeconds(); + * @returns {Number} Seconds fraction from the instance */ - Kairos.Gnomon.prototype.getSeconds = function () { + Kairos.Engine.prototype.getSeconds = function () { return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toMinutes()) * MILLIS.MINUTE)) / MILLIS.SECOND); }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Sets milliseconds fraction in the current instance. + * + * @param {Number} milliseconds Milliseconds to set + * @example new Kairos.Engine('01:00').setMilliseconds(200); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setMilliseconds = function (milliseconds) { - this.milliseconds = _parse(this, 1, milliseconds); + Kairos.Engine.prototype.setMilliseconds = function (milliseconds) { + this.milliseconds = this._resolveStep(1, milliseconds); return this; }; /** - * - * @returns {Number|*} + * Gets milliseconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMilliseconds(); + * @returns {Number} Milliseconds fraction from the instance */ - Kairos.Gnomon.prototype.getMilliseconds = function () { + Kairos.Engine.prototype.getMilliseconds = function () { return Math.trunc(this.milliseconds - (Math.trunc(this.toSeconds()) * MILLIS.SECOND)); }; /** + * Adds hours to the current instance. * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * @param {Number} hours Hours to add + * @example new Kairos.Engine('01:00').addHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addHours = function (hours) { + Kairos.Engine.prototype.addHours = function (hours) { this.milliseconds += (MILLIS.HOUR * hours); return this; }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Adds minutes to the current instance. + * + * @param {Number} minutes Minutes to add + * @example new Kairos.Engine('01:00').addMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addMinutes = function (minutes) { + Kairos.Engine.prototype.addMinutes = function (minutes) { this.milliseconds += (MILLIS.MINUTE * minutes); return this; }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Adds seconds in the current instance. + * + * @param {Number} seconds Seconds to add + * @example new Kairos.Engine('01:00').addSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addSeconds = function (seconds) { + Kairos.Engine.prototype.addSeconds = function (seconds) { this.milliseconds += (MILLIS.SECOND * seconds); return this; }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Adds milliseconds in the current instance. + * + * @param {Number} milliseconds Milliseconds to add + * @example new Kairos.Engine('01:00').addMilliseconds(500); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addMilliseconds = function (milliseconds) { + Kairos.Engine.prototype.addMilliseconds = function (milliseconds) { this.milliseconds += milliseconds; return this; }; /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * Removes hours from the current instance. + * + * @param {Number} hours Hours to remove + * @example new Kairos.Engine('01:00').removeHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeHours = function (hours) { + Kairos.Engine.prototype.removeHours = function (hours) { this.milliseconds -= (MILLIS.HOUR * hours); return this; }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Removes minutes from the current instance. + * + * @param {Number} minutes Minutes to remove + * @example new Kairos.Engine('01:00').removeMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeMinutes = function (minutes) { + Kairos.Engine.prototype.removeMinutes = function (minutes) { this.milliseconds -= (MILLIS.MINUTE * minutes); return this; }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Removes seconds from the current instance. + * + * @param {Number} seconds Seconds to remove + * @example new Kairos.Engine('01:00').removeSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeSeconds = function (seconds) { + Kairos.Engine.prototype.removeSeconds = function (seconds) { this.milliseconds -= (MILLIS.SECOND * seconds); return this; }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Removes milliseconds from the current instance. + * + * @example new Kairos.Engine('01:00').removeMilliseconds(50); + * @param {Number} milliseconds Milliseconds to remove + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeMilliseconds = function (milliseconds) { + Kairos.Engine.prototype.removeMilliseconds = function (milliseconds) { this.milliseconds -= milliseconds; return this; }; /** - * - * @returns {Number} hours within the time expression + * Returns total hours within the current instance. + * + * @example new Kairos.Engine('01:00').toHours(); + * @returns {Number} Hours within the current instance */ - Kairos.Gnomon.prototype.toHours = function () { + Kairos.Engine.prototype.toHours = function () { return (this.milliseconds / MILLIS.HOUR); }; /** - * - * @returns {Number} minutes within the time expression + * Returns total minutes within the current instance. + * + * @example new Kairos.Engine('01:00').toMinutes(); + * @returns {Number} Minutes within the current instance */ - Kairos.Gnomon.prototype.toMinutes = function () { + Kairos.Engine.prototype.toMinutes = function () { return (this.milliseconds / MILLIS.MINUTE); }; /** - * - * @returns {Number} seconds within the time expression + * Returns total seconds within the current instance. + * + * @example new Kairos.Engine('01:00').toSeconds(); + * @returns {Number} Seconds within the current instance */ - Kairos.Gnomon.prototype.toSeconds = function () { + Kairos.Engine.prototype.toSeconds = function () { return (this.milliseconds / MILLIS.SECOND); }; /** - * - * @returns {Number} milliseconds within the time expression + * Returns total milliseconds within the current instance. + * + * @example new Kairos.Engine('01:00').toMilliseconds(); + * @returns {Number} Milliseconds within the current instance */ - Kairos.Gnomon.prototype.toMilliseconds = function () { + Kairos.Engine.prototype.toMilliseconds = function () { return this.milliseconds; }; /** - * - * @returns {String} - */ - Kairos.Gnomon.prototype.toExpression = function () { - var expression = ''; - // Hours - var hours = Math.trunc(Math.abs(this.getHours())); - expression += ((String(hours).length > 1) ? '' : '0') + hours + ':'; - // Minutes - expression += ('00' + Math.trunc(Math.abs(this.getMinutes()))).slice(-2); - // Seconds - if (this.getSeconds() !== 0 || this.getMilliseconds() !== 0) { - expression += ':' + ('00' + Math.trunc(Math.abs(this.getSeconds()))).slice(-2); - } - // Millis - if (this.getMilliseconds() !== 0) { - expression += ':' + ('000' + Math.trunc(Math.abs(this.getMilliseconds()))).slice(-3); - } - - if (this.milliseconds < 0) { - expression = '-' + expression; - } - return expression; + * Makes the current instance's value absolute. + * + * @example new Kairos.Engine('01:00').toAbsolute(); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.toAbsolute = function () { + this.milliseconds = Math.abs(this.milliseconds); + return this; }; /** - * - * @param {Number|String|Kairos.Gnomon} addend - * @returns {Kairos.Gnomon} self + * Sums the given addend. + * + * @param {Number|String|Kairos.Engine} addend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.plus = function (addend) { - addend = (addend instanceof Kairos.Gnomon) ? addend : new Kairos.Gnomon(addend); + Kairos.Engine.prototype.plus = function (addend, pattern) { + addend = new Kairos.Engine(addend, pattern); this.milliseconds += addend.toMilliseconds(); return this; }; /** + * Subtracts the given subtrahend. * - * @param {Number|String|Kairos.Gnomon} subtrahend - * @returns {Kairos.Gnomon} self + * @param {Number|String|Kairos.Engine} subtrahend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.minus = function (subtrahend) { - subtrahend = (subtrahend instanceof Kairos.Gnomon) ? subtrahend : new Kairos.Gnomon(subtrahend); + Kairos.Engine.prototype.minus = function (subtrahend, pattern) { + subtrahend = new Kairos.Engine(subtrahend, pattern); this.milliseconds -= subtrahend.toMilliseconds(); return this; }; /** - * - * @param {Number} multiplicand - * @returns {Kairos.Gnomon} self + * Multiply by the given multiplicand. + * + * @param {Number} multiplicand Multiplicand value + * @example new Kairos.Engine('01:00').multiply(2); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.multiply = function (multiplicand) { + Kairos.Engine.prototype.multiply = function (multiplicand) { this.milliseconds *= multiplicand; return this; }; /** - * - * @param {Number} dividend - * @returns {Kairos.Gnomon} self + * Divies by the given dividend. + * + * @param {Number} divisor Divisor value + * @example new Kairos.Engine('01:00').divide(2); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.divide = function (dividend) { - this.milliseconds /= dividend; + Kairos.Engine.prototype.divide = function (divisor) { + this.milliseconds /= divisor; return this; }; /** * Compares with another instance. - * Smaller -1 - * Equals 0 - * Bigger 1 * - * @param {String|Number|Kairos.Gnomon} another Expression to compare with - * @returns {Number} + * @param {String|Number|Kairos.Engine} another Expression to compare with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').compareTo('00:30'); + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.Gnomon.prototype.compareTo = function (another) { - another = (another instanceof Kairos.Gnomon) ? another : new Kairos.Gnomon(another); + Kairos.Engine.prototype.compareTo = function (another, pattern) { + another = new Kairos.Engine(another, pattern); if (this.milliseconds < another.toMilliseconds()) { return -1; @@ -631,6 +918,18 @@ return 1; } }; + + /** + * Returns a string representation of the object. + * + * @param {String} pattern Pattern to format the time expression + * @example new Kairos.Engine('22:10').toString('hh:mm'); + * @returns {String} String representing the instance time + */ + Kairos.Engine.prototype.toString = function (pattern) { + return Kairos.Lexicon.format(this, pattern); + }; + }()); module.exports = Kairos; } diff --git a/build/kairos.js b/build/kairos.js index 96c4a01..c4cd1a9 100644 --- a/build/kairos.js +++ b/build/kairos.js @@ -1,17 +1,26 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v1.1.0 + * @version v2.0.0 * @link https://github.com/kairos * @license BSD-2-Clause */ /** * @module Kairos */ -(function () { +;(function () { + 'use strict'; var Kairos = {}; + Kairos._locales = {}; + + // Set default locale + Kairos._locale = Kairos._locales.en; + // Set default pattern + Kairos._pattern = '#hh:mm:ss.SSS'; + // Set default regex + Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; // global on the server, window in the browser var previous_Kairos; @@ -28,11 +37,11 @@ } /** - * Avoid conflict in case of another instance of Kairos is already in the scope + * Avoid conflict in case of another instance of Kairos is already in the scope. * * @memberof module:Kairos * @method noConflict - * @returns {Object} + * @returns {Object} Previous Kairos object */ Kairos.noConflict = function () { root.Kairos = previous_Kairos; @@ -40,234 +49,296 @@ }; /** - * Validates if the given expression is valid. + * Sets Kairos locale. + * + * @param {String|Object} locale A locale from Kairos.locales or a compatible locale object + * @example Kairos.setLocale('en'); + */ + Kairos.setLocale = function (locale) { + if (typeof locale === 'string') { + return Kairos._locale = Kairos._locales[locale]; + } + if (typeof locale === 'object') { + return Kairos._locale = locale; + } + }; + + /** + * Gets Kairos current locale. + * + * @returns {String} Current locale + */ + Kairos.getLocale = function () { + return Kairos._locale; + }; + + /** + * Sets Kairos time expression pattern. + * Pattern structure is the following: + * # -> sign + * h -> hours + * m -> minutes + * s -> seconds + * S -> milliseconds + * + * @param {String} pattern The pattern to parse and format time expressions + * @example Kairos.setPattern('hh:mm:ss.fff'); + */ + Kairos.setPattern = function (pattern) { + Kairos._pattern = pattern; + Kairos._validator = Kairos.Lexicon.getValidator(pattern); + }; + + /** + * Gets current Kairos pattern. + * + * @returns {String} Current Kairos pattern + */ + Kairos.getPattern = function () { + return Kairos._pattern; + }; + + /** + * Validates the give expression with the current or given pattern. + * + * @param {String} expression Time expression to validate + * @param {String} pattern Pattern to test the expression + * @example Kairos.validate('10:30', 'hh:mm'); + * @returns {Boolean} True if valid, false if invalid + */ + Kairos.validate = function (expression, pattern) { + return Kairos.Lexicon.validate(expression, pattern); + }; + + /** + * Returns a new Kairos.Engine instance. * * @memberof module:Kairos - * @method validateExpression - * @param {String|Number} expression Time expression - * @returns {Boolean} + * @method new + * @param {String|Number|kairos.Engine} time Time expression to create an instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ - Kairos.validateExpression = function (expression) { - var regex = /^[+-]?\d+(?::?\d{1,2}(?::\d{1,2}(?::\d{1,3})?)?)?$/; - return regex.test(expression); + Kairos.new = function (time, pattern) { + return new Kairos.Engine(time, pattern); }; /** - * Return a Kairos.Gnomon instance. - * + * Returns an instance of Kairos.Engine with absolute time. + * * @memberof module:Kairos - * @method with - * @param {String|Number} expression Time expression - * @returns {Kairos.Gnomon} + * @method absolute + * @param {String|Number|kairos.Engine} time Time expression to get its absolute value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ - Kairos.with = function (expression) { - return new Kairos.Gnomon(expression); + Kairos.absolute = function (time, pattern) { + return Kairos.new(time, pattern).toAbsolute(); }; /** - * Sums augend time with addend time + * Sums augend time with addend time. * * @memberof module:Kairos * @method plus - * @param {String|Number} augend Augend time expression - * @param {String|Number} addend Addend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} augend Augend time expression + * @param {String|Number|kairos.Engine} addend Addend time expression + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ - Kairos.plus = function (augend, addend) { - return Kairos.with(augend).plus(addend).toExpression(); + Kairos.plus = function (augend, addend, pattern) { + return Kairos.new(augend, pattern).plus(addend, pattern); }; /** - * Subtracts minuend time with subtrahend time + * Subtracts minuend time with subtrahend time. * * @memberof module:Kairos * @method minus - * @param {String|Number} minuend Minuend time expression - * @param {String|Number} subtrahend Subtrahend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} minuend Minuend time expression + * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ - Kairos.minus = function (minuend, subtrahend) { - return Kairos.with(minuend).minus(subtrahend).toExpression(); + Kairos.minus = function (minuend, subtrahend, pattern) { + return Kairos.new(minuend, pattern).minus(subtrahend, pattern); }; /** - * Multiplies multiplier by the multiplicand + * Multiplies multiplier by the multiplicand. * * @memberof module:Kairos * @method multiply - * @param {String|Number} multiplier Multiplier time expression - * @param {String|Number} multiplicand Multiplicand number - * @returns {String} + * @param {String|Number|kairos.Engine} multiplier Multiplier time expression + * @param {Number} multiplicand Multiplicand value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ - Kairos.multiply = function (multiplier, multiplicand) { - return Kairos.with(multiplier).multiply(multiplicand).toExpression(); + Kairos.multiply = function (multiplier, multiplicand, pattern) { + return Kairos.new(multiplier, pattern).multiply(multiplicand); }; /** - * Divides dividend by the divisor + * Divides dividend by the divisor. * * @memberof module:Kairos * @method divide - * @param {String|Number} dividend Dividend time expression - * @param {Number} divisor Dividor number - * @returns {String} + * @param {String|Number|kairos.Engine} dividend Dividend time expression + * @param {Number} divisor Divisor value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with division result */ - Kairos.divide = function (dividend, divisor) { - return Kairos.with(dividend).divide(divisor).toExpression(); + Kairos.divide = function (dividend, divisor, pattern) { + return Kairos.new(dividend, pattern).divide(divisor); }; /** - * Returns a fraction of the current time + * Returns a fraction of the current time. * * @memberof module:Kairos * @method getFraction - * @param {String|Number} time - * @param {Number} numerator - * @param {Number} denominator - * @returns {String} + * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction + * @param {Number} numerator Numerator value + * @param {Number} denominator Denominator value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ - Kairos.getFraction = function (time, numerator, denominator) { + Kairos.getFraction = function (time, numerator, denominator, pattern) { if (numerator > denominator) { throw new Error('Improper fraction'); } - return Kairos.with(time).multiply(numerator).divide(denominator).toExpression(); + return Kairos.new(time, pattern).multiply(numerator).divide(denominator); }; /** - * Returns a time expression representing the time between starting time and ending time + * Returns a time expression representing the time between starting time and ending time. * * @memberof module:Kairos * @method getInterval - * @param {String|Number} time1 time expression representing the starting time - * @param {String|Number} time2 time expression representing the ending time - * @returns {String} - */ - Kairos.getInterval = function (starting, ending) { - var st = new Kairos.Gnomon(starting); - var en = new Kairos.Gnomon(ending); - if (st.compareTo(en) > 0) { - throw new Error('Starting time must be bigger than ending time'); - } - return en.minus(st).toExpression(); + * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 + */ + Kairos.getInterval = function (time1, time2, pattern) { + return Kairos.new(time1, pattern).minus(time2, pattern).toAbsolute(); }; /** - * Converts the given time expression to milliseconds + * Converts the given time expression to milliseconds. * * @memberof module:Kairos * @method toMilliseconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total milliseconds in the time expression */ - Kairos.toMilliseconds = function (expression) { - return Kairos.with(expression).toMilliseconds(); + Kairos.toMilliseconds = function (time, pattern) { + return Kairos.new(time, pattern).toMilliseconds(); }; /** - * Converts the given time expression to seconds + * Converts the given time expression to seconds. * * @memberof module:Kairos * @method toSeconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total seconds in the time expression */ - Kairos.toSeconds = function (expression) { - return Kairos.with(expression).toSeconds(); + Kairos.toSeconds = function (time, pattern) { + return Kairos.new(time, pattern).toSeconds(); }; /** - * Converts the given time expression to minutes + * Converts the given time expression to minutes. * * @memberof module:Kairos * @method toMinutes - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total minutes in the time expression */ - Kairos.toMinutes = function (expression) { - return Kairos.with(expression).toMinutes(); + Kairos.toMinutes = function (time, pattern) { + return Kairos.new(time, pattern).toMinutes(); }; /** - * Converts the given time expression to hours + * Converts the given time expression to hours. * * @memberof module:Kairos * @method toHours - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total hours in the time expression */ - Kairos.toHours = function (expression) { - return Kairos.with(expression).toHours(); + Kairos.toHours = function (time, pattern) { + return Kairos.new(time, pattern).toHours(); }; /** * Compares first time with second time and returns -1, 0 or 1 if first value - * is smaller, equals or bigger than second value + * is smaller, equals or bigger than second value. * * @memberof module:Kairos * @method compare - * @param {String|Number} time1 Time expression - * @param {String|Number} time2 Time expression for comparation - * @returns {Number} + * @param {String|Number} comparand Time to compare with + * @param {String|Number} comparator Time to be compared with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.compare = function (time1, time2) { - return Kairos.with(time1).compareTo(time2); + Kairos.compare = function (comparand, comparator, pattern) { + return Kairos.new(comparand, pattern).compareTo(comparator, pattern); }; /** - * Returns the minimum value from the given values + * Returns the minimum value from the given values. * * @memberof module:Kairos * @method min - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ - Kairos.min = function (values) { + Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() < current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; }); - - return (min instanceof Kairos.Gnomon) ? min.toExpression() : new Kairos.Gnomon(min).toExpression(); + + return Kairos.new(min, pattern); }; /** - * Returns the maximum value from the given values + * Returns the maximum value from the given values. * * @memberof module:Kairos * @method max - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {String} Kairos.Engine instance with the greatest value found in the list */ - Kairos.max = function (values) { + Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var max = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() > current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) > 0 ? previous : current; }); - return (max instanceof Kairos.Gnomon) ? max.toExpression() : new Kairos.Gnomon(max).toExpression(); + return Kairos.new(max, pattern); }; // Node.js if (typeof module === 'object' && module.exports) { - //=include /engine/Gnomon.js + //=include /locales/en.js + //=include /locales/pt-BR.js + //=include /Lexicon.js + //=include /Engine.js module.exports = Kairos; } // AMD / RequireJS @@ -289,8 +360,210 @@ (function () { 'use strict'; + Kairos.locales.en = { + HOURS: { singular: 'hour', plural: 'hours' }, + MINUTES: { singular: 'minute', plural: 'minutes' }, + SECONDS: { singular: 'second', plural: 'seconds' }, + MILLISECONDS: { singular: 'millisecond', plural: 'milliseconds' } + }; +}()); +(function () { + 'use strict'; + + Kairos.locales['pt-BR'] = { + HOURS: { singular: 'hora', plural: 'horas' }, + MINUTES: { singular: 'minuto', plural: 'minutos' }, + SECONDS: { singular: 'segundo', plural: 'segundos' }, + MILLISECONDS: { singular: 'milissegundo', plural: 'milissegundos' } + }; +}()); +/** + * @module Kairos.Lexicon + */ +;(function () { + + 'use strict'; + + /** + * @type {{HOURS: string, MINUTES: string, SECONDS: string, MILLISECONDS: string}} + */ + var TOKENS = { + SIGN: '#', HOURS: 'h', MINUTES: 'm', + SECONDS: 's', MILLISECONDS: 'S' + }; + + Kairos.Lexicon = {}; + + /** + * Gets a regex from a pattern. + * + * @param {String} [Kairos pattern] pattern Pattern to convert + * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); + * @returns {RegExp} + */ + Kairos.Lexicon.getValidator = function (pattern) { + if (typeof pattern !== 'string') { + pattern = Kairos._pattern; + } + if (pattern === Kairos._pattern) { + return Kairos._validator; + } + + var regex = ''; + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + regex += '^[+-]?'; + break; + case TOKENS.HOURS: + case TOKENS.MINUTES: + case TOKENS.SECONDS: + case TOKENS.MILLISECONDS: + regex += '\\d'; + break; + default: + regex += cur.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + } + + return new RegExp(regex); + }; + + /** + * Validates if given expression matches the current pattern. + * + * @param {String} expression Time expression to be validated + * @param {String} [Kairos pattern] pattern Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @returns {Boolean} True if expression is valid, false if expression is invalid + */ + Kairos.Lexicon.validate = function (expression, pattern) { + return Kairos.Lexicon.getValidator(pattern).test(expression); + }; + + /** + * Parses given time expression to a Kairos.Engine instance. + * + * @param {String} expression Time expression to be parsed + * @param {String} [Kairos pattern] pattern Pattern to parse + * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); + * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine + */ + Kairos.Lexicon.parse = function (expression, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + if (!Kairos.Lexicon.validate(expression, pattern)) { + throw new Error('Cannot parse expression. Time format doesn\'t match the current time pattern.'); + } + + var sign = true, hours = '', minutes = '', seconds = '', milliseconds = ''; + + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + var validSign = (['+', '-'].indexOf(expression[i]) !== -1); + if (!validSign) { + pattern = pattern.slice(0, i) + pattern.slice(i + 1); + len--; + i--; + } else { + sign = expression[i] === '+'; + } + break; + case TOKENS.HOURS: + hours += expression[i]; + break; + case TOKENS.MINUTES: + minutes += expression[i]; + break; + case TOKENS.SECONDS: + seconds += expression[i]; + break; + case TOKENS.MILLISECONDS: + milliseconds += expression[i]; + break; + } + } + + var result = Kairos.new() + .setHours(hours ? +hours : 0) + .setMinutes(minutes ? +minutes : 0) + .setSeconds(seconds ? +seconds : 0) + .setMilliseconds(milliseconds ? +milliseconds : 0); + + if (!sign) { + result.milliseconds =- result.milliseconds; + } + + return result; + }; + + /** + * Returns a formated string from an Kairos.Engine instance. + * + * @param {Kairos.Engine} instance The instance to format + * @param {String} [Kairos pattern] pattern Pattern to format + * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); + * @returns {String} Formated time expression + */ + Kairos.Lexicon.format = function (instance, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + + var sign = instance.milliseconds >= 0, + hours = String(instance.getHours()), + minutes = String(instance.getMinutes()), + seconds = String(instance.getSeconds()), + milliseconds = String(instance.getMilliseconds()); + + var result = ''; + for (var i = pattern.length - 1; i >= 0; i--) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + result = (sign ? '+' : '-') + result; + break; + case TOKENS.HOURS: + result = (hours.slice(-1) || '0') + result; + if (hours.length > 0) { + hours = hours.slice(0, hours.length - 1); + } + break; + case TOKENS.MINUTES: + result = (minutes.slice(-1) || '0') + result; + if (minutes.length > 0) { + minutes = minutes.slice(0, minutes.length - 1); + } + break; + case TOKENS.SECONDS: + result = (seconds.slice(-1) || '0') + result; + if (seconds.length > 0) { + seconds = seconds.slice(0, seconds.length - 1); + } + break; + case TOKENS.MILLISECONDS: + result = (milliseconds.slice(-1) || '0') + result; + if (milliseconds.length > 0) { + milliseconds = milliseconds.slice(0, milliseconds.length - 1); + } + break; + default: + result = cur + result; + } + } + + return result; + }; +}()); +;(function () { + + 'use strict'; + /** - * * @type {{SECOND: number, MINUTE: number, HOUR: number}} */ var MILLIS = { @@ -300,73 +573,56 @@ }; /** - * Gnomon is the time engine for Kairos. It's name references the first solar clock ever made. + * Kairos time engine. * - * @param {String|Number} expression Time expression + * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance + * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ - Kairos.Gnomon = function (expression) { - if (typeof expression === 'number') { + Kairos.Engine = function (expression, pattern) { + if (!expression) { + return; + } - this.milliseconds = expression; + if (expression instanceof Kairos.Engine) { + return expression; + } - } else if (typeof expression === 'string' && expression.length > 0) { - - if (!Kairos.validateExpression(expression)) { - throw new Error('Invalid time expression'); - } + if (typeof expression === 'number') { + return this.milliseconds = expression; + } - var timeSteps = expression.split(':'); - var positive = expression.slice(0, 1)[0] !== '-'; - - for (var i = 0, len = timeSteps.length; i < len; i++) { - var timeStep = timeSteps[i]; - - timeStep = Math.abs(timeStep); - switch (i) { - case 0: - this.milliseconds = _parse(this, MILLIS.HOUR, timeStep); - break; - case 1: - this.milliseconds = _parse(this, MILLIS.MINUTE, timeStep); - break; - case 2: - this.milliseconds = _parse(this, MILLIS.SECOND, timeStep); - break; - case 3: - this.milliseconds = _parse(this, 1, timeStep); - break; - } - } - if (!positive) { - this.milliseconds = -Math.abs(this.milliseconds); - } + if (typeof expression === 'string' && expression.length > 0) { + return new Kairos.Lexicon.parse(expression, pattern); } + + throw new Error('Invalid arguments'); }; /** - * @param {Kairos.Gnomon} instance + * @param {Kairos.Engine} instance * @param {Number} millis * @param {Number} time * @returns {Number} * @private */ - var _parse = function (instance, millis, time) { + Kairos.Engine.prototype._resolveStep = function (millis, time) { switch (millis) { case 1: - instance.removeMilliseconds(instance.getMilliseconds()); + this.removeMilliseconds(this.getMilliseconds()); break; case MILLIS.SECOND: - instance.removeSeconds(instance.getSeconds()); + this.removeSeconds(this.getSeconds()); break; case MILLIS.MINUTE: - instance.removeMinutes(instance.getMinutes()); + this.removeMinutes(this.getMinutes()); break; case MILLIS.HOUR: - instance.removeHours(instance.getHours()); + this.removeHours(this.getHours()); break; } - return instance.milliseconds + (time * millis); + return this.milliseconds + (time * millis); }; /** @@ -374,271 +630,305 @@ * @default 0 * @protected */ - Kairos.Gnomon.prototype.milliseconds = 0; + Kairos.Engine.prototype.milliseconds = 0; /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * Sets hours fraction in the current instance. + * + * @param {Number} hours Hours to set + * @example new Kairos.Engine('01:00').setHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setHours = function (hours) { - this.milliseconds = _parse(this, MILLIS.HOUR, hours); + Kairos.Engine.prototype.setHours = function (hours) { + this.milliseconds = this._resolveStep(MILLIS.HOUR, hours); return this; }; /** - * - * @returns {*|Number} + * Gets hours fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getHours(); + * @returns {Number} Hours fraction from the instance */ - Kairos.Gnomon.prototype.getHours = function () { + Kairos.Engine.prototype.getHours = function () { return Math.trunc(this.milliseconds / MILLIS.HOUR); }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Sets minutes fraction in the current instance. + * + * @param {Number} minutes Minutes to set + * @example new Kairos.Engine('01:00').setMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setMinutes = function (minutes) { - this.milliseconds = _parse(this, MILLIS.MINUTE, minutes); + Kairos.Engine.prototype.setMinutes = function (minutes) { + this.milliseconds = this._resolveStep(MILLIS.MINUTE, minutes); return this; }; /** - * - * @returns {*|Number} + * Gets minutes fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMinutes(); + * @returns {Number} Minutes fraction from the instance */ - Kairos.Gnomon.prototype.getMinutes = function () { + Kairos.Engine.prototype.getMinutes = function () { return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toHours()) * MILLIS.HOUR)) / MILLIS.MINUTE); }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Sets seconds fraction in the current instance. + * + * @param {Number} seconds Seconds to set + * @example new Kairos.Engine('01:00').setSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setSeconds = function (seconds) { - this.milliseconds = _parse(this, MILLIS.SECOND, seconds); + Kairos.Engine.prototype.setSeconds = function (seconds) { + this.milliseconds = this._resolveStep(MILLIS.SECOND, seconds); return this; }; /** - * - * @returns {*|Number} + * Gets seconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getSeconds(); + * @returns {Number} Seconds fraction from the instance */ - Kairos.Gnomon.prototype.getSeconds = function () { + Kairos.Engine.prototype.getSeconds = function () { return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toMinutes()) * MILLIS.MINUTE)) / MILLIS.SECOND); }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Sets milliseconds fraction in the current instance. + * + * @param {Number} milliseconds Milliseconds to set + * @example new Kairos.Engine('01:00').setMilliseconds(200); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.setMilliseconds = function (milliseconds) { - this.milliseconds = _parse(this, 1, milliseconds); + Kairos.Engine.prototype.setMilliseconds = function (milliseconds) { + this.milliseconds = this._resolveStep(1, milliseconds); return this; }; /** - * - * @returns {Number|*} + * Gets milliseconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMilliseconds(); + * @returns {Number} Milliseconds fraction from the instance */ - Kairos.Gnomon.prototype.getMilliseconds = function () { + Kairos.Engine.prototype.getMilliseconds = function () { return Math.trunc(this.milliseconds - (Math.trunc(this.toSeconds()) * MILLIS.SECOND)); }; /** + * Adds hours to the current instance. * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * @param {Number} hours Hours to add + * @example new Kairos.Engine('01:00').addHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addHours = function (hours) { + Kairos.Engine.prototype.addHours = function (hours) { this.milliseconds += (MILLIS.HOUR * hours); return this; }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Adds minutes to the current instance. + * + * @param {Number} minutes Minutes to add + * @example new Kairos.Engine('01:00').addMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addMinutes = function (minutes) { + Kairos.Engine.prototype.addMinutes = function (minutes) { this.milliseconds += (MILLIS.MINUTE * minutes); return this; }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Adds seconds in the current instance. + * + * @param {Number} seconds Seconds to add + * @example new Kairos.Engine('01:00').addSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addSeconds = function (seconds) { + Kairos.Engine.prototype.addSeconds = function (seconds) { this.milliseconds += (MILLIS.SECOND * seconds); return this; }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Adds milliseconds in the current instance. + * + * @param {Number} milliseconds Milliseconds to add + * @example new Kairos.Engine('01:00').addMilliseconds(500); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.addMilliseconds = function (milliseconds) { + Kairos.Engine.prototype.addMilliseconds = function (milliseconds) { this.milliseconds += milliseconds; return this; }; /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self + * Removes hours from the current instance. + * + * @param {Number} hours Hours to remove + * @example new Kairos.Engine('01:00').removeHours(1); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeHours = function (hours) { + Kairos.Engine.prototype.removeHours = function (hours) { this.milliseconds -= (MILLIS.HOUR * hours); return this; }; /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self + * Removes minutes from the current instance. + * + * @param {Number} minutes Minutes to remove + * @example new Kairos.Engine('01:00').removeMinutes(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeMinutes = function (minutes) { + Kairos.Engine.prototype.removeMinutes = function (minutes) { this.milliseconds -= (MILLIS.MINUTE * minutes); return this; }; /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self + * Removes seconds from the current instance. + * + * @param {Number} seconds Seconds to remove + * @example new Kairos.Engine('01:00').removeSeconds(30); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeSeconds = function (seconds) { + Kairos.Engine.prototype.removeSeconds = function (seconds) { this.milliseconds -= (MILLIS.SECOND * seconds); return this; }; /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self + * Removes milliseconds from the current instance. + * + * @example new Kairos.Engine('01:00').removeMilliseconds(50); + * @param {Number} milliseconds Milliseconds to remove + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.removeMilliseconds = function (milliseconds) { + Kairos.Engine.prototype.removeMilliseconds = function (milliseconds) { this.milliseconds -= milliseconds; return this; }; /** - * - * @returns {Number} hours within the time expression + * Returns total hours within the current instance. + * + * @example new Kairos.Engine('01:00').toHours(); + * @returns {Number} Hours within the current instance */ - Kairos.Gnomon.prototype.toHours = function () { + Kairos.Engine.prototype.toHours = function () { return (this.milliseconds / MILLIS.HOUR); }; /** - * - * @returns {Number} minutes within the time expression + * Returns total minutes within the current instance. + * + * @example new Kairos.Engine('01:00').toMinutes(); + * @returns {Number} Minutes within the current instance */ - Kairos.Gnomon.prototype.toMinutes = function () { + Kairos.Engine.prototype.toMinutes = function () { return (this.milliseconds / MILLIS.MINUTE); }; /** - * - * @returns {Number} seconds within the time expression + * Returns total seconds within the current instance. + * + * @example new Kairos.Engine('01:00').toSeconds(); + * @returns {Number} Seconds within the current instance */ - Kairos.Gnomon.prototype.toSeconds = function () { + Kairos.Engine.prototype.toSeconds = function () { return (this.milliseconds / MILLIS.SECOND); }; /** - * - * @returns {Number} milliseconds within the time expression + * Returns total milliseconds within the current instance. + * + * @example new Kairos.Engine('01:00').toMilliseconds(); + * @returns {Number} Milliseconds within the current instance */ - Kairos.Gnomon.prototype.toMilliseconds = function () { + Kairos.Engine.prototype.toMilliseconds = function () { return this.milliseconds; }; /** - * - * @returns {String} - */ - Kairos.Gnomon.prototype.toExpression = function () { - var expression = ''; - // Hours - var hours = Math.trunc(Math.abs(this.getHours())); - expression += ((String(hours).length > 1) ? '' : '0') + hours + ':'; - // Minutes - expression += ('00' + Math.trunc(Math.abs(this.getMinutes()))).slice(-2); - // Seconds - if (this.getSeconds() !== 0 || this.getMilliseconds() !== 0) { - expression += ':' + ('00' + Math.trunc(Math.abs(this.getSeconds()))).slice(-2); - } - // Millis - if (this.getMilliseconds() !== 0) { - expression += ':' + ('000' + Math.trunc(Math.abs(this.getMilliseconds()))).slice(-3); - } - - if (this.milliseconds < 0) { - expression = '-' + expression; - } - return expression; + * Makes the current instance's value absolute. + * + * @example new Kairos.Engine('01:00').toAbsolute(); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.toAbsolute = function () { + this.milliseconds = Math.abs(this.milliseconds); + return this; }; /** - * - * @param {Number|String|Kairos.Gnomon} addend - * @returns {Kairos.Gnomon} self + * Sums the given addend. + * + * @param {Number|String|Kairos.Engine} addend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.plus = function (addend) { - addend = (addend instanceof Kairos.Gnomon) ? addend : new Kairos.Gnomon(addend); + Kairos.Engine.prototype.plus = function (addend, pattern) { + addend = new Kairos.Engine(addend, pattern); this.milliseconds += addend.toMilliseconds(); return this; }; /** + * Subtracts the given subtrahend. * - * @param {Number|String|Kairos.Gnomon} subtrahend - * @returns {Kairos.Gnomon} self + * @param {Number|String|Kairos.Engine} subtrahend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.minus = function (subtrahend) { - subtrahend = (subtrahend instanceof Kairos.Gnomon) ? subtrahend : new Kairos.Gnomon(subtrahend); + Kairos.Engine.prototype.minus = function (subtrahend, pattern) { + subtrahend = new Kairos.Engine(subtrahend, pattern); this.milliseconds -= subtrahend.toMilliseconds(); return this; }; /** - * - * @param {Number} multiplicand - * @returns {Kairos.Gnomon} self + * Multiply by the given multiplicand. + * + * @param {Number} multiplicand Multiplicand value + * @example new Kairos.Engine('01:00').multiply(2); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.multiply = function (multiplicand) { + Kairos.Engine.prototype.multiply = function (multiplicand) { this.milliseconds *= multiplicand; return this; }; /** - * - * @param {Number} dividend - * @returns {Kairos.Gnomon} self + * Divies by the given dividend. + * + * @param {Number} divisor Divisor value + * @example new Kairos.Engine('01:00').divide(2); + * @returns {Kairos.Engine} Self */ - Kairos.Gnomon.prototype.divide = function (dividend) { - this.milliseconds /= dividend; + Kairos.Engine.prototype.divide = function (divisor) { + this.milliseconds /= divisor; return this; }; /** * Compares with another instance. - * Smaller -1 - * Equals 0 - * Bigger 1 * - * @param {String|Number|Kairos.Gnomon} another Expression to compare with - * @returns {Number} + * @param {String|Number|Kairos.Engine} another Expression to compare with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').compareTo('00:30'); + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.Gnomon.prototype.compareTo = function (another) { - another = (another instanceof Kairos.Gnomon) ? another : new Kairos.Gnomon(another); + Kairos.Engine.prototype.compareTo = function (another, pattern) { + another = new Kairos.Engine(another, pattern); if (this.milliseconds < another.toMilliseconds()) { return -1; @@ -650,4 +940,16 @@ return 1; } }; + + /** + * Returns a string representation of the object. + * + * @param {String} pattern Pattern to format the time expression + * @example new Kairos.Engine('22:10').toString('hh:mm'); + * @returns {String} String representing the instance time + */ + Kairos.Engine.prototype.toString = function (pattern) { + return Kairos.Lexicon.format(this, pattern); + }; + }()); \ No newline at end of file diff --git a/examples/calc/calc.js b/examples/calc/calc.js index bc01e59..2086d08 100644 --- a/examples/calc/calc.js +++ b/examples/calc/calc.js @@ -88,8 +88,8 @@ var _equals = function () { try { - var val1 = new Kairos.Gnomon(String(_val1)); - var val2 = _doNotParse ? parseInt(_val2) : new Kairos.Gnomon(_val2); + var val1 = new Kairos.Engine(String(_val1)); + var val2 = _doNotParse ? parseInt(_val2) : new Kairos.Engine(_val2); switch (_operator) { case '/': diff --git a/examples/usecase/index.html b/examples/usecase/index.html index 42ee376..f8f6eb8 100644 --- a/examples/usecase/index.html +++ b/examples/usecase/index.html @@ -7,24 +7,23 @@ - + Kairos Usecase - + - + -

Kairo Usecase

- -
- -
+ +
+ +
@@ -32,8 +31,12 @@

Kairo Usecase

- -
+ +
+ +
+ +
@@ -52,15 +55,15 @@

Kairo Usecase

- +
- + - +
- + diff --git a/examples/usecase/index.js b/examples/usecase/index.js index 2b97425..6e0a928 100644 --- a/examples/usecase/index.js +++ b/examples/usecase/index.js @@ -1,46 +1,46 @@ (function (window) { 'use strict'; - + var _tasks = []; - + var exports = {}; - + var _taskNameInput, _taskStartBtn, _tasksTableBody, _totalTime; - + var _initSelectors = function () { _taskNameInput = document.querySelector('input#task-name'); _taskStartBtn = document.querySelector('div#taks-start'); _tasksTableBody = document.querySelector('table#tasks-table tbody'); _totalTime = document.getElementById('total-time'); }; - + var _initEventHandlers = function () { _taskStartBtn.addEventListener('click', _addTask); }; - + var _addTask = function () { var task = new Task(_taskNameInput.value); _tasks.push(task); - + var row = document.createElement('tr'), taskCol = document.createElement('td'), executedForCol = document.createElement('td'), actionCol = document.createElement('td'), taskContent = document.createTextNode(task.name), stopTaskBtn = document.createElement('button'); - + taskCol.appendChild(taskContent); row.appendChild(taskCol); - + var updateInterval = setInterval(function () { executedForCol.innerHTML = task.getTimeElapsed().toExpression(); _updateTotal(); }, 1000); row.appendChild(executedForCol); - + stopTaskBtn.setAttribute('class', 'btn btn-danger'); stopTaskBtn.innerHTML = 'Stop'; stopTaskBtn.addEventListener('click', function () { @@ -49,27 +49,27 @@ }); actionCol.appendChild(stopTaskBtn); row.appendChild(actionCol); - + _tasksTableBody.appendChild(row); _taskNameInput.value = ''; }; - + var _updateTotal = function () { - var g = new Kairos.Gnomon(); + var g = new Kairos.Engine(); for (var i = 0, len = _tasks.length; i < len; i++) { g.plus(_tasks[i].getTimeElapsed()); } - + _totalTime.innerHTML = g.toExpression(); }; - + var _init = function () { _initSelectors(); _initEventHandlers(); }; - + exports.init = _init; - + window.TaskManager = exports; })(window); diff --git a/examples/usecase/jumbotron-narrow.css b/examples/usecase/jumbotron-narrow.css deleted file mode 100644 index 952adc5..0000000 --- a/examples/usecase/jumbotron-narrow.css +++ /dev/null @@ -1,79 +0,0 @@ -/* Space out content a bit */ -body { - padding-top: 20px; - padding-bottom: 20px; -} - -/* Everything but the jumbotron gets side spacing for mobile first views */ -.header, -.marketing, -.footer { - padding-right: 15px; - padding-left: 15px; -} - -/* Custom page header */ -.header { - padding-bottom: 20px; - border-bottom: 1px solid #e5e5e5; -} -/* Make the masthead heading the same height as the navigation */ -.header h3 { - margin-top: 0; - margin-bottom: 0; - line-height: 40px; -} - -/* Custom page footer */ -.footer { - padding-top: 19px; - color: #777; - border-top: 1px solid #e5e5e5; -} - -/* Customize container */ -@media (min-width: 768px) { - .container { - max-width: 730px; - } -} -.container-narrow > hr { - margin: 30px 0; -} - -/* Main marketing message and sign up button */ -.jumbotron { - text-align: center; - border-bottom: 1px solid #e5e5e5; -} -.jumbotron .btn { - padding: 14px 24px; - font-size: 21px; -} - -/* Supporting marketing content */ -.marketing { - margin: 40px 0; -} -.marketing p + h4 { - margin-top: 28px; -} - -/* Responsive: Portrait tablets and up */ -@media screen and (min-width: 768px) { - /* Remove the padding we set earlier */ - .header, - .marketing, - .footer { - padding-right: 0; - padding-left: 0; - } - /* Space out the masthead */ - .header { - margin-bottom: 30px; - } - /* Remove the bottom border on the jumbotron for visual effect */ - .jumbotron { - border-bottom: 0; - } -} diff --git a/examples/usecase/task.js b/examples/usecase/task.js index 97e9609..751940a 100644 --- a/examples/usecase/task.js +++ b/examples/usecase/task.js @@ -16,14 +16,14 @@ * @protected */ Task.prototype.name = ''; - + /** * @type {Date} * @default new Date * @protected */ Task.prototype.startedAt = null; - + /** * @type {Date} * @default null @@ -37,16 +37,16 @@ Task.prototype.finish = function () { this.finishedAt = new Date(); }; - + /** * @returns {Kairos.Gnomon} */ Task.prototype.getTimeElapsed = function () { var diff = ((this.finishedAt || new Date()).getTime() - this.startedAt.getTime()); - var gnomon = new Kairos.Gnomon(diff); - gnomon.removeMilliseconds(gnomon.getMilliseconds()); - return gnomon; + var engine = new Kairos.Engine(diff); + engine.removeMilliseconds(engine.getMilliseconds()); + return engine; }; - + window.Task = Task; }()); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 0804825..b4d831a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,7 +10,8 @@ const stylish = require('jshint-stylish'); const mainFiles = [ 'src/kairos.js', - 'src/engine/Gnomon.js' + 'src/Lexicon.js', + 'src/Engine.js' ]; gulp.task('init', () => { diff --git a/karma.conf.js b/karma.conf.js index c55ad0e..1750301 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -6,11 +6,13 @@ module.exports = function (config) { files: [ 'bower_components/mocha/mocha.css', 'src/kairos.js', - 'src/engine/Gnomon.js', + 'src/Lexicon.js', + 'src/Engine.js', 'bower_components/assert/assert.js', 'bower_components/mocha/mocha.js', 'test/browser/kairos.js', - 'test/browser/gnomon.js', + 'test/browser/lexicon.js', + 'test/browser/engine.js', { pattern: 'test/browser/fixture/*', included: false, diff --git a/package.json b/package.json index 327aada..cb01b85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kairos", - "version": "1.1.0", + "version": "2.0.0", "description": "A non date-based time calculator", "license": "BSD-2-Clause", "repository": "kairos", @@ -27,7 +27,7 @@ "del": "^2.2.0", "gulp": "^3.9.0", "gulp-autoprefixer": "^3.1.0", - "gulp-bower": "0.0.11", + "gulp-bower": "0.0.13", "gulp-concat": "^2.6.0", "gulp-esformatter": "^5.0.0", "gulp-header": "^1.7.1", @@ -39,7 +39,7 @@ "gulp-uglify": "^1.5.1", "gulp-webserver": "^0.9.1", "jasmine-core": "^2.4.1", - "jshint": "^2.9.1-rc2", + "jshint": "^2.9.1", "jshint-stylish": "^2.1.0", "karma": "^0.13.15", "karma-chrome-launcher": "^0.2.2", @@ -47,10 +47,10 @@ "karma-firefox-launcher": "^0.1.7", "karma-jasmine": "^0.3.6", "karma-mocha": "^0.2.1", - "karma-phantomjs-launcher": "^0.2.1", - "mocha": "^2.3.4", + "karma-phantomjs-launcher": "^1.0.0", + "mocha": "^2.4.5", "phantom": "^0.8.4", - "phantomjs": "^1.9.19", + "phantomjs-prebuilt": "^2.1.3", "run-sequence": "^1.1.5" } } diff --git a/src/Engine.js b/src/Engine.js new file mode 100644 index 0000000..f50c50b --- /dev/null +++ b/src/Engine.js @@ -0,0 +1,394 @@ +;(function () { + + 'use strict'; + + /** + * @type {{SECOND: number, MINUTE: number, HOUR: number}} + */ + var MILLIS = { + SECOND: 1000, + MINUTE: 60 * 1000, + HOUR: 60 * 60 * 1000 + }; + + /** + * Kairos time engine. + * + * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance + * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('10:30', 'hh:mm'); + * @constructor + */ + Kairos.Engine = function (expression, pattern) { + if (!expression) { + return; + } + + if (expression instanceof Kairos.Engine) { + return expression; + } + + if (typeof expression === 'number') { + this.milliseconds = expression; + return this; + } + + if (typeof expression === 'string' && expression.length > 0) { + return new Kairos.Lexicon.parse(expression, pattern); + } + + throw new Error('Invalid arguments'); + }; + + /** + * @param {Kairos.Engine} instance + * @param {Number} millis + * @param {Number} time + * @returns {Number} + * @private + */ + Kairos.Engine.prototype._resolveStep = function (millis, time) { + switch (millis) { + case 1: + this.removeMilliseconds(this.getMilliseconds()); + break; + case MILLIS.SECOND: + this.removeSeconds(this.getSeconds()); + break; + case MILLIS.MINUTE: + this.removeMinutes(this.getMinutes()); + break; + case MILLIS.HOUR: + this.removeHours(this.getHours()); + break; + } + return this.milliseconds + (time * millis); + }; + + /** + * @type {Number} + * @default 0 + * @protected + */ + Kairos.Engine.prototype.milliseconds = 0; + + /** + * Sets hours fraction in the current instance. + * + * @param {Number} hours Hours to set + * @example new Kairos.Engine('01:00').setHours(1); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.setHours = function (hours) { + this.milliseconds = this._resolveStep(MILLIS.HOUR, hours); + return this; + }; + + /** + * Gets hours fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getHours(); + * @returns {Number} Hours fraction from the instance + */ + Kairos.Engine.prototype.getHours = function () { + return Math.trunc(this.milliseconds / MILLIS.HOUR); + }; + + /** + * Sets minutes fraction in the current instance. + * + * @param {Number} minutes Minutes to set + * @example new Kairos.Engine('01:00').setMinutes(30); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.setMinutes = function (minutes) { + this.milliseconds = this._resolveStep(MILLIS.MINUTE, minutes); + return this; + }; + + /** + * Gets minutes fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMinutes(); + * @returns {Number} Minutes fraction from the instance + */ + Kairos.Engine.prototype.getMinutes = function () { + return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toHours()) * MILLIS.HOUR)) / MILLIS.MINUTE); + }; + + /** + * Sets seconds fraction in the current instance. + * + * @param {Number} seconds Seconds to set + * @example new Kairos.Engine('01:00').setSeconds(30); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.setSeconds = function (seconds) { + this.milliseconds = this._resolveStep(MILLIS.SECOND, seconds); + return this; + }; + + /** + * Gets seconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getSeconds(); + * @returns {Number} Seconds fraction from the instance + */ + Kairos.Engine.prototype.getSeconds = function () { + return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toMinutes()) * MILLIS.MINUTE)) / MILLIS.SECOND); + }; + + /** + * Sets milliseconds fraction in the current instance. + * + * @param {Number} milliseconds Milliseconds to set + * @example new Kairos.Engine('01:00').setMilliseconds(200); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.setMilliseconds = function (milliseconds) { + this.milliseconds = this._resolveStep(1, milliseconds); + return this; + }; + + /** + * Gets milliseconds fraction in the current instance. + * + * @example new Kairos.Engine('01:00').getMilliseconds(); + * @returns {Number} Milliseconds fraction from the instance + */ + Kairos.Engine.prototype.getMilliseconds = function () { + return Math.trunc(this.milliseconds - (Math.trunc(this.toSeconds()) * MILLIS.SECOND)); + }; + + /** + * Adds hours to the current instance. + * + * @param {Number} hours Hours to add + * @example new Kairos.Engine('01:00').addHours(1); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.addHours = function (hours) { + this.milliseconds += (MILLIS.HOUR * hours); + return this; + }; + + /** + * Adds minutes to the current instance. + * + * @param {Number} minutes Minutes to add + * @example new Kairos.Engine('01:00').addMinutes(30); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.addMinutes = function (minutes) { + this.milliseconds += (MILLIS.MINUTE * minutes); + return this; + }; + + /** + * Adds seconds in the current instance. + * + * @param {Number} seconds Seconds to add + * @example new Kairos.Engine('01:00').addSeconds(30); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.addSeconds = function (seconds) { + this.milliseconds += (MILLIS.SECOND * seconds); + return this; + }; + + /** + * Adds milliseconds in the current instance. + * + * @param {Number} milliseconds Milliseconds to add + * @example new Kairos.Engine('01:00').addMilliseconds(500); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.addMilliseconds = function (milliseconds) { + this.milliseconds += milliseconds; + return this; + }; + + /** + * Removes hours from the current instance. + * + * @param {Number} hours Hours to remove + * @example new Kairos.Engine('01:00').removeHours(1); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.removeHours = function (hours) { + this.milliseconds -= (MILLIS.HOUR * hours); + return this; + }; + + /** + * Removes minutes from the current instance. + * + * @param {Number} minutes Minutes to remove + * @example new Kairos.Engine('01:00').removeMinutes(30); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.removeMinutes = function (minutes) { + this.milliseconds -= (MILLIS.MINUTE * minutes); + return this; + }; + + /** + * Removes seconds from the current instance. + * + * @param {Number} seconds Seconds to remove + * @example new Kairos.Engine('01:00').removeSeconds(30); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.removeSeconds = function (seconds) { + this.milliseconds -= (MILLIS.SECOND * seconds); + return this; + }; + + /** + * Removes milliseconds from the current instance. + * + * @example new Kairos.Engine('01:00').removeMilliseconds(50); + * @param {Number} milliseconds Milliseconds to remove + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.removeMilliseconds = function (milliseconds) { + this.milliseconds -= milliseconds; + return this; + }; + + /** + * Returns total hours within the current instance. + * + * @example new Kairos.Engine('01:00').toHours(); + * @returns {Number} Hours within the current instance + */ + Kairos.Engine.prototype.toHours = function () { + return (this.milliseconds / MILLIS.HOUR); + }; + + /** + * Returns total minutes within the current instance. + * + * @example new Kairos.Engine('01:00').toMinutes(); + * @returns {Number} Minutes within the current instance + */ + Kairos.Engine.prototype.toMinutes = function () { + return (this.milliseconds / MILLIS.MINUTE); + }; + + /** + * Returns total seconds within the current instance. + * + * @example new Kairos.Engine('01:00').toSeconds(); + * @returns {Number} Seconds within the current instance + */ + Kairos.Engine.prototype.toSeconds = function () { + return (this.milliseconds / MILLIS.SECOND); + }; + + /** + * Returns total milliseconds within the current instance. + * + * @example new Kairos.Engine('01:00').toMilliseconds(); + * @returns {Number} Milliseconds within the current instance + */ + Kairos.Engine.prototype.toMilliseconds = function () { + return this.milliseconds; + }; + + /** + * Makes the current instance's value absolute. + * + * @example new Kairos.Engine('01:00').toAbsolute(); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.toAbsolute = function () { + this.milliseconds = Math.abs(this.milliseconds); + return this; + }; + + /** + * Sums the given addend. + * + * @param {Number|String|Kairos.Engine} addend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.plus = function (addend, pattern) { + addend = new Kairos.Engine(addend, pattern); + this.milliseconds += addend.toMilliseconds(); + return this; + }; + + /** + * Subtracts the given subtrahend. + * + * @param {Number|String|Kairos.Engine} subtrahend + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').minus('00:30'); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.minus = function (subtrahend, pattern) { + subtrahend = new Kairos.Engine(subtrahend, pattern); + this.milliseconds -= subtrahend.toMilliseconds(); + return this; + }; + + /** + * Multiply by the given multiplicand. + * + * @param {Number} multiplicand Multiplicand value + * @example new Kairos.Engine('01:00').multiply(2); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.multiply = function (multiplicand) { + this.milliseconds *= multiplicand; + return this; + }; + + /** + * Divies by the given dividend. + * + * @param {Number} divisor Divisor value + * @example new Kairos.Engine('01:00').divide(2); + * @returns {Kairos.Engine} Self + */ + Kairos.Engine.prototype.divide = function (divisor) { + this.milliseconds /= divisor; + return this; + }; + + /** + * Compares with another instance. + * + * @param {String|Number|Kairos.Engine} another Expression to compare with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @example new Kairos.Engine('01:00').compareTo('00:30'); + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 + */ + Kairos.Engine.prototype.compareTo = function (another, pattern) { + another = new Kairos.Engine(another, pattern); + + if (this.milliseconds < another.toMilliseconds()) { + return -1; + } + if (this.milliseconds === another.toMilliseconds()) { + return 0; + } + if (this.milliseconds > another.toMilliseconds()) { + return 1; + } + }; + + /** + * Returns a string representation of the object. + * + * @param {String} pattern Pattern to format the time expression + * @example new Kairos.Engine('22:10').toString('hh:mm'); + * @returns {String} String representing the instance time + */ + Kairos.Engine.prototype.toString = function (pattern) { + return Kairos.Lexicon.format(this, pattern); + }; +}()); \ No newline at end of file diff --git a/src/Lexicon.js b/src/Lexicon.js new file mode 100644 index 0000000..2928d3c --- /dev/null +++ b/src/Lexicon.js @@ -0,0 +1,182 @@ +/** + * @module Kairos.Lexicon + */ +;(function () { + + 'use strict'; + + /** + * @type {{HOURS: string, MINUTES: string, SECONDS: string, MILLISECONDS: string}} + */ + var TOKENS = { + SIGN: '#', HOURS: 'h', MINUTES: 'm', + SECONDS: 's', MILLISECONDS: 'S' + }; + + Kairos.Lexicon = {}; + + /** + * Gets a regex from a pattern. + * + * @param {String} [Kairos pattern] pattern Pattern to convert + * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); + * @returns {RegExp} + */ + Kairos.Lexicon.getValidator = function (pattern) { + if (typeof pattern !== 'string') { + pattern = Kairos._pattern; + } + if (pattern === Kairos._pattern) { + return Kairos._validator; + } + + var regex = ''; + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + regex += '^[+-]?'; + break; + case TOKENS.HOURS: + case TOKENS.MINUTES: + case TOKENS.SECONDS: + case TOKENS.MILLISECONDS: + regex += '\\d'; + break; + default: + regex += cur.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + } + + return new RegExp(regex); + }; + + /** + * Validates if given expression matches the current pattern. + * + * @param {String} expression Time expression to be validated + * @param {String} [Kairos pattern] pattern Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @returns {Boolean} True if expression is valid, false if expression is invalid + */ + Kairos.Lexicon.validate = function (expression, pattern) { + return Kairos.Lexicon.getValidator(pattern).test(expression); + }; + + /** + * Parses given time expression to a Kairos.Engine instance. + * + * @param {String} expression Time expression to be parsed + * @param {String} [Kairos pattern] pattern Pattern to parse + * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); + * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine + */ + Kairos.Lexicon.parse = function (expression, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + if (!Kairos.Lexicon.validate(expression, pattern)) { + throw new Error('Cannot parse expression. Time format doesn\'t match the current time pattern.'); + } + + var sign = true, hours = '', minutes = '', seconds = '', milliseconds = ''; + + for (var i = 0, len = pattern.length; len > i; i++) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + var validSign = (['+', '-'].indexOf(expression[i]) !== -1); + if (!validSign) { + pattern = pattern.slice(0, i) + pattern.slice(i + 1); + len--; + i--; + } else { + sign = expression[i] === '+'; + } + break; + case TOKENS.HOURS: + hours += expression[i]; + break; + case TOKENS.MINUTES: + minutes += expression[i]; + break; + case TOKENS.SECONDS: + seconds += expression[i]; + break; + case TOKENS.MILLISECONDS: + milliseconds += expression[i]; + break; + } + } + + var result = Kairos.new() + .setHours(hours ? +hours : 0) + .setMinutes(minutes ? +minutes : 0) + .setSeconds(seconds ? +seconds : 0) + .setMilliseconds(milliseconds ? +milliseconds : 0); + + if (!sign) { + result.milliseconds =- result.milliseconds; + } + + return result; + }; + + /** + * Returns a formated string from an Kairos.Engine instance. + * + * @param {Kairos.Engine} instance The instance to format + * @param {String} [Kairos pattern] pattern Pattern to format + * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); + * @returns {String} Formated time expression + */ + Kairos.Lexicon.format = function (instance, pattern) { + if (!pattern) { + pattern = Kairos._pattern; + } + + var sign = instance.milliseconds >= 0, + hours = String(instance.getHours()), + minutes = String(instance.getMinutes()), + seconds = String(instance.getSeconds()), + milliseconds = String(instance.getMilliseconds()); + + var result = ''; + for (var i = pattern.length - 1; i >= 0; i--) { + var cur = pattern[i]; + switch (cur) { + case TOKENS.SIGN: + result = (sign ? '+' : '-') + result; + break; + case TOKENS.HOURS: + result = (hours.slice(-1) || '0') + result; + if (hours.length > 0) { + hours = hours.slice(0, hours.length - 1); + } + break; + case TOKENS.MINUTES: + result = (minutes.slice(-1) || '0') + result; + if (minutes.length > 0) { + minutes = minutes.slice(0, minutes.length - 1); + } + break; + case TOKENS.SECONDS: + result = (seconds.slice(-1) || '0') + result; + if (seconds.length > 0) { + seconds = seconds.slice(0, seconds.length - 1); + } + break; + case TOKENS.MILLISECONDS: + result = (milliseconds.slice(-1) || '0') + result; + if (milliseconds.length > 0) { + milliseconds = milliseconds.slice(0, milliseconds.length - 1); + } + break; + default: + result = cur + result; + } + } + + return result; + }; +}()); \ No newline at end of file diff --git a/src/engine/Gnomon.js b/src/engine/Gnomon.js deleted file mode 100644 index 0d1fab8..0000000 --- a/src/engine/Gnomon.js +++ /dev/null @@ -1,365 +0,0 @@ -(function () { - 'use strict'; - - /** - * - * @type {{SECOND: number, MINUTE: number, HOUR: number}} - */ - var MILLIS = { - SECOND: 1000, - MINUTE: 60 * 1000, - HOUR: 60 * 60 * 1000 - }; - - /** - * Gnomon is the time engine for Kairos. It's name references the first solar clock ever made. - * - * @param {String|Number} expression Time expression - * @constructor - */ - Kairos.Gnomon = function (expression) { - if (typeof expression === 'number') { - - this.milliseconds = expression; - - } else if (typeof expression === 'string' && expression.length > 0) { - - if (!Kairos.validateExpression(expression)) { - throw new Error('Invalid time expression'); - } - - var timeSteps = expression.split(':'); - var positive = expression.slice(0, 1)[0] !== '-'; - - for (var i = 0, len = timeSteps.length; i < len; i++) { - var timeStep = timeSteps[i]; - - timeStep = Math.abs(timeStep); - switch (i) { - case 0: - this.milliseconds = _parse(this, MILLIS.HOUR, timeStep); - break; - case 1: - this.milliseconds = _parse(this, MILLIS.MINUTE, timeStep); - break; - case 2: - this.milliseconds = _parse(this, MILLIS.SECOND, timeStep); - break; - case 3: - this.milliseconds = _parse(this, 1, timeStep); - break; - } - } - if (!positive) { - this.milliseconds = -Math.abs(this.milliseconds); - } - } - }; - - /** - * @param {Kairos.Gnomon} instance - * @param {Number} millis - * @param {Number} time - * @returns {Number} - * @private - */ - var _parse = function (instance, millis, time) { - switch (millis) { - case 1: - instance.removeMilliseconds(instance.getMilliseconds()); - break; - case MILLIS.SECOND: - instance.removeSeconds(instance.getSeconds()); - break; - case MILLIS.MINUTE: - instance.removeMinutes(instance.getMinutes()); - break; - case MILLIS.HOUR: - instance.removeHours(instance.getHours()); - break; - } - return instance.milliseconds + (time * millis); - }; - - /** - * @type {Number} - * @default 0 - * @protected - */ - Kairos.Gnomon.prototype.milliseconds = 0; - - /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.setHours = function (hours) { - this.milliseconds = _parse(this, MILLIS.HOUR, hours); - return this; - }; - - /** - * - * @returns {*|Number} - */ - Kairos.Gnomon.prototype.getHours = function () { - return Math.trunc(this.milliseconds / MILLIS.HOUR); - }; - - /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.setMinutes = function (minutes) { - this.milliseconds = _parse(this, MILLIS.MINUTE, minutes); - return this; - }; - - /** - * - * @returns {*|Number} - */ - Kairos.Gnomon.prototype.getMinutes = function () { - return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toHours()) * MILLIS.HOUR)) / MILLIS.MINUTE); - }; - - /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.setSeconds = function (seconds) { - this.milliseconds = _parse(this, MILLIS.SECOND, seconds); - return this; - }; - - /** - * - * @returns {*|Number} - */ - Kairos.Gnomon.prototype.getSeconds = function () { - return Math.trunc(Math.trunc(this.milliseconds - (Math.trunc(this.toMinutes()) * MILLIS.MINUTE)) / MILLIS.SECOND); - }; - - /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.setMilliseconds = function (milliseconds) { - this.milliseconds = _parse(this, 1, milliseconds); - return this; - }; - - /** - * - * @returns {Number|*} - */ - Kairos.Gnomon.prototype.getMilliseconds = function () { - return Math.trunc(this.milliseconds - (Math.trunc(this.toSeconds()) * MILLIS.SECOND)); - }; - - /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.addHours = function (hours) { - this.milliseconds += (MILLIS.HOUR * hours); - return this; - }; - - /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.addMinutes = function (minutes) { - this.milliseconds += (MILLIS.MINUTE * minutes); - return this; - }; - - /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.addSeconds = function (seconds) { - this.milliseconds += (MILLIS.SECOND * seconds); - return this; - }; - - /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.addMilliseconds = function (milliseconds) { - this.milliseconds += milliseconds; - return this; - }; - - /** - * - * @param {Number} hours - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.removeHours = function (hours) { - this.milliseconds -= (MILLIS.HOUR * hours); - return this; - }; - - /** - * - * @param {Number} minutes - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.removeMinutes = function (minutes) { - this.milliseconds -= (MILLIS.MINUTE * minutes); - return this; - }; - - /** - * - * @param {Number} seconds - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.removeSeconds = function (seconds) { - this.milliseconds -= (MILLIS.SECOND * seconds); - return this; - }; - - /** - * - * @param {Number} milliseconds - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.removeMilliseconds = function (milliseconds) { - this.milliseconds -= milliseconds; - return this; - }; - - /** - * - * @returns {Number} hours within the time expression - */ - Kairos.Gnomon.prototype.toHours = function () { - return (this.milliseconds / MILLIS.HOUR); - }; - - /** - * - * @returns {Number} minutes within the time expression - */ - Kairos.Gnomon.prototype.toMinutes = function () { - return (this.milliseconds / MILLIS.MINUTE); - }; - - /** - * - * @returns {Number} seconds within the time expression - */ - Kairos.Gnomon.prototype.toSeconds = function () { - return (this.milliseconds / MILLIS.SECOND); - }; - - /** - * - * @returns {Number} milliseconds within the time expression - */ - Kairos.Gnomon.prototype.toMilliseconds = function () { - return this.milliseconds; - }; - - /** - * - * @returns {String} - */ - Kairos.Gnomon.prototype.toExpression = function () { - var expression = ''; - // Hours - var hours = Math.trunc(Math.abs(this.getHours())); - expression += ((String(hours).length > 1) ? '' : '0') + hours + ':'; - // Minutes - expression += ('00' + Math.trunc(Math.abs(this.getMinutes()))).slice(-2); - // Seconds - if (this.getSeconds() !== 0 || this.getMilliseconds() !== 0) { - expression += ':' + ('00' + Math.trunc(Math.abs(this.getSeconds()))).slice(-2); - } - // Millis - if (this.getMilliseconds() !== 0) { - expression += ':' + ('000' + Math.trunc(Math.abs(this.getMilliseconds()))).slice(-3); - } - - if (this.milliseconds < 0) { - expression = '-' + expression; - } - return expression; - }; - - /** - * - * @param {Number|String|Kairos.Gnomon} addend - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.plus = function (addend) { - addend = (addend instanceof Kairos.Gnomon) ? addend : new Kairos.Gnomon(addend); - this.milliseconds += addend.toMilliseconds(); - return this; - }; - - /** - * - * @param {Number|String|Kairos.Gnomon} subtrahend - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.minus = function (subtrahend) { - subtrahend = (subtrahend instanceof Kairos.Gnomon) ? subtrahend : new Kairos.Gnomon(subtrahend); - this.milliseconds -= subtrahend.toMilliseconds(); - return this; - }; - - /** - * - * @param {Number} multiplicand - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.multiply = function (multiplicand) { - this.milliseconds *= multiplicand; - return this; - }; - - /** - * - * @param {Number} dividend - * @returns {Kairos.Gnomon} self - */ - Kairos.Gnomon.prototype.divide = function (dividend) { - this.milliseconds /= dividend; - return this; - }; - - /** - * Compares with another instance. - * Smaller -1 - * Equals 0 - * Bigger 1 - * - * @param {String|Number|Kairos.Gnomon} another Expression to compare with - * @returns {Number} - */ - Kairos.Gnomon.prototype.compareTo = function (another) { - another = (another instanceof Kairos.Gnomon) ? another : new Kairos.Gnomon(another); - - if (this.milliseconds < another.toMilliseconds()) { - return -1; - } - if (this.milliseconds === another.toMilliseconds()) { - return 0; - } - if (this.milliseconds > another.toMilliseconds()) { - return 1; - } - }; -}()); \ No newline at end of file diff --git a/src/kairos.js b/src/kairos.js index 15598ae..3f61bb1 100644 --- a/src/kairos.js +++ b/src/kairos.js @@ -1,11 +1,17 @@ /** * @module Kairos */ -(function () { +;(function () { + 'use strict'; var Kairos = {}; + // Set default pattern + Kairos._pattern = '#hh:mm:ss.SSS'; + // Set default regex + Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + // global on the server, window in the browser var previous_Kairos; @@ -21,11 +27,11 @@ } /** - * Avoid conflict in case of another instance of Kairos is already in the scope + * Avoid conflict in case of another instance of Kairos is already in the scope. * * @memberof module:Kairos * @method noConflict - * @returns {Object} + * @returns {Object} Previous Kairos object */ Kairos.noConflict = function () { root.Kairos = previous_Kairos; @@ -33,234 +39,270 @@ }; /** - * Validates if the given expression is valid. + * Sets Kairos time expression pattern. + * Pattern structure is the following: + * # -> sign + * h -> hours + * m -> minutes + * s -> seconds + * S -> milliseconds + * + * @param {String} pattern The pattern to parse and format time expressions + * @example Kairos.setPattern('hh:mm:ss.fff'); + */ + Kairos.setPattern = function (pattern) { + Kairos._pattern = pattern; + Kairos._validator = Kairos.Lexicon.getValidator(pattern); + }; + + /** + * Gets current Kairos pattern. + * + * @returns {String} Current Kairos pattern + */ + Kairos.getPattern = function () { + return Kairos._pattern; + }; + + /** + * Validates the give expression with the current or given pattern. + * + * @param {String} expression Time expression to validate + * @param {String} pattern Pattern to test the expression + * @example Kairos.validate('10:30', 'hh:mm'); + * @returns {Boolean} True if valid, false if invalid + */ + Kairos.validate = function (expression, pattern) { + return Kairos.Lexicon.validate(expression, pattern); + }; + + /** + * Returns a new Kairos.Engine instance. * * @memberof module:Kairos - * @method validateExpression - * @param {String|Number} expression Time expression - * @returns {Boolean} + * @method new + * @param {String|Number|kairos.Engine} time Time expression to create an instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ - Kairos.validateExpression = function (expression) { - var regex = /^[+-]?\d+(?::?\d{1,2}(?::\d{1,2}(?::\d{1,3})?)?)?$/; - return regex.test(expression); + Kairos.new = function (time, pattern) { + return new Kairos.Engine(time, pattern); }; /** - * Return a Kairos.Gnomon instance. - * + * Returns an instance of Kairos.Engine with absolute time. + * * @memberof module:Kairos - * @method with - * @param {String|Number} expression Time expression - * @returns {Kairos.Gnomon} + * @method absolute + * @param {String|Number|kairos.Engine} time Time expression to get its absolute value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ - Kairos.with = function (expression) { - return new Kairos.Gnomon(expression); + Kairos.absolute = function (time, pattern) { + return Kairos.new(time, pattern).toAbsolute(); }; /** - * Sums augend time with addend time + * Sums augend time with addend time. * * @memberof module:Kairos * @method plus - * @param {String|Number} augend Augend time expression - * @param {String|Number} addend Addend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} augend Augend time expression + * @param {String|Number|kairos.Engine} addend Addend time expression + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ - Kairos.plus = function (augend, addend) { - return Kairos.with(augend).plus(addend).toExpression(); + Kairos.plus = function (augend, addend, pattern) { + return Kairos.new(augend, pattern).plus(addend, pattern); }; /** - * Subtracts minuend time with subtrahend time + * Subtracts minuend time with subtrahend time. * * @memberof module:Kairos * @method minus - * @param {String|Number} minuend Minuend time expression - * @param {String|Number} subtrahend Subtrahend time expression - * @returns {String} + * @param {String|Number|kairos.Engine} minuend Minuend time expression + * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ - Kairos.minus = function (minuend, subtrahend) { - return Kairos.with(minuend).minus(subtrahend).toExpression(); + Kairos.minus = function (minuend, subtrahend, pattern) { + return Kairos.new(minuend, pattern).minus(subtrahend, pattern); }; /** - * Multiplies multiplier by the multiplicand + * Multiplies multiplier by the multiplicand. * * @memberof module:Kairos * @method multiply - * @param {String|Number} multiplier Multiplier time expression - * @param {String|Number} multiplicand Multiplicand number - * @returns {String} + * @param {String|Number|kairos.Engine} multiplier Multiplier time expression + * @param {Number} multiplicand Multiplicand value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ - Kairos.multiply = function (multiplier, multiplicand) { - return Kairos.with(multiplier).multiply(multiplicand).toExpression(); + Kairos.multiply = function (multiplier, multiplicand, pattern) { + return Kairos.new(multiplier, pattern).multiply(multiplicand); }; /** - * Divides dividend by the divisor + * Divides dividend by the divisor. * * @memberof module:Kairos * @method divide - * @param {String|Number} dividend Dividend time expression - * @param {Number} divisor Dividor number - * @returns {String} + * @param {String|Number|kairos.Engine} dividend Dividend time expression + * @param {Number} divisor Divisor value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with division result */ - Kairos.divide = function (dividend, divisor) { - return Kairos.with(dividend).divide(divisor).toExpression(); + Kairos.divide = function (dividend, divisor, pattern) { + return Kairos.new(dividend, pattern).divide(divisor); }; /** - * Returns a fraction of the current time + * Returns a fraction of the current time. * * @memberof module:Kairos * @method getFraction - * @param {String|Number} time - * @param {Number} numerator - * @param {Number} denominator - * @returns {String} + * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction + * @param {Number} numerator Numerator value + * @param {Number} denominator Denominator value + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ - Kairos.getFraction = function (time, numerator, denominator) { + Kairos.getFraction = function (time, numerator, denominator, pattern) { if (numerator > denominator) { throw new Error('Improper fraction'); } - return Kairos.with(time).multiply(numerator).divide(denominator).toExpression(); + return Kairos.new(time, pattern).multiply(numerator).divide(denominator); }; /** - * Returns a time expression representing the time between starting time and ending time + * Returns a time expression representing the time between starting time and ending time. * * @memberof module:Kairos * @method getInterval - * @param {String|Number} time1 time expression representing the starting time - * @param {String|Number} time2 time expression representing the ending time - * @returns {String} + * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 */ - Kairos.getInterval = function (starting, ending) { - var st = new Kairos.Gnomon(starting); - var en = new Kairos.Gnomon(ending); - if (st.compareTo(en) > 0) { - throw new Error('Starting time must be bigger than ending time'); - } - return en.minus(st).toExpression(); + Kairos.getInterval = function (time1, time2, pattern) { + return Kairos.new(time1, pattern).minus(time2, pattern).toAbsolute(); }; /** - * Converts the given time expression to milliseconds + * Converts the given time expression to milliseconds. * * @memberof module:Kairos * @method toMilliseconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total milliseconds in the time expression */ - Kairos.toMilliseconds = function (expression) { - return Kairos.with(expression).toMilliseconds(); + Kairos.toMilliseconds = function (time, pattern) { + return Kairos.new(time, pattern).toMilliseconds(); }; /** - * Converts the given time expression to seconds + * Converts the given time expression to seconds. * * @memberof module:Kairos * @method toSeconds - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total seconds in the time expression */ - Kairos.toSeconds = function (expression) { - return Kairos.with(expression).toSeconds(); + Kairos.toSeconds = function (time, pattern) { + return Kairos.new(time, pattern).toSeconds(); }; /** - * Converts the given time expression to minutes + * Converts the given time expression to minutes. * * @memberof module:Kairos * @method toMinutes - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total minutes in the time expression */ - Kairos.toMinutes = function (expression) { - return Kairos.with(expression).toMinutes(); + Kairos.toMinutes = function (time, pattern) { + return Kairos.new(time, pattern).toMinutes(); }; /** - * Converts the given time expression to hours + * Converts the given time expression to hours. * * @memberof module:Kairos * @method toHours - * @param {String|Number} expression Time expression - * @returns {Number} + * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Total hours in the time expression */ - Kairos.toHours = function (expression) { - return Kairos.with(expression).toHours(); + Kairos.toHours = function (time, pattern) { + return Kairos.new(time, pattern).toHours(); }; /** * Compares first time with second time and returns -1, 0 or 1 if first value - * is smaller, equals or bigger than second value + * is smaller, equals or bigger than second value. * * @memberof module:Kairos * @method compare - * @param {String|Number} time1 Time expression - * @param {String|Number} time2 Time expression for comparation - * @returns {Number} + * @param {String|Number} comparand Time to compare with + * @param {String|Number} comparator Time to be compared with + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ - Kairos.compare = function (time1, time2) { - return Kairos.with(time1).compareTo(time2); + Kairos.compare = function (comparand, comparator, pattern) { + return Kairos.new(comparand, pattern).compareTo(comparator, pattern); }; /** - * Returns the minimum value from the given values + * Returns the minimum value from the given values. * * @memberof module:Kairos * @method min - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ - Kairos.min = function (values) { + Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() < current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; }); - - return (min instanceof Kairos.Gnomon) ? min.toExpression() : new Kairos.Gnomon(min).toExpression(); + + return Kairos.new(min, pattern); }; /** - * Returns the maximum value from the given values + * Returns the maximum value from the given values. * * @memberof module:Kairos * @method max - * @param {String[]|Number[]|Kairos.Gnomon[]} values Array with time expressions - * @returns {String} + * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions + * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @returns {String} Kairos.Engine instance with the greatest value found in the list */ - Kairos.max = function (values) { + Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { values = Array.prototype.slice.call(arguments); } var max = values.reduce(function (previous, current) { - if (!(previous instanceof Kairos.Gnomon)) { - previous = new Kairos.Gnomon(previous ? previous : 0); - } - if (!(current instanceof Kairos.Gnomon)) { - current = new Kairos.Gnomon(current ? current : 0); - } - return ( previous.toMilliseconds() > current.toMilliseconds() ? previous : current ); + return Kairos.new(previous, pattern).compareTo(current, pattern) > 0 ? previous : current; }); - return (max instanceof Kairos.Gnomon) ? max.toExpression() : new Kairos.Gnomon(max).toExpression(); + return Kairos.new(max, pattern); }; // Node.js if (typeof module === 'object' && module.exports) { - //=include /engine/Gnomon.js + //=include /Lexicon.js + //=include /Engine.js module.exports = Kairos; } // AMD / RequireJS diff --git a/test/browser/gnomon.js b/test/browser/engine.js similarity index 50% rename from test/browser/gnomon.js rename to test/browser/engine.js index d256a46..294cb1f 100644 --- a/test/browser/gnomon.js +++ b/test/browser/engine.js @@ -10,11 +10,11 @@ if (typeof require !== 'undefined') { Kairos = require('../../build/kairos-node'); } -describe('Kairos.Gnomon', function () { +describe('Kairos.Engine', function () { // Setup ===================================================================== - var gnomon; + var engine; before(function (done) { done(); @@ -23,16 +23,16 @@ describe('Kairos.Gnomon', function () { // Tests ===================================================================== beforeEach(function () { - gnomon = new Kairos.Gnomon('01:30:30:123'); + engine = new Kairos.Engine('01:30:30:123'); }); afterEach(function () { }); - it('should return an instance of Kairos.Gnomon', function (done) { + it('should return an instance of Kairos.Engine', function (done) { assert.doesNotThrow(function () { - var t1 = new Kairos.Gnomon('10:20:30:123'); - var t2 = new Kairos.Gnomon(1); + var t1 = new Kairos.Engine('10:20:30:123'); + var t2 = new Kairos.Engine(1); assert.equal(t1.getMilliseconds(), 123); assert.equal(t1.getSeconds(), 30); @@ -55,248 +55,248 @@ describe('Kairos.Gnomon', function () { done(); }); - it('should return an instance of Kairos.Gnomon with zero value', function (done) { - assert.equal(new Kairos.Gnomon().toMilliseconds(), 0); + it('should return an instance of Kairos.Engine with zero value', function (done) { + assert.equal(new Kairos.Engine().toMilliseconds(), 0); done(); }); it('should throw error when expression is invalid', function (done) { assert.throws(function () { - new Kairos.Gnomon('00:00:00:00:00'); + new Kairos.Engine('00:00:00:00:00'); }, Error); done(); }); it('should throw error when a expression time step is not a number', function (done) { assert.throws(function () { - new Kairos.Gnomon('00:00:00:a0'); + new Kairos.Engine('00:00:00:a0'); }, Error); done(); }); it('should return the milliseconds in the expression', function (done) { - assert.equal(gnomon.getMilliseconds(), 123); + assert.equal(engine.getMilliseconds(), 123); done(); }); it('should return the seconds in the expression', function (done) { - assert.equal(gnomon.getSeconds(), 30); + assert.equal(engine.getSeconds(), 30); done(); }); it('should return the minutes in the expression', function (done) { - assert.equal(gnomon.getMinutes(), 30); + assert.equal(engine.getMinutes(), 30); done(); }); it('should return the hours in the expression', function (done) { - assert.equal(gnomon.getHours(), 1); + assert.equal(engine.getHours(), 1); done(); }); it('should convert the expression to milliseconds', function (done) { - assert.equal(gnomon.toMilliseconds(), 5430123); + assert.equal(engine.toMilliseconds(), 5430123); done(); }); it('should convert the expression to seconds', function (done) { - assert.equal(gnomon.toSeconds(), 5430.123); + assert.equal(engine.toSeconds(), 5430.123); done(); }); it('should convert the expression to minutes', function (done) { - assert.equal(gnomon.toMinutes(), 90.50205); + assert.equal(engine.toMinutes(), 90.50205); done(); }); it('should convert the expression to hours', function (done) { - assert.equal(gnomon.toHours(), 1.5083675); + assert.equal(engine.toHours(), 1.5083675); done(); }); it('should return the given expression', function (done) { - assert.equal(gnomon.toExpression(), '01:30:30:123'); + assert.equal(engine.toString(), '01:30:30:123'); done(); }); it('should return the given negative expression', function (done) { - gnomon = new Kairos.Gnomon('-01:30:30:123'); - assert.equal(gnomon.toExpression(), '-01:30:30:123'); + engine = new Kairos.Engine('-01:30:30:123'); + assert.equal(engine.toString(), '-01:30:30:123'); done(); }); it('should add 900 milliseconds to the expression', function (done) { - var t = gnomon.addMilliseconds(900); - assert.equal(gnomon.getMilliseconds(), 23); - assert.equal(gnomon.getSeconds(), 31); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.addMilliseconds(900); + assert.equal(engine.getMilliseconds(), 23); + assert.equal(engine.getSeconds(), 31); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getMilliseconds(), 23); done(); }); it('should add 31 seconds to the expression', function (done) { - var t = gnomon.addSeconds(31); - assert.equal(gnomon.getMilliseconds(), 123); - assert.equal(gnomon.getSeconds(), 1); - assert.equal(gnomon.getMinutes(), 31); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.addSeconds(31); + assert.equal(engine.getMilliseconds(), 123); + assert.equal(engine.getSeconds(), 1); + assert.equal(engine.getMinutes(), 31); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getSeconds(), 1); done(); }); it('should add 31 minutes to the expression', function (done) { - var t = gnomon.addMinutes(31); - assert.equal(gnomon.getMilliseconds(), 123); - assert.equal(gnomon.getSeconds(), 30); - assert.equal(gnomon.getMinutes(), 1); - assert.equal(gnomon.getHours(), 2); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.addMinutes(31); + assert.equal(engine.getMilliseconds(), 123); + assert.equal(engine.getSeconds(), 30); + assert.equal(engine.getMinutes(), 1); + assert.equal(engine.getHours(), 2); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getMinutes(), 1); done(); }); it('should add 1.5 hours to the expression', function (done) { - var t = gnomon.addHours(1.5); - assert.equal(gnomon.getMilliseconds(), 123); - assert.equal(gnomon.getSeconds(), 30); - assert.equal(gnomon.getMinutes(), 0); - assert.equal(gnomon.getHours(), 3); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.addHours(1.5); + assert.equal(engine.getMilliseconds(), 123); + assert.equal(engine.getSeconds(), 30); + assert.equal(engine.getMinutes(), 0); + assert.equal(engine.getHours(), 3); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getHours(), 3); done(); }); it('should remove 900 milliseconds to the expression', function (done) { - var t = gnomon.removeMilliseconds(900); - assert.equal(gnomon.getMilliseconds(), 223); - assert.equal(gnomon.getSeconds(), 29); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.removeMilliseconds(900); + assert.equal(engine.getMilliseconds(), 223); + assert.equal(engine.getSeconds(), 29); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getMilliseconds(), 223); done(); }); it('should remove 31 seconds to the expression', function (done) { - var t = gnomon.removeSeconds(31); - assert.equal(gnomon.getMilliseconds(), 123); - assert.equal(gnomon.getSeconds(), 59); - assert.equal(gnomon.getMinutes(), 29); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.removeSeconds(31); + assert.equal(engine.getMilliseconds(), 123); + assert.equal(engine.getSeconds(), 59); + assert.equal(engine.getMinutes(), 29); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getSeconds(), 59); done(); }); it('should remove 31 minutes to the expression', function (done) { - var t = gnomon.removeMinutes(31); - assert.equal(gnomon.getMilliseconds(), 123); - assert.equal(gnomon.getSeconds(), 30); - assert.equal(gnomon.getMinutes(), 59); - assert.equal(gnomon.getHours(), 0); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.removeMinutes(31); + assert.equal(engine.getMilliseconds(), 123); + assert.equal(engine.getSeconds(), 30); + assert.equal(engine.getMinutes(), 59); + assert.equal(engine.getHours(), 0); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getMinutes(), 59); done(); }); it('should remove 1.5 hours to the expression', function (done) { - var t = gnomon.removeHours(1.5); - assert.equal(gnomon.getMilliseconds(), 123); - assert.equal(gnomon.getSeconds(), 30); - assert.equal(gnomon.getMinutes(), 0); - assert.equal(gnomon.getHours(), 0); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.removeHours(1.5); + assert.equal(engine.getMilliseconds(), 123); + assert.equal(engine.getSeconds(), 30); + assert.equal(engine.getMinutes(), 0); + assert.equal(engine.getHours(), 0); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getHours(), 0); done(); }); it('should set expression millisecons to 321', function (done) { - var t = gnomon.setMilliseconds(321); - assert.equal(gnomon.getMilliseconds(), 321); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.setMilliseconds(321); + assert.equal(engine.getMilliseconds(), 321); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getMilliseconds(), 321); done(); }); it('should set expression seconds to 45', function (done) { - var t = gnomon.setSeconds(45); - assert.equal(gnomon.getSeconds(), 45); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.setSeconds(45); + assert.equal(engine.getSeconds(), 45); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getSeconds(), 45); done(); }); it('should set expression minutes to 45', function (done) { - var t = gnomon.setMinutes(45); - assert.equal(gnomon.getMinutes(), 45); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.setMinutes(45); + assert.equal(engine.getMinutes(), 45); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getMinutes(), 45); done(); }); it('should set expression hours to 5', function (done) { - var t = gnomon.setHours(5); - assert.equal(gnomon.getHours(), 5); - assert.ok(t instanceof Kairos.Gnomon); + var t = engine.setHours(5); + assert.equal(engine.getHours(), 5); + assert.ok(t instanceof Kairos.Engine); assert.equal(t.getHours(), 5); done(); }); it('should sum two time expressions', function (done) { - var addend = new Kairos.Gnomon('01:30:30:123'); - var t = gnomon.plus(addend); - assert.equal(gnomon.toExpression(), '03:01:00:246'); - assert.ok(t instanceof Kairos.Gnomon); - assert.equal(t.toExpression(), '03:01:00:246'); + var addend = new Kairos.Engine('01:30:30:123'); + var t = engine.plus(addend); + assert.equal(engine.toString(), '03:01:00:246'); + assert.ok(t instanceof Kairos.Engine); + assert.equal(t.toString(), '03:01:00:246'); done(); }); it('should subtract two time expressions', function (done) { - var substrahend = new Kairos.Gnomon('01:30:30:123'); - var t = gnomon.minus(substrahend); - assert.equal(gnomon.toExpression(), '00:00'); - assert.ok(t instanceof Kairos.Gnomon); - assert.equal(t.toExpression(), '00:00'); + var substrahend = new Kairos.Engine('01:30:30:123'); + var t = engine.minus(substrahend); + assert.equal(engine.toString(), '00:00'); + assert.ok(t instanceof Kairos.Engine); + assert.equal(t.toString(), '00:00'); done(); }); it('should multiply the time expression by 2', function (done) { - var t = gnomon.multiply(2); - assert.equal(gnomon.toExpression(), '03:01:00:246'); - assert.ok(t instanceof Kairos.Gnomon); - assert.equal(t.toExpression(), '03:01:00:246'); + var t = engine.multiply(2); + assert.equal(engine.toString(), '03:01:00:246'); + assert.ok(t instanceof Kairos.Engine); + assert.equal(t.toString(), '03:01:00:246'); done(); }); it('should divide the time expression by 2', function (done) { - var t = gnomon.divide(2); - assert.equal(gnomon.toExpression(), '00:45:15:061'); - assert.ok(t instanceof Kairos.Gnomon); - assert.equal(t.toExpression(), '00:45:15:061'); + var t = engine.divide(2); + assert.equal(engine.toString(), '00:45:15:061'); + assert.ok(t instanceof Kairos.Engine); + assert.equal(t.toString(), '00:45:15:061'); done(); }); it('should compare first time with second time and return -1 for smaller, 0 for equals and 1 for bigger', function (done) { - gnomon = new Kairos.Gnomon('01:00'); - assert.equal(gnomon.compareTo(new Kairos.Gnomon('02:00')), -1); - assert.equal(gnomon.compareTo(new Kairos.Gnomon('01:00')), 0); - assert.equal(gnomon.compareTo(new Kairos.Gnomon('00:30')), 1); + engine = new Kairos.Engine('01:00'); + assert.equal(engine.compareTo(new Kairos.Engine('02:00')), -1); + assert.equal(engine.compareTo(new Kairos.Engine('01:00')), 0); + assert.equal(engine.compareTo(new Kairos.Engine('00:30')), 1); done(); }); it('should parse correctly expressions whith hours < 10 and > 99', function (done) { - var a = new Kairos.Gnomon('60:00'); - var b = new Kairos.Gnomon('80:00'); + var a = new Kairos.Engine('60:00'); + var b = new Kairos.Engine('80:00'); a.plus(b); - assert.equal(a.toExpression(), '140:00'); + assert.equal(a.toString(), '140:00'); - a.minus(new Kairos.Gnomon('139:00')); - assert.equal(a.toExpression(), '01:00'); + a.minus(new Kairos.Engine('139:00')); + assert.equal(a.toString(), '01:00'); done(); }); it('should execute commands in sequence and output the correct result', function (done) { - var t = new Kairos.Gnomon('01:00').plus('02:00').minus('01:00').divide(2).multiply(10); - assert.ok(t instanceof Kairos.Gnomon); - assert.equal(t.toExpression(), '10:00'); + var t = new Kairos.Engine('01:00').plus('02:00').minus('01:00').divide(2).multiply(10); + assert.ok(t instanceof Kairos.Engine); + assert.equal(t.toString(), '10:00'); done(); }); }); diff --git a/test/browser/kairos.js b/test/browser/kairos.js index adc12fa..ea11b6a 100644 --- a/test/browser/kairos.js +++ b/test/browser/kairos.js @@ -14,7 +14,7 @@ describe('Kairos', function () { // Setup ===================================================================== - var gnomon; + var engine; before(function (done) { done(); @@ -23,7 +23,7 @@ describe('Kairos', function () { // Tests ===================================================================== beforeEach(function () { - gnomon = new Kairos.Gnomon('01:30:30:123'); + engine = new Kairos.Engine('01:30:30:123'); }); afterEach(function () { @@ -38,7 +38,7 @@ describe('Kairos', function () { it('should sum first time expression with second time expression', function (done) { var time = Kairos.plus('01:00', '01:30:35:100'); - assert.equal(time, '02:30:35:100'); + assert.equal(time.toString(), '02:30:35:100'); done(); }); @@ -71,17 +71,10 @@ describe('Kairos', function () { }); it('should return a time expression representing the interval between starting time and ending time', function (done) { - assert.equal(Kairos.getInterval('01:00', '02:00'), '01:00'); + assert.equal(Kairos.getInterval('01:00', '02:00').toString(), '01:00'); done(); }); - it('should throw error when starting time is bigger than ending time', function (done) { - assert.throws(function () { - Kairos.getInterval('02:00', '01:00'); - }); - done(); - }); - it('should return total milliseconds in the given time expression', function (done) { assert.equal(Kairos.toMilliseconds('01:30:35:100'), 5435100); done(); @@ -113,17 +106,17 @@ describe('Kairos', function () { assert.equal(Kairos.min(['01:00', '05:00', '00:30', '00:40']), '00:30'); assert.equal(Kairos.min([ - new Kairos.Gnomon('01:00'), - new Kairos.Gnomon('05:00'), - new Kairos.Gnomon('00:30'), - new Kairos.Gnomon('00:40')]), '00:30'); + new Kairos.Engine('01:00'), + new Kairos.Engine('05:00'), + new Kairos.Engine('00:30'), + new Kairos.Engine('00:40')]), '00:30'); assert.equal(Kairos.min('01:00', '05:00', '00:30', '00:40'), '00:30'); - assert.equal(Kairos.min(new Kairos.Gnomon('01:00'), - new Kairos.Gnomon('05:00'), - new Kairos.Gnomon('00:30'), - new Kairos.Gnomon('00:40')), '00:30'); + assert.equal(Kairos.min(new Kairos.Engine('01:00'), + new Kairos.Engine('05:00'), + new Kairos.Engine('00:30'), + new Kairos.Engine('00:40')), '00:30'); assert.equal(Kairos.min('01:00'), '01:00'); @@ -134,17 +127,17 @@ describe('Kairos', function () { assert.equal(Kairos.max(['01:00', '05:00', '00:30', '00:40']), '05:00'); assert.equal(Kairos.max([ - new Kairos.Gnomon('01:00'), - new Kairos.Gnomon('05:00'), - new Kairos.Gnomon('00:30'), - new Kairos.Gnomon('00:40')]), '05:00'); + new Kairos.Engine('01:00'), + new Kairos.Engine('05:00'), + new Kairos.Engine('00:30'), + new Kairos.Engine('00:40')]), '05:00'); assert.equal(Kairos.max('01:00', '05:00', '00:30', '00:40'), '05:00'); - assert.equal(Kairos.max(new Kairos.Gnomon('01:00'), - new Kairos.Gnomon('05:00'), - new Kairos.Gnomon('00:30'), - new Kairos.Gnomon('00:40')), '05:00'); + assert.equal(Kairos.max(new Kairos.Engine('01:00'), + new Kairos.Engine('05:00'), + new Kairos.Engine('00:30'), + new Kairos.Engine('00:40')), '05:00'); assert.equal(Kairos.max('01:00'), '01:00'); @@ -161,14 +154,14 @@ describe('Kairos', function () { done(); }); - it('should create an instance of Kairos.Gnomon', function (done) { - var a = Kairos.with(); - var b = Kairos.with('01:00'); - var c = Kairos.with(123); - - assert.ok(a instanceof Kairos.Gnomon); - assert.ok(b instanceof Kairos.Gnomon); - assert.ok(c instanceof Kairos.Gnomon); + it('should create an instance of Kairos.Engine', function (done) { + var a = Kairos.new(); + var b = Kairos.new('01:00'); + var c = Kairos.new(123); + + assert.ok(a instanceof Kairos.Engine); + assert.ok(b instanceof Kairos.Engine); + assert.ok(c instanceof Kairos.Engine); done(); }); }); diff --git a/test/browser/lexicon.js b/test/browser/lexicon.js new file mode 100644 index 0000000..e69de29 diff --git a/test/browser/test.html b/test/browser/test.html index b223867..719df53 100644 --- a/test/browser/test.html +++ b/test/browser/test.html @@ -12,7 +12,8 @@ - + + From b997d541d037d9bfb38790eac4606a32d5a305c6 Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Thu, 18 Feb 2016 12:51:44 +0000 Subject: [PATCH 2/8] fixing tests --- .gitignore | 1 + build/kairos-debug.js | 65 ++--------- build/kairos-min.js | 8 +- build/kairos-node.js | 63 ++--------- build/kairos.js | 65 ++--------- package.json | 4 +- src/Lexicon.js | 8 +- src/kairos.js | 4 +- test/browser/{engine.js => engine} | 2 +- test/browser/kairos.js | 168 ++++++++++++++++------------- test/browser/lexicon.js | 15 +++ 11 files changed, 152 insertions(+), 251 deletions(-) rename test/browser/{engine.js => engine} (99%) diff --git a/.gitignore b/.gitignore index bf5f217..3c5db2f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ bower_components node_modules +/coverage diff --git a/build/kairos-debug.js b/build/kairos-debug.js index c4cd1a9..40222db 100644 --- a/build/kairos-debug.js +++ b/build/kairos-debug.js @@ -13,10 +13,7 @@ 'use strict'; var Kairos = {}; - Kairos._locales = {}; - // Set default locale - Kairos._locale = Kairos._locales.en; // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex @@ -48,30 +45,6 @@ return Kairos; }; - /** - * Sets Kairos locale. - * - * @param {String|Object} locale A locale from Kairos.locales or a compatible locale object - * @example Kairos.setLocale('en'); - */ - Kairos.setLocale = function (locale) { - if (typeof locale === 'string') { - return Kairos._locale = Kairos._locales[locale]; - } - if (typeof locale === 'object') { - return Kairos._locale = locale; - } - }; - - /** - * Gets Kairos current locale. - * - * @returns {String} Current locale - */ - Kairos.getLocale = function () { - return Kairos._locale; - }; - /** * Sets Kairos time expression pattern. * Pattern structure is the following: @@ -302,11 +275,12 @@ */ Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; + return Kairos.compare(previous, current, pattern) < 0 ? previous : current; }); return Kairos.new(min, pattern); @@ -323,6 +297,7 @@ */ Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } @@ -335,8 +310,6 @@ // Node.js if (typeof module === 'object' && module.exports) { - //=include /locales/en.js - //=include /locales/pt-BR.js //=include /Lexicon.js //=include /Engine.js module.exports = Kairos; @@ -357,26 +330,6 @@ return x < 0 ? Math.ceil(x) : Math.floor(x); }; }()); -(function () { - 'use strict'; - - Kairos.locales.en = { - HOURS: { singular: 'hour', plural: 'hours' }, - MINUTES: { singular: 'minute', plural: 'minutes' }, - SECONDS: { singular: 'second', plural: 'seconds' }, - MILLISECONDS: { singular: 'millisecond', plural: 'milliseconds' } - }; -}()); -(function () { - 'use strict'; - - Kairos.locales['pt-BR'] = { - HOURS: { singular: 'hora', plural: 'horas' }, - MINUTES: { singular: 'minuto', plural: 'minutos' }, - SECONDS: { singular: 'segundo', plural: 'segundos' }, - MILLISECONDS: { singular: 'milissegundo', plural: 'milissegundos' } - }; -}()); /** * @module Kairos.Lexicon */ @@ -489,10 +442,10 @@ } var result = Kairos.new() - .setHours(hours ? +hours : 0) - .setMinutes(minutes ? +minutes : 0) - .setSeconds(seconds ? +seconds : 0) - .setMilliseconds(milliseconds ? +milliseconds : 0); + .addHours(hours ? +hours : 0) + .addMinutes(minutes ? +minutes : 0) + .addSeconds(seconds ? +seconds : 0) + .addMilliseconds(milliseconds ? +milliseconds : 0); if (!sign) { result.milliseconds =- result.milliseconds; @@ -590,7 +543,8 @@ } if (typeof expression === 'number') { - return this.milliseconds = expression; + this.milliseconds = expression; + return this; } if (typeof expression === 'string' && expression.length > 0) { @@ -951,5 +905,4 @@ Kairos.Engine.prototype.toString = function (pattern) { return Kairos.Lexicon.format(this, pattern); }; - }()); \ No newline at end of file diff --git a/build/kairos-min.js b/build/kairos-min.js index d5c3e14..a1e200d 100644 --- a/build/kairos-min.js +++ b/build/kairos-min.js @@ -5,8 +5,6 @@ * @link https://github.com/kairos * @license BSD-2-Clause */ -!function(){"use strict";var n={};n._locales={},n._locale=n._locales.en,n._pattern="#hh:mm:ss.SSS",n._validator=/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/;var e,t="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==t&&(e=t.Kairos),n.noConflict=function(){return t.Kairos=e,n},n.setLocale=function(e){return"string"==typeof e?n._locale=n._locales[e]:"object"==typeof e?n._locale=e:void 0},n.getLocale=function(){return n._locale},n.setPattern=function(e){n._pattern=e,n._validator=n.Lexicon.getValidator(e)},n.getPattern=function(){return n._pattern},n.validate=function(e,t){return n.Lexicon.validate(e,t)},n["new"]=function(e,t){return new n.Engine(e,t)},n.absolute=function(e,t){return n["new"](e,t).toAbsolute()},n.plus=function(e,t,o){return n["new"](e,o).plus(t,o)},n.minus=function(e,t,o){return n["new"](e,o).minus(t,o)},n.multiply=function(e,t,o){return n["new"](e,o).multiply(t)},n.divide=function(e,t,o){return n["new"](e,o).divide(t)},n.getFraction=function(e,t,o,r){if(t>o)throw new Error("Improper fraction");return n["new"](e,r).multiply(t).divide(o)},n.getInterval=function(e,t,o){return n["new"](e,o).minus(t,o).toAbsolute()},n.toMilliseconds=function(e,t){return n["new"](e,t).toMilliseconds()},n.toSeconds=function(e,t){return n["new"](e,t).toSeconds()},n.toMinutes=function(e,t){return n["new"](e,t).toMinutes()},n.toHours=function(e,t){return n["new"](e,t).toHours()},n.compare=function(e,t,o){return n["new"](e,o).compareTo(t,o)},n.min=function(e,t){e instanceof Array||(e=Array.prototype.slice.call(arguments));var o=e.reduce(function(e,o){return n["new"](e,t).compareTo(o,t)<0?e:o});return n["new"](o,t)},n.max=function(e,t){e instanceof Array||(e=Array.prototype.slice.call(arguments));var o=e.reduce(function(e,o){return n["new"](e,t).compareTo(o,t)>0?e:o});return n["new"](o,t)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):t.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); -!function(){"use strict";Kairos.locales.en={HOURS:{singular:"hour",plural:"hours"},MINUTES:{singular:"minute",plural:"minutes"},SECONDS:{singular:"second",plural:"seconds"},MILLISECONDS:{singular:"millisecond",plural:"milliseconds"}}}(); -!function(){"use strict";Kairos.locales["pt-BR"]={HOURS:{singular:"hora",plural:"horas"},MINUTES:{singular:"minuto",plural:"minutos"},SECONDS:{singular:"segundo",plural:"segundos"},MILLISECONDS:{singular:"milissegundo",plural:"milissegundos"}}}(); -!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(r){if("string"!=typeof r&&(r=Kairos._pattern),r===Kairos._pattern)return Kairos._validator;for(var a="",s=0,t=r.length;t>s;s++){var i=r[s];switch(i){case e.SIGN:a+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:a+="\\d";break;default:a+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(a)},Kairos.Lexicon.validate=function(e,r){return Kairos.Lexicon.getValidator(r).test(e)},Kairos.Lexicon.parse=function(r,a){if(a||(a=Kairos._pattern),!Kairos.Lexicon.validate(r,a))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=a.length;l>o;o++){var S=a[o];switch(S){case e.SIGN:var g=-1!==["+","-"].indexOf(r[o]);g?s="+"===r[o]:(a=a.slice(0,o)+a.slice(o+1),l--,o--);break;case e.HOURS:t+=r[o];break;case e.MINUTES:i+=r[o];break;case e.SECONDS:n+=r[o];break;case e.MILLISECONDS:c+=r[o]}}var h=Kairos["new"]().setHours(t?+t:0).setMinutes(i?+i:0).setSeconds(n?+n:0).setMilliseconds(c?+c:0);return s||(h.milliseconds=-h.milliseconds),h},Kairos.Lexicon.format=function(r,a){a||(a=Kairos._pattern);for(var s=r.milliseconds>=0,t=String(r.getHours()),i=String(r.getMinutes()),n=String(r.getSeconds()),c=String(r.getMilliseconds()),o="",l=a.length-1;l>=0;l--){var S=a[l];switch(S){case e.SIGN:o=(s?"+":"-")+o;break;case e.HOURS:o=(t.slice(-1)||"0")+o,t.length>0&&(t=t.slice(0,t.length-1));break;case e.MINUTES:o=(i.slice(-1)||"0")+o,i.length>0&&(i=i.slice(0,i.length-1));break;case e.SECONDS:o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.MILLISECONDS:o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;default:o=S+o}}return o}}(); -!function(){"use strict";var i={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Engine=function(i,t){if(i){if(i instanceof Kairos.Engine)return i;if("number"==typeof i)return this.milliseconds=i;if("string"==typeof i&&i.length>0)return new Kairos.Lexicon.parse(i,t);throw new Error("Invalid arguments")}},Kairos.Engine.prototype._resolveStep=function(t,n){switch(t){case 1:this.removeMilliseconds(this.getMilliseconds());break;case i.SECOND:this.removeSeconds(this.getSeconds());break;case i.MINUTE:this.removeMinutes(this.getMinutes());break;case i.HOUR:this.removeHours(this.getHours())}return this.milliseconds+n*t},Kairos.Engine.prototype.milliseconds=0,Kairos.Engine.prototype.setHours=function(t){return this.milliseconds=this._resolveStep(i.HOUR,t),this},Kairos.Engine.prototype.getHours=function(){return Math.trunc(this.milliseconds/i.HOUR)},Kairos.Engine.prototype.setMinutes=function(t){return this.milliseconds=this._resolveStep(i.MINUTE,t),this},Kairos.Engine.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*i.HOUR)/i.MINUTE)},Kairos.Engine.prototype.setSeconds=function(t){return this.milliseconds=this._resolveStep(i.SECOND,t),this},Kairos.Engine.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*i.MINUTE)/i.SECOND)},Kairos.Engine.prototype.setMilliseconds=function(i){return this.milliseconds=this._resolveStep(1,i),this},Kairos.Engine.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*i.SECOND)},Kairos.Engine.prototype.addHours=function(t){return this.milliseconds+=i.HOUR*t,this},Kairos.Engine.prototype.addMinutes=function(t){return this.milliseconds+=i.MINUTE*t,this},Kairos.Engine.prototype.addSeconds=function(t){return this.milliseconds+=i.SECOND*t,this},Kairos.Engine.prototype.addMilliseconds=function(i){return this.milliseconds+=i,this},Kairos.Engine.prototype.removeHours=function(t){return this.milliseconds-=i.HOUR*t,this},Kairos.Engine.prototype.removeMinutes=function(t){return this.milliseconds-=i.MINUTE*t,this},Kairos.Engine.prototype.removeSeconds=function(t){return this.milliseconds-=i.SECOND*t,this},Kairos.Engine.prototype.removeMilliseconds=function(i){return this.milliseconds-=i,this},Kairos.Engine.prototype.toHours=function(){return this.milliseconds/i.HOUR},Kairos.Engine.prototype.toMinutes=function(){return this.milliseconds/i.MINUTE},Kairos.Engine.prototype.toSeconds=function(){return this.milliseconds/i.SECOND},Kairos.Engine.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Engine.prototype.toAbsolute=function(){return this.milliseconds=Math.abs(this.milliseconds),this},Kairos.Engine.prototype.plus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds+=i.toMilliseconds(),this},Kairos.Engine.prototype.minus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds-=i.toMilliseconds(),this},Kairos.Engine.prototype.multiply=function(i){return this.milliseconds*=i,this},Kairos.Engine.prototype.divide=function(i){return this.milliseconds/=i,this},Kairos.Engine.prototype.compareTo=function(i,t){return i=new Kairos.Engine(i,t),this.millisecondsi.toMilliseconds()?1:void 0},Kairos.Engine.prototype.toString=function(i){return Kairos.Lexicon.format(this,i)}}(); \ No newline at end of file +!function(){"use strict";var n={};n._pattern="#hh:mm:ss.SSS",n._validator=/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/;var t,e="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==e&&(t=e.Kairos),n.noConflict=function(){return e.Kairos=t,n},n.setPattern=function(t){n._pattern=t,n._validator=n.Lexicon.getValidator(t)},n.getPattern=function(){return n._pattern},n.validate=function(t,e){return n.Lexicon.validate(t,e)},n["new"]=function(t,e){return new n.Engine(t,e)},n.absolute=function(t,e){return n["new"](t,e).toAbsolute()},n.plus=function(t,e,r){return n["new"](t,r).plus(e,r)},n.minus=function(t,e,r){return n["new"](t,r).minus(e,r)},n.multiply=function(t,e,r){return n["new"](t,r).multiply(e)},n.divide=function(t,e,r){return n["new"](t,r).divide(e)},n.getFraction=function(t,e,r,o){if(e>r)throw new Error("Improper fraction");return n["new"](t,o).multiply(e).divide(r)},n.getInterval=function(t,e,r){return n["new"](t,r).minus(e,r).toAbsolute()},n.toMilliseconds=function(t,e){return n["new"](t,e).toMilliseconds()},n.toSeconds=function(t,e){return n["new"](t,e).toSeconds()},n.toMinutes=function(t,e){return n["new"](t,e).toMinutes()},n.toHours=function(t,e){return n["new"](t,e).toHours()},n.compare=function(t,e,r){return n["new"](t,r).compareTo(e,r)},n.min=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n.compare(t,r,e)<0?t:r});return n["new"](r,e)},n.max=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n["new"](t,e).compareTo(r,e)>0?t:r});return n["new"](r,e)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):e.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); +!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var r="",s=0,t=a.length;t>s;s++){var i=a[s];switch(i){case e.SIGN:r+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:r+="\\d";break;default:r+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(r)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,r){if(r||(r=Kairos._pattern),!Kairos.Lexicon.validate(a,r))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=r.length;l>o;o++){var S=r[o];switch(S){case e.SIGN:var d=-1!==["+","-"].indexOf(a[o]);d?s="+"===a[o]:(r=r.slice(0,o)+r.slice(o+1),l--,o--);break;case e.HOURS:t+=a[o];break;case e.MINUTES:i+=a[o];break;case e.SECONDS:n+=a[o];break;case e.MILLISECONDS:c+=a[o]}}var g=Kairos["new"]().addHours(t?+t:0).addMinutes(i?+i:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return s||(g.milliseconds=-g.milliseconds),g},Kairos.Lexicon.format=function(a,r){r||(r=Kairos._pattern);for(var s=a.milliseconds>=0,t=String(a.getHours()),i=String(a.getMinutes()),n=String(a.getSeconds()),c=String(a.getMilliseconds()),o="",l=r.length-1;l>=0;l--){var S=r[l];switch(S){case e.SIGN:o=(s?"+":"-")+o;break;case e.HOURS:o=(t.slice(-1)||"0")+o,t.length>0&&(t=t.slice(0,t.length-1));break;case e.MINUTES:o=(i.slice(-1)||"0")+o,i.length>0&&(i=i.slice(0,i.length-1));break;case e.SECONDS:o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.MILLISECONDS:o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;default:o=S+o}}return o}}(); +!function(){"use strict";var i={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Engine=function(i,t){if(i){if(i instanceof Kairos.Engine)return i;if("number"==typeof i)return this.milliseconds=i,this;if("string"==typeof i&&i.length>0)return new Kairos.Lexicon.parse(i,t);throw new Error("Invalid arguments")}},Kairos.Engine.prototype._resolveStep=function(t,n){switch(t){case 1:this.removeMilliseconds(this.getMilliseconds());break;case i.SECOND:this.removeSeconds(this.getSeconds());break;case i.MINUTE:this.removeMinutes(this.getMinutes());break;case i.HOUR:this.removeHours(this.getHours())}return this.milliseconds+n*t},Kairos.Engine.prototype.milliseconds=0,Kairos.Engine.prototype.setHours=function(t){return this.milliseconds=this._resolveStep(i.HOUR,t),this},Kairos.Engine.prototype.getHours=function(){return Math.trunc(this.milliseconds/i.HOUR)},Kairos.Engine.prototype.setMinutes=function(t){return this.milliseconds=this._resolveStep(i.MINUTE,t),this},Kairos.Engine.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*i.HOUR)/i.MINUTE)},Kairos.Engine.prototype.setSeconds=function(t){return this.milliseconds=this._resolveStep(i.SECOND,t),this},Kairos.Engine.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*i.MINUTE)/i.SECOND)},Kairos.Engine.prototype.setMilliseconds=function(i){return this.milliseconds=this._resolveStep(1,i),this},Kairos.Engine.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*i.SECOND)},Kairos.Engine.prototype.addHours=function(t){return this.milliseconds+=i.HOUR*t,this},Kairos.Engine.prototype.addMinutes=function(t){return this.milliseconds+=i.MINUTE*t,this},Kairos.Engine.prototype.addSeconds=function(t){return this.milliseconds+=i.SECOND*t,this},Kairos.Engine.prototype.addMilliseconds=function(i){return this.milliseconds+=i,this},Kairos.Engine.prototype.removeHours=function(t){return this.milliseconds-=i.HOUR*t,this},Kairos.Engine.prototype.removeMinutes=function(t){return this.milliseconds-=i.MINUTE*t,this},Kairos.Engine.prototype.removeSeconds=function(t){return this.milliseconds-=i.SECOND*t,this},Kairos.Engine.prototype.removeMilliseconds=function(i){return this.milliseconds-=i,this},Kairos.Engine.prototype.toHours=function(){return this.milliseconds/i.HOUR},Kairos.Engine.prototype.toMinutes=function(){return this.milliseconds/i.MINUTE},Kairos.Engine.prototype.toSeconds=function(){return this.milliseconds/i.SECOND},Kairos.Engine.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Engine.prototype.toAbsolute=function(){return this.milliseconds=Math.abs(this.milliseconds),this},Kairos.Engine.prototype.plus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds+=i.toMilliseconds(),this},Kairos.Engine.prototype.minus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds-=i.toMilliseconds(),this},Kairos.Engine.prototype.multiply=function(i){return this.milliseconds*=i,this},Kairos.Engine.prototype.divide=function(i){return this.milliseconds/=i,this},Kairos.Engine.prototype.compareTo=function(i,t){return i=new Kairos.Engine(i,t),this.millisecondsi.toMilliseconds()?1:void 0},Kairos.Engine.prototype.toString=function(i){return Kairos.Lexicon.format(this,i)}}(); \ No newline at end of file diff --git a/build/kairos-node.js b/build/kairos-node.js index 3064c34..a14cce4 100644 --- a/build/kairos-node.js +++ b/build/kairos-node.js @@ -13,10 +13,7 @@ 'use strict'; var Kairos = {}; - Kairos._locales = {}; - // Set default locale - Kairos._locale = Kairos._locales.en; // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex @@ -48,30 +45,6 @@ return Kairos; }; - /** - * Sets Kairos locale. - * - * @param {String|Object} locale A locale from Kairos.locales or a compatible locale object - * @example Kairos.setLocale('en'); - */ - Kairos.setLocale = function (locale) { - if (typeof locale === 'string') { - return Kairos._locale = Kairos._locales[locale]; - } - if (typeof locale === 'object') { - return Kairos._locale = locale; - } - }; - - /** - * Gets Kairos current locale. - * - * @returns {String} Current locale - */ - Kairos.getLocale = function () { - return Kairos._locale; - }; - /** * Sets Kairos time expression pattern. * Pattern structure is the following: @@ -302,11 +275,12 @@ */ Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; + return Kairos.compare(previous, current, pattern) < 0 ? previous : current; }); return Kairos.new(min, pattern); @@ -323,6 +297,7 @@ */ Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } @@ -335,26 +310,6 @@ // Node.js if (typeof module === 'object' && module.exports) { - (function () { - 'use strict'; - - Kairos.locales.en = { - HOURS: { singular: 'hour', plural: 'hours' }, - MINUTES: { singular: 'minute', plural: 'minutes' }, - SECONDS: { singular: 'second', plural: 'seconds' }, - MILLISECONDS: { singular: 'millisecond', plural: 'milliseconds' } - }; - }()); - (function () { - 'use strict'; - - Kairos.locales['pt-BR'] = { - HOURS: { singular: 'hora', plural: 'horas' }, - MINUTES: { singular: 'minuto', plural: 'minutos' }, - SECONDS: { singular: 'segundo', plural: 'segundos' }, - MILLISECONDS: { singular: 'milissegundo', plural: 'milissegundos' } - }; - }()); /** * @module Kairos.Lexicon */ @@ -467,10 +422,10 @@ } var result = Kairos.new() - .setHours(hours ? +hours : 0) - .setMinutes(minutes ? +minutes : 0) - .setSeconds(seconds ? +seconds : 0) - .setMilliseconds(milliseconds ? +milliseconds : 0); + .addHours(hours ? +hours : 0) + .addMinutes(minutes ? +minutes : 0) + .addSeconds(seconds ? +seconds : 0) + .addMilliseconds(milliseconds ? +milliseconds : 0); if (!sign) { result.milliseconds =- result.milliseconds; @@ -568,7 +523,8 @@ } if (typeof expression === 'number') { - return this.milliseconds = expression; + this.milliseconds = expression; + return this; } if (typeof expression === 'string' && expression.length > 0) { @@ -929,7 +885,6 @@ Kairos.Engine.prototype.toString = function (pattern) { return Kairos.Lexicon.format(this, pattern); }; - }()); module.exports = Kairos; } diff --git a/build/kairos.js b/build/kairos.js index c4cd1a9..40222db 100644 --- a/build/kairos.js +++ b/build/kairos.js @@ -13,10 +13,7 @@ 'use strict'; var Kairos = {}; - Kairos._locales = {}; - // Set default locale - Kairos._locale = Kairos._locales.en; // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex @@ -48,30 +45,6 @@ return Kairos; }; - /** - * Sets Kairos locale. - * - * @param {String|Object} locale A locale from Kairos.locales or a compatible locale object - * @example Kairos.setLocale('en'); - */ - Kairos.setLocale = function (locale) { - if (typeof locale === 'string') { - return Kairos._locale = Kairos._locales[locale]; - } - if (typeof locale === 'object') { - return Kairos._locale = locale; - } - }; - - /** - * Gets Kairos current locale. - * - * @returns {String} Current locale - */ - Kairos.getLocale = function () { - return Kairos._locale; - }; - /** * Sets Kairos time expression pattern. * Pattern structure is the following: @@ -302,11 +275,12 @@ */ Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; + return Kairos.compare(previous, current, pattern) < 0 ? previous : current; }); return Kairos.new(min, pattern); @@ -323,6 +297,7 @@ */ Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } @@ -335,8 +310,6 @@ // Node.js if (typeof module === 'object' && module.exports) { - //=include /locales/en.js - //=include /locales/pt-BR.js //=include /Lexicon.js //=include /Engine.js module.exports = Kairos; @@ -357,26 +330,6 @@ return x < 0 ? Math.ceil(x) : Math.floor(x); }; }()); -(function () { - 'use strict'; - - Kairos.locales.en = { - HOURS: { singular: 'hour', plural: 'hours' }, - MINUTES: { singular: 'minute', plural: 'minutes' }, - SECONDS: { singular: 'second', plural: 'seconds' }, - MILLISECONDS: { singular: 'millisecond', plural: 'milliseconds' } - }; -}()); -(function () { - 'use strict'; - - Kairos.locales['pt-BR'] = { - HOURS: { singular: 'hora', plural: 'horas' }, - MINUTES: { singular: 'minuto', plural: 'minutos' }, - SECONDS: { singular: 'segundo', plural: 'segundos' }, - MILLISECONDS: { singular: 'milissegundo', plural: 'milissegundos' } - }; -}()); /** * @module Kairos.Lexicon */ @@ -489,10 +442,10 @@ } var result = Kairos.new() - .setHours(hours ? +hours : 0) - .setMinutes(minutes ? +minutes : 0) - .setSeconds(seconds ? +seconds : 0) - .setMilliseconds(milliseconds ? +milliseconds : 0); + .addHours(hours ? +hours : 0) + .addMinutes(minutes ? +minutes : 0) + .addSeconds(seconds ? +seconds : 0) + .addMilliseconds(milliseconds ? +milliseconds : 0); if (!sign) { result.milliseconds =- result.milliseconds; @@ -590,7 +543,8 @@ } if (typeof expression === 'number') { - return this.milliseconds = expression; + this.milliseconds = expression; + return this; } if (typeof expression === 'string' && expression.length > 0) { @@ -951,5 +905,4 @@ Kairos.Engine.prototype.toString = function (pattern) { return Kairos.Lexicon.format(this, pattern); }; - }()); \ No newline at end of file diff --git a/package.json b/package.json index cb01b85..ba6e368 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ }, "main": "./build/kairos-node.js", "scripts": { - "test": "node test/node/test.js" + "test": "node test/node/test.js", + "coverage": "istanbul cover gulp test -- -R spec" }, "keywords": [ "time", @@ -38,6 +39,7 @@ "gulp-strip-debug": "^1.1.0", "gulp-uglify": "^1.5.1", "gulp-webserver": "^0.9.1", + "istanbul": "^0.4.2", "jasmine-core": "^2.4.1", "jshint": "^2.9.1", "jshint-stylish": "^2.1.0", diff --git a/src/Lexicon.js b/src/Lexicon.js index 2928d3c..108b839 100644 --- a/src/Lexicon.js +++ b/src/Lexicon.js @@ -110,10 +110,10 @@ } var result = Kairos.new() - .setHours(hours ? +hours : 0) - .setMinutes(minutes ? +minutes : 0) - .setSeconds(seconds ? +seconds : 0) - .setMilliseconds(milliseconds ? +milliseconds : 0); + .addHours(hours ? +hours : 0) + .addMinutes(minutes ? +minutes : 0) + .addSeconds(seconds ? +seconds : 0) + .addMilliseconds(milliseconds ? +milliseconds : 0); if (!sign) { result.milliseconds =- result.milliseconds; diff --git a/src/kairos.js b/src/kairos.js index 3f61bb1..ec5ef08 100644 --- a/src/kairos.js +++ b/src/kairos.js @@ -268,11 +268,12 @@ */ Kairos.min = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } var min = values.reduce(function (previous, current) { - return Kairos.new(previous, pattern).compareTo(current, pattern) < 0 ? previous : current; + return Kairos.compare(previous, current, pattern) < 0 ? previous : current; }); return Kairos.new(min, pattern); @@ -289,6 +290,7 @@ */ Kairos.max = function (values, pattern) { if (!(values instanceof Array)) { + pattern = null; values = Array.prototype.slice.call(arguments); } diff --git a/test/browser/engine.js b/test/browser/engine similarity index 99% rename from test/browser/engine.js rename to test/browser/engine index 294cb1f..6ead3ef 100644 --- a/test/browser/engine.js +++ b/test/browser/engine @@ -23,7 +23,7 @@ describe('Kairos.Engine', function () { // Tests ===================================================================== beforeEach(function () { - engine = new Kairos.Engine('01:30:30:123'); + engine = new Kairos.Engine('01:30:30.123'); }); afterEach(function () { diff --git a/test/browser/kairos.js b/test/browser/kairos.js index ea11b6a..ec79b0b 100644 --- a/test/browser/kairos.js +++ b/test/browser/kairos.js @@ -13,20 +13,17 @@ if (typeof require !== 'undefined') { describe('Kairos', function () { // Setup ===================================================================== - - var engine; - - before(function (done) { - done(); - }); + + var loadDefaults = function () { + Kairos._pattern = '#hh:mm:ss.SSS'; + Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + }; // Tests ===================================================================== - beforeEach(function () { - engine = new Kairos.Engine('01:30:30:123'); - }); - - afterEach(function () { + afterEach(function (done) { + loadDefaults(); + done(); }); it('should return previous instance of Kairos if it already exists', function (done) { @@ -36,132 +33,157 @@ describe('Kairos', function () { done(); }); + it('should set a new pattern to Kairos', function (done) { + Kairos.setPattern('hh:mm'); + assert.equal(Kairos.getPattern() === 'hh:mm', true); + done(); + }); + + it('should validate the expression with the given pattern or the current Kairos pattern', function (done) { + assert.equal(Kairos.validate('22:30', 'hh:mm'), true); + assert.equal(Kairos.validate('22:30', 'hh'), true); + assert.equal(Kairos.validate('-22:30:30.500'), true); + assert.equal(Kairos.validate('-22:30:30'), false); + assert.equal(Kairos.validate('-300:30:30'), false); + done(); + }); + it('should sum first time expression with second time expression', function (done) { - var time = Kairos.plus('01:00', '01:30:35:100'); - assert.equal(time.toString(), '02:30:35:100'); + var time = Kairos.plus('01:00:00.000', '01:30:35.100'); + assert.equal(time.toString(), '+02:30:35.100'); + time = Kairos.plus('01:00:00', '01:30:35', 'hh:mm:ss'); + assert.equal(time.toString('hh:mm:ss'), '02:30:35'); done(); }); it('should subtract first time expression with second time expression', function (done) { - var time = Kairos.minus('01:30:35:100', '01:15'); - assert.equal(time, '00:15:35:100'); + var time = Kairos.minus('01:30:35.100', '01:15:00.000'); + assert.equal(time.toString(), '+00:15:35.100'); + time = Kairos.minus('01:30:35', '01:15:00', 'hh:mm:ss'); + assert.equal(time.toString('hh:mm:ss'), '00:15:35'); done(); }); it('should multiply the time expression by 2', function (done) { - assert.equal(Kairos.multiply('01:30:35:100', 2), '03:01:10:200'); + assert.equal(Kairos.multiply('01:30:35.100', 2).toString(), '+03:01:10.200'); + assert.equal(Kairos.multiply('01:30:35', 2, 'hh:mm:ss').toString('hh:mm:ss'), '03:01:10'); done(); }); it('should divide the time expression by 2', function (done) { - assert.equal(Kairos.divide('01:30:35:100', 2), '00:45:17:550'); + assert.equal(Kairos.divide('01:30:35.100', 2).toString(), '+00:45:17.550'); + assert.equal(Kairos.divide('01:30:35', 2, 'hh:mm:ss').toString('hh:mm:ss'), '00:45:17'); done(); }); it('should return a time fraction', function (done) { - assert.equal(Kairos.getFraction('01:00', 2, 3), '00:40'); + assert.equal(Kairos.getFraction('01:00:00.000', 2, 3).toString(), '+00:40:00.000'); + assert.equal(Kairos.getFraction('01:00:00', 2, 3, 'hh:mm:ss').toString('hh:mm:ss'), '00:40:00'); done(); }); it('should throw error when a improper fraction is given', function (done) { assert.throws(function () { - Kairos.getFraction('01:00', 3, 2); + Kairos.getFraction('01:00:00.000', 3, 2); }); done(); }); - + it('should return a time expression representing the interval between starting time and ending time', function (done) { - assert.equal(Kairos.getInterval('01:00', '02:00').toString(), '01:00'); + assert.equal(Kairos.getInterval('01:00:00.000', '02:00:00.000').toString(), '+01:00:00.000'); + assert.equal(Kairos.getInterval('01:00:00', '02:00:00', 'hh:mm:ss').toString('hh:mm:ss'), '01:00:00'); done(); }); it('should return total milliseconds in the given time expression', function (done) { - assert.equal(Kairos.toMilliseconds('01:30:35:100'), 5435100); + assert.equal(Kairos.toMilliseconds('01:30:35.100'), 5435100); + assert.equal(Kairos.toMilliseconds('01:30:35', 'hh:mm:ss'), 5435000); done(); }); it('should return total seconds in the given time expression', function (done) { - assert.equal(Kairos.toSeconds('01:30:35:100'), 5435.1); + assert.equal(Kairos.toSeconds('01:30:35.100'), 5435.1); + assert.equal(Kairos.toSeconds('01:30:35', 'hh:mm:ss'), 5435); done(); }); it('should return total minutes in the given time expression', function (done) { - assert.equal(Kairos.toMinutes('01:30:35:100'), 90.585); + assert.equal(Kairos.toMinutes('01:30:35.100'), 90.585); + assert.equal(Kairos.toMinutes('01:30:35', 'hh:mm:ss'), 90.58333333333333); done(); }); it('should return total hours in the given time expression', function (done) { - assert.equal(Kairos.toHours('01:30:35:100'), 1.50975); + assert.equal(Kairos.toHours('01:30:35.100'), 1.50975); + assert.equal(Kairos.toHours('01:30:35', 'hh:mm:ss'), 1.5097222222222222); done(); }); it('should compare first time with second time and return -1 for smaller, 0 for equals and 1 for bigger', function (done) { - assert.equal(Kairos.compare('01:00', '02:00'), -1); - assert.equal(Kairos.compare('01:00', '01:00'), 0); - assert.equal(Kairos.compare('02:00', '01:00'), 1); + assert.equal(Kairos.compare('01:00:00.000', '02:00:00.000'), -1); + assert.equal(Kairos.compare('01:00:00.000', '01:00:00.000'), 0); + assert.equal(Kairos.compare('02:00:00.000', '01:00:00.000'), 1); + assert.equal(Kairos.compare('01:00:00', '01:00:00.000', 'hh:mm:ss'), 0); done(); }); - + it('should return the minimun value from the given values', function (done) { - assert.equal(Kairos.min(['01:00', '05:00', '00:30', '00:40']), '00:30'); - + assert.equal(Kairos.min(['01:00', '05:00', '00:30', '00:40'], 'hh:mm').toString('hh:mm'), '00:30'); + assert.equal(Kairos.min([ - new Kairos.Engine('01:00'), - new Kairos.Engine('05:00'), - new Kairos.Engine('00:30'), - new Kairos.Engine('00:40')]), '00:30'); - - assert.equal(Kairos.min('01:00', '05:00', '00:30', '00:40'), '00:30'); - - assert.equal(Kairos.min(new Kairos.Engine('01:00'), - new Kairos.Engine('05:00'), - new Kairos.Engine('00:30'), - new Kairos.Engine('00:40')), '00:30'); - - assert.equal(Kairos.min('01:00'), '01:00'); - + new Kairos.Engine('01:00:00.000'), + new Kairos.Engine('05:00:00.000'), + new Kairos.Engine('00:30:00.000'), + new Kairos.Engine('00:40', 'hh:mm')]).toString(), '+00:30:00.000'); + + assert.equal(Kairos.min('01:00:00.000', '05:00:00.000', '00:30:00.000', '00:40:00.000').toString('hh:mm'), '00:30'); + + assert.equal(Kairos.min(new Kairos.Engine('01:00:00.000'), + new Kairos.Engine('05:00:00.000'), + new Kairos.Engine('00:30:00.000'), + new Kairos.Engine('00:40', 'hh:mm')).toString('mm'), '30'); + + assert.equal(Kairos.min('01:00:00.000').toString('hh:mm'), '01:00'); + done(); }); - + it('should return the maximum value from the given values', function (done) { - assert.equal(Kairos.max(['01:00', '05:00', '00:30', '00:40']), '05:00'); - + assert.equal(Kairos.max(['01:00', '05:00', '00:30', '00:40'], 'hh:mm').toString('hh:mm'), '05:00'); + assert.equal(Kairos.max([ - new Kairos.Engine('01:00'), - new Kairos.Engine('05:00'), - new Kairos.Engine('00:30'), - new Kairos.Engine('00:40')]), '05:00'); - - assert.equal(Kairos.max('01:00', '05:00', '00:30', '00:40'), '05:00'); - - assert.equal(Kairos.max(new Kairos.Engine('01:00'), - new Kairos.Engine('05:00'), - new Kairos.Engine('00:30'), - new Kairos.Engine('00:40')), '05:00'); - - assert.equal(Kairos.max('01:00'), '01:00'); - - done(); - }); - - it('should invalidate the given expression', function (done) { - assert.equal(Kairos.validateExpression('10:000'), false); - done(); - }); - - it('should validate the given expression', function (done) { - assert.equal(Kairos.validateExpression('10:01:00:000'), true); + new Kairos.Engine('01:00:00.000'), + new Kairos.Engine('05:00:00.000'), + new Kairos.Engine('00:30:00.000'), + new Kairos.Engine('00:40', 'hh:mm')]).toString(), '+05:00:00.000'); + + assert.equal(Kairos.max('01:00:00.000', '05:00:00.000', '00:30:00.000', '00:40:00.000').toString('hh:mm'), '05:00'); + + assert.equal(Kairos.max(new Kairos.Engine('01:00:00.000'), + new Kairos.Engine('05:00:00.000'), + new Kairos.Engine('00:30:00.000'), + new Kairos.Engine('00:40', 'hh:mm')).toString('hh'), '05'); + + assert.equal(Kairos.max('01:00:00.000').toString('hh:mm'), '01:00'); + done(); }); it('should create an instance of Kairos.Engine', function (done) { var a = Kairos.new(); - var b = Kairos.new('01:00'); + var b = Kairos.new('+01:00:00.000'); var c = Kairos.new(123); + var d = Kairos.new('01:00', 'hh:mm'); assert.ok(a instanceof Kairos.Engine); assert.ok(b instanceof Kairos.Engine); assert.ok(c instanceof Kairos.Engine); + assert.ok(d instanceof Kairos.Engine); + + assert.throws(function () { + assert.Kairos.new('+01:00:00:000'); + }, Error); + done(); }); }); diff --git a/test/browser/lexicon.js b/test/browser/lexicon.js index e69de29..54cb282 100644 --- a/test/browser/lexicon.js +++ b/test/browser/lexicon.js @@ -0,0 +1,15 @@ +'use strict'; + +// Pre assign variables +var assert = assert; +var Kairos = Kairos; + +// Require modules when running with Node.js +if (typeof require !== 'undefined') { + assert = require('assert'); + Kairos = require('../../build/kairos-node'); +} + +describe('Kairos.Lexicon', function () { + +}); \ No newline at end of file From 5b43f9d0ca0cda0da5c2891af921f32800c8aa46 Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Thu, 18 Feb 2016 12:58:28 +0000 Subject: [PATCH 3/8] updated dependencies --- bower.json | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index b4720a4..fff6d9e 100644 --- a/bower.json +++ b/bower.json @@ -29,7 +29,7 @@ "test" ], "devDependencies": { - "mocha": "~2.3.4", + "mocha": "~2.4.5", "assert": "~0.1.0" } } diff --git a/package.json b/package.json index ba6e368..26b62c0 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "gulp-autoprefixer": "^3.1.0", "gulp-bower": "0.0.13", "gulp-concat": "^2.6.0", - "gulp-esformatter": "^5.0.0", + "gulp-esformatter": "^6.0.0", "gulp-header": "^1.7.1", "gulp-include": "^2.1.0", "gulp-jsdoc": "^0.1.5", @@ -51,7 +51,7 @@ "karma-mocha": "^0.2.1", "karma-phantomjs-launcher": "^1.0.0", "mocha": "^2.4.5", - "phantom": "^0.8.4", + "phantom": "^2.0.0-alpha.2", "phantomjs-prebuilt": "^2.1.3", "run-sequence": "^1.1.5" } From 13eba5d625263094e4477516bd8ccf8099aafbf1 Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Thu, 18 Feb 2016 13:06:49 +0000 Subject: [PATCH 4/8] disabled complexity lint --- .codeclimate.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.codeclimate.yml b/.codeclimate.yml index 1dd4f75..fb93241 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -5,6 +5,9 @@ engines: enabled: true eslint: enabled: true + checks: + complexity: + enabled: false fixme: enabled: true duplication: From dfaaa24091e7efe0be97f95565ad3f8a9192b403 Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Thu, 18 Feb 2016 13:07:38 +0000 Subject: [PATCH 5/8] removed unecessary semicollon --- src/Engine.js | 2 +- src/Lexicon.js | 2 +- src/kairos.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Engine.js b/src/Engine.js index f50c50b..301161c 100644 --- a/src/Engine.js +++ b/src/Engine.js @@ -1,4 +1,4 @@ -;(function () { +(function () { 'use strict'; diff --git a/src/Lexicon.js b/src/Lexicon.js index 108b839..021cc7d 100644 --- a/src/Lexicon.js +++ b/src/Lexicon.js @@ -1,7 +1,7 @@ /** * @module Kairos.Lexicon */ -;(function () { +(function () { 'use strict'; diff --git a/src/kairos.js b/src/kairos.js index ec5ef08..45d43aa 100644 --- a/src/kairos.js +++ b/src/kairos.js @@ -1,7 +1,7 @@ /** * @module Kairos */ -;(function () { +(function () { 'use strict'; From d8c67c84b868bffeb9a458f19dfe5aad1cff4fdf Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Thu, 18 Feb 2016 13:08:45 +0000 Subject: [PATCH 6/8] disabled max-statements lint --- .codeclimate.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.codeclimate.yml b/.codeclimate.yml index fb93241..9488f4c 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -8,6 +8,8 @@ engines: checks: complexity: enabled: false + max-statements: + enabled: false fixme: enabled: true duplication: From fa0eaa0c25a4976d25d641305b531209986e94f1 Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Fri, 19 Feb 2016 10:32:42 +0000 Subject: [PATCH 7/8] finished tests --- build/kairos-debug.js | 20 ++++----- build/kairos-min.js | 4 +- build/kairos-node.js | 20 ++++----- build/kairos.js | 20 ++++----- src/Lexicon.js | 8 ++-- src/kairos.js | 6 +-- test/browser/{engine => engine.js} | 66 +++++++++++++++++++----------- test/browser/kairos.js | 17 +++++++- test/browser/lexicon.js | 51 ++++++++++++++++++++++- 9 files changed, 146 insertions(+), 66 deletions(-) rename test/browser/{engine => engine.js} (85%) diff --git a/build/kairos-debug.js b/build/kairos-debug.js index 40222db..00dae38 100644 --- a/build/kairos-debug.js +++ b/build/kairos-debug.js @@ -8,7 +8,7 @@ /** * @module Kairos */ -;(function () { +(function () { 'use strict'; @@ -17,7 +17,7 @@ // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex - Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); // global on the server, window in the browser var previous_Kairos; @@ -55,11 +55,11 @@ * S -> milliseconds * * @param {String} pattern The pattern to parse and format time expressions - * @example Kairos.setPattern('hh:mm:ss.fff'); + * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ Kairos.setPattern = function (pattern) { - Kairos._pattern = pattern; Kairos._validator = Kairos.Lexicon.getValidator(pattern); + Kairos._pattern = pattern; }; /** @@ -333,7 +333,7 @@ /** * @module Kairos.Lexicon */ -;(function () { +(function () { 'use strict'; @@ -468,10 +468,10 @@ } var sign = instance.milliseconds >= 0, - hours = String(instance.getHours()), - minutes = String(instance.getMinutes()), - seconds = String(instance.getSeconds()), - milliseconds = String(instance.getMilliseconds()); + hours = String(Math.abs(instance.getHours())), + minutes = String(Math.abs(instance.getMinutes())), + seconds = String(Math.abs(instance.getSeconds())), + milliseconds = String(Math.abs(instance.getMilliseconds())); var result = ''; for (var i = pattern.length - 1; i >= 0; i--) { @@ -512,7 +512,7 @@ return result; }; }()); -;(function () { +(function () { 'use strict'; diff --git a/build/kairos-min.js b/build/kairos-min.js index a1e200d..02841fe 100644 --- a/build/kairos-min.js +++ b/build/kairos-min.js @@ -5,6 +5,6 @@ * @link https://github.com/kairos * @license BSD-2-Clause */ -!function(){"use strict";var n={};n._pattern="#hh:mm:ss.SSS",n._validator=/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/;var t,e="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==e&&(t=e.Kairos),n.noConflict=function(){return e.Kairos=t,n},n.setPattern=function(t){n._pattern=t,n._validator=n.Lexicon.getValidator(t)},n.getPattern=function(){return n._pattern},n.validate=function(t,e){return n.Lexicon.validate(t,e)},n["new"]=function(t,e){return new n.Engine(t,e)},n.absolute=function(t,e){return n["new"](t,e).toAbsolute()},n.plus=function(t,e,r){return n["new"](t,r).plus(e,r)},n.minus=function(t,e,r){return n["new"](t,r).minus(e,r)},n.multiply=function(t,e,r){return n["new"](t,r).multiply(e)},n.divide=function(t,e,r){return n["new"](t,r).divide(e)},n.getFraction=function(t,e,r,o){if(e>r)throw new Error("Improper fraction");return n["new"](t,o).multiply(e).divide(r)},n.getInterval=function(t,e,r){return n["new"](t,r).minus(e,r).toAbsolute()},n.toMilliseconds=function(t,e){return n["new"](t,e).toMilliseconds()},n.toSeconds=function(t,e){return n["new"](t,e).toSeconds()},n.toMinutes=function(t,e){return n["new"](t,e).toMinutes()},n.toHours=function(t,e){return n["new"](t,e).toHours()},n.compare=function(t,e,r){return n["new"](t,r).compareTo(e,r)},n.min=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n.compare(t,r,e)<0?t:r});return n["new"](r,e)},n.max=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n["new"](t,e).compareTo(r,e)>0?t:r});return n["new"](r,e)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):e.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); -!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var r="",s=0,t=a.length;t>s;s++){var i=a[s];switch(i){case e.SIGN:r+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:r+="\\d";break;default:r+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(r)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,r){if(r||(r=Kairos._pattern),!Kairos.Lexicon.validate(a,r))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=r.length;l>o;o++){var S=r[o];switch(S){case e.SIGN:var d=-1!==["+","-"].indexOf(a[o]);d?s="+"===a[o]:(r=r.slice(0,o)+r.slice(o+1),l--,o--);break;case e.HOURS:t+=a[o];break;case e.MINUTES:i+=a[o];break;case e.SECONDS:n+=a[o];break;case e.MILLISECONDS:c+=a[o]}}var g=Kairos["new"]().addHours(t?+t:0).addMinutes(i?+i:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return s||(g.milliseconds=-g.milliseconds),g},Kairos.Lexicon.format=function(a,r){r||(r=Kairos._pattern);for(var s=a.milliseconds>=0,t=String(a.getHours()),i=String(a.getMinutes()),n=String(a.getSeconds()),c=String(a.getMilliseconds()),o="",l=r.length-1;l>=0;l--){var S=r[l];switch(S){case e.SIGN:o=(s?"+":"-")+o;break;case e.HOURS:o=(t.slice(-1)||"0")+o,t.length>0&&(t=t.slice(0,t.length-1));break;case e.MINUTES:o=(i.slice(-1)||"0")+o,i.length>0&&(i=i.slice(0,i.length-1));break;case e.SECONDS:o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.MILLISECONDS:o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;default:o=S+o}}return o}}(); +!function(){"use strict";var n={};n._pattern="#hh:mm:ss.SSS",n._validator=new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/);var t,e="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==e&&(t=e.Kairos),n.noConflict=function(){return e.Kairos=t,n},n.setPattern=function(t){n._validator=n.Lexicon.getValidator(t),n._pattern=t},n.getPattern=function(){return n._pattern},n.validate=function(t,e){return n.Lexicon.validate(t,e)},n["new"]=function(t,e){return new n.Engine(t,e)},n.absolute=function(t,e){return n["new"](t,e).toAbsolute()},n.plus=function(t,e,r){return n["new"](t,r).plus(e,r)},n.minus=function(t,e,r){return n["new"](t,r).minus(e,r)},n.multiply=function(t,e,r){return n["new"](t,r).multiply(e)},n.divide=function(t,e,r){return n["new"](t,r).divide(e)},n.getFraction=function(t,e,r,o){if(e>r)throw new Error("Improper fraction");return n["new"](t,o).multiply(e).divide(r)},n.getInterval=function(t,e,r){return n["new"](t,r).minus(e,r).toAbsolute()},n.toMilliseconds=function(t,e){return n["new"](t,e).toMilliseconds()},n.toSeconds=function(t,e){return n["new"](t,e).toSeconds()},n.toMinutes=function(t,e){return n["new"](t,e).toMinutes()},n.toHours=function(t,e){return n["new"](t,e).toHours()},n.compare=function(t,e,r){return n["new"](t,r).compareTo(e,r)},n.min=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n.compare(t,r,e)<0?t:r});return n["new"](r,e)},n.max=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n["new"](t,e).compareTo(r,e)>0?t:r});return n["new"](r,e)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):e.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); +!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var r="",s=0,t=a.length;t>s;s++){var i=a[s];switch(i){case e.SIGN:r+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:r+="\\d";break;default:r+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(r)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,r){if(r||(r=Kairos._pattern),!Kairos.Lexicon.validate(a,r))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=r.length;l>o;o++){var S=r[o];switch(S){case e.SIGN:var d=-1!==["+","-"].indexOf(a[o]);d?s="+"===a[o]:(r=r.slice(0,o)+r.slice(o+1),l--,o--);break;case e.HOURS:t+=a[o];break;case e.MINUTES:i+=a[o];break;case e.SECONDS:n+=a[o];break;case e.MILLISECONDS:c+=a[o]}}var g=Kairos["new"]().addHours(t?+t:0).addMinutes(i?+i:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return s||(g.milliseconds=-g.milliseconds),g},Kairos.Lexicon.format=function(a,r){r||(r=Kairos._pattern);for(var s=a.milliseconds>=0,t=String(Math.abs(a.getHours())),i=String(Math.abs(a.getMinutes())),n=String(Math.abs(a.getSeconds())),c=String(Math.abs(a.getMilliseconds())),o="",l=r.length-1;l>=0;l--){var S=r[l];switch(S){case e.SIGN:o=(s?"+":"-")+o;break;case e.HOURS:o=(t.slice(-1)||"0")+o,t.length>0&&(t=t.slice(0,t.length-1));break;case e.MINUTES:o=(i.slice(-1)||"0")+o,i.length>0&&(i=i.slice(0,i.length-1));break;case e.SECONDS:o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.MILLISECONDS:o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;default:o=S+o}}return o}}(); !function(){"use strict";var i={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Engine=function(i,t){if(i){if(i instanceof Kairos.Engine)return i;if("number"==typeof i)return this.milliseconds=i,this;if("string"==typeof i&&i.length>0)return new Kairos.Lexicon.parse(i,t);throw new Error("Invalid arguments")}},Kairos.Engine.prototype._resolveStep=function(t,n){switch(t){case 1:this.removeMilliseconds(this.getMilliseconds());break;case i.SECOND:this.removeSeconds(this.getSeconds());break;case i.MINUTE:this.removeMinutes(this.getMinutes());break;case i.HOUR:this.removeHours(this.getHours())}return this.milliseconds+n*t},Kairos.Engine.prototype.milliseconds=0,Kairos.Engine.prototype.setHours=function(t){return this.milliseconds=this._resolveStep(i.HOUR,t),this},Kairos.Engine.prototype.getHours=function(){return Math.trunc(this.milliseconds/i.HOUR)},Kairos.Engine.prototype.setMinutes=function(t){return this.milliseconds=this._resolveStep(i.MINUTE,t),this},Kairos.Engine.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*i.HOUR)/i.MINUTE)},Kairos.Engine.prototype.setSeconds=function(t){return this.milliseconds=this._resolveStep(i.SECOND,t),this},Kairos.Engine.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*i.MINUTE)/i.SECOND)},Kairos.Engine.prototype.setMilliseconds=function(i){return this.milliseconds=this._resolveStep(1,i),this},Kairos.Engine.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*i.SECOND)},Kairos.Engine.prototype.addHours=function(t){return this.milliseconds+=i.HOUR*t,this},Kairos.Engine.prototype.addMinutes=function(t){return this.milliseconds+=i.MINUTE*t,this},Kairos.Engine.prototype.addSeconds=function(t){return this.milliseconds+=i.SECOND*t,this},Kairos.Engine.prototype.addMilliseconds=function(i){return this.milliseconds+=i,this},Kairos.Engine.prototype.removeHours=function(t){return this.milliseconds-=i.HOUR*t,this},Kairos.Engine.prototype.removeMinutes=function(t){return this.milliseconds-=i.MINUTE*t,this},Kairos.Engine.prototype.removeSeconds=function(t){return this.milliseconds-=i.SECOND*t,this},Kairos.Engine.prototype.removeMilliseconds=function(i){return this.milliseconds-=i,this},Kairos.Engine.prototype.toHours=function(){return this.milliseconds/i.HOUR},Kairos.Engine.prototype.toMinutes=function(){return this.milliseconds/i.MINUTE},Kairos.Engine.prototype.toSeconds=function(){return this.milliseconds/i.SECOND},Kairos.Engine.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Engine.prototype.toAbsolute=function(){return this.milliseconds=Math.abs(this.milliseconds),this},Kairos.Engine.prototype.plus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds+=i.toMilliseconds(),this},Kairos.Engine.prototype.minus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds-=i.toMilliseconds(),this},Kairos.Engine.prototype.multiply=function(i){return this.milliseconds*=i,this},Kairos.Engine.prototype.divide=function(i){return this.milliseconds/=i,this},Kairos.Engine.prototype.compareTo=function(i,t){return i=new Kairos.Engine(i,t),this.millisecondsi.toMilliseconds()?1:void 0},Kairos.Engine.prototype.toString=function(i){return Kairos.Lexicon.format(this,i)}}(); \ No newline at end of file diff --git a/build/kairos-node.js b/build/kairos-node.js index a14cce4..3d49247 100644 --- a/build/kairos-node.js +++ b/build/kairos-node.js @@ -8,7 +8,7 @@ /** * @module Kairos */ -;(function () { +(function () { 'use strict'; @@ -17,7 +17,7 @@ // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex - Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); // global on the server, window in the browser var previous_Kairos; @@ -55,11 +55,11 @@ * S -> milliseconds * * @param {String} pattern The pattern to parse and format time expressions - * @example Kairos.setPattern('hh:mm:ss.fff'); + * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ Kairos.setPattern = function (pattern) { - Kairos._pattern = pattern; Kairos._validator = Kairos.Lexicon.getValidator(pattern); + Kairos._pattern = pattern; }; /** @@ -313,7 +313,7 @@ /** * @module Kairos.Lexicon */ - ;(function () { + (function () { 'use strict'; @@ -448,10 +448,10 @@ } var sign = instance.milliseconds >= 0, - hours = String(instance.getHours()), - minutes = String(instance.getMinutes()), - seconds = String(instance.getSeconds()), - milliseconds = String(instance.getMilliseconds()); + hours = String(Math.abs(instance.getHours())), + minutes = String(Math.abs(instance.getMinutes())), + seconds = String(Math.abs(instance.getSeconds())), + milliseconds = String(Math.abs(instance.getMilliseconds())); var result = ''; for (var i = pattern.length - 1; i >= 0; i--) { @@ -492,7 +492,7 @@ return result; }; }()); - ;(function () { + (function () { 'use strict'; diff --git a/build/kairos.js b/build/kairos.js index 40222db..00dae38 100644 --- a/build/kairos.js +++ b/build/kairos.js @@ -8,7 +8,7 @@ /** * @module Kairos */ -;(function () { +(function () { 'use strict'; @@ -17,7 +17,7 @@ // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex - Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); // global on the server, window in the browser var previous_Kairos; @@ -55,11 +55,11 @@ * S -> milliseconds * * @param {String} pattern The pattern to parse and format time expressions - * @example Kairos.setPattern('hh:mm:ss.fff'); + * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ Kairos.setPattern = function (pattern) { - Kairos._pattern = pattern; Kairos._validator = Kairos.Lexicon.getValidator(pattern); + Kairos._pattern = pattern; }; /** @@ -333,7 +333,7 @@ /** * @module Kairos.Lexicon */ -;(function () { +(function () { 'use strict'; @@ -468,10 +468,10 @@ } var sign = instance.milliseconds >= 0, - hours = String(instance.getHours()), - minutes = String(instance.getMinutes()), - seconds = String(instance.getSeconds()), - milliseconds = String(instance.getMilliseconds()); + hours = String(Math.abs(instance.getHours())), + minutes = String(Math.abs(instance.getMinutes())), + seconds = String(Math.abs(instance.getSeconds())), + milliseconds = String(Math.abs(instance.getMilliseconds())); var result = ''; for (var i = pattern.length - 1; i >= 0; i--) { @@ -512,7 +512,7 @@ return result; }; }()); -;(function () { +(function () { 'use strict'; diff --git a/src/Lexicon.js b/src/Lexicon.js index 021cc7d..f024481 100644 --- a/src/Lexicon.js +++ b/src/Lexicon.js @@ -136,10 +136,10 @@ } var sign = instance.milliseconds >= 0, - hours = String(instance.getHours()), - minutes = String(instance.getMinutes()), - seconds = String(instance.getSeconds()), - milliseconds = String(instance.getMilliseconds()); + hours = String(Math.abs(instance.getHours())), + minutes = String(Math.abs(instance.getMinutes())), + seconds = String(Math.abs(instance.getSeconds())), + milliseconds = String(Math.abs(instance.getMilliseconds())); var result = ''; for (var i = pattern.length - 1; i >= 0; i--) { diff --git a/src/kairos.js b/src/kairos.js index 45d43aa..03da33f 100644 --- a/src/kairos.js +++ b/src/kairos.js @@ -10,7 +10,7 @@ // Set default pattern Kairos._pattern = '#hh:mm:ss.SSS'; // Set default regex - Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); // global on the server, window in the browser var previous_Kairos; @@ -48,11 +48,11 @@ * S -> milliseconds * * @param {String} pattern The pattern to parse and format time expressions - * @example Kairos.setPattern('hh:mm:ss.fff'); + * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ Kairos.setPattern = function (pattern) { - Kairos._pattern = pattern; Kairos._validator = Kairos.Lexicon.getValidator(pattern); + Kairos._pattern = pattern; }; /** diff --git a/test/browser/engine b/test/browser/engine.js similarity index 85% rename from test/browser/engine rename to test/browser/engine.js index 6ead3ef..e981419 100644 --- a/test/browser/engine +++ b/test/browser/engine.js @@ -14,6 +14,11 @@ describe('Kairos.Engine', function () { // Setup ===================================================================== + var loadDefaults = function () { + Kairos._pattern = '#hh:mm:ss.SSS'; + Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); + }; + var engine; before(function (done) { @@ -22,8 +27,11 @@ describe('Kairos.Engine', function () { // Tests ===================================================================== - beforeEach(function () { + beforeEach(function (done) { + loadDefaults(); engine = new Kairos.Engine('01:30:30.123'); + + done(); }); afterEach(function () { @@ -31,7 +39,7 @@ describe('Kairos.Engine', function () { it('should return an instance of Kairos.Engine', function (done) { assert.doesNotThrow(function () { - var t1 = new Kairos.Engine('10:20:30:123'); + var t1 = new Kairos.Engine('10:20:30.123'); var t2 = new Kairos.Engine(1); assert.equal(t1.getMilliseconds(), 123); @@ -51,12 +59,25 @@ describe('Kairos.Engine', function () { assert.equal(t2.toSeconds(), 0.001); assert.equal(t2.toMinutes(), 0.000016666666666666667); assert.equal(t2.toHours(), 2.7777777777777776e-7); + + var time = new Kairos.Engine(new Kairos.Engine()); + assert.equal(time.getMilliseconds(), 0); + + time = new Kairos.Engine('10:00', 'hh:mm'); + assert.equal(time.toString('hh:mm'), '10:00'); + + Kairos.setPattern('hhh:mm:ss'); + + time = new Kairos.Engine('100:00:00'); + assert.equal(time.toString(), '100:00:00'); }); + done(); }); it('should return an instance of Kairos.Engine with zero value', function (done) { assert.equal(new Kairos.Engine().toMilliseconds(), 0); + done(); }); @@ -64,13 +85,7 @@ describe('Kairos.Engine', function () { assert.throws(function () { new Kairos.Engine('00:00:00:00:00'); }, Error); - done(); - }); - it('should throw error when a expression time step is not a number', function (done) { - assert.throws(function () { - new Kairos.Engine('00:00:00:a0'); - }, Error); done(); }); @@ -115,13 +130,13 @@ describe('Kairos.Engine', function () { }); it('should return the given expression', function (done) { - assert.equal(engine.toString(), '01:30:30:123'); + assert.equal(engine.toString(), '+01:30:30.123'); done(); }); it('should return the given negative expression', function (done) { - engine = new Kairos.Engine('-01:30:30:123'); - assert.equal(engine.toString(), '-01:30:30:123'); + engine = new Kairos.Engine('-01:30:30.123'); + assert.equal(engine.toString(), '-01:30:30.123'); done(); }); @@ -240,40 +255,41 @@ describe('Kairos.Engine', function () { }); it('should sum two time expressions', function (done) { - var addend = new Kairos.Engine('01:30:30:123'); + var addend = new Kairos.Engine('01:30:30.123'); var t = engine.plus(addend); - assert.equal(engine.toString(), '03:01:00:246'); + assert.equal(engine.toString(), '+03:01:00.246'); assert.ok(t instanceof Kairos.Engine); - assert.equal(t.toString(), '03:01:00:246'); + assert.equal(t.toString(), '+03:01:00.246'); done(); }); it('should subtract two time expressions', function (done) { - var substrahend = new Kairos.Engine('01:30:30:123'); + var substrahend = new Kairos.Engine('01:30:30.123'); var t = engine.minus(substrahend); - assert.equal(engine.toString(), '00:00'); + assert.equal(engine.toString('hh:mm'), '00:00'); assert.ok(t instanceof Kairos.Engine); - assert.equal(t.toString(), '00:00'); + assert.equal(t.toString('hh:mm'), '00:00'); done(); }); it('should multiply the time expression by 2', function (done) { var t = engine.multiply(2); - assert.equal(engine.toString(), '03:01:00:246'); + assert.equal(engine.toString(), '+03:01:00.246'); assert.ok(t instanceof Kairos.Engine); - assert.equal(t.toString(), '03:01:00:246'); + assert.equal(t.toString(), '+03:01:00.246'); done(); }); it('should divide the time expression by 2', function (done) { var t = engine.divide(2); - assert.equal(engine.toString(), '00:45:15:061'); + assert.equal(engine.toString(), '+00:45:15.061'); assert.ok(t instanceof Kairos.Engine); - assert.equal(t.toString(), '00:45:15:061'); + assert.equal(t.toString(), '+00:45:15.061'); done(); }); it('should compare first time with second time and return -1 for smaller, 0 for equals and 1 for bigger', function (done) { + Kairos.setPattern('hh:mm'); engine = new Kairos.Engine('01:00'); assert.equal(engine.compareTo(new Kairos.Engine('02:00')), -1); assert.equal(engine.compareTo(new Kairos.Engine('01:00')), 0); @@ -282,18 +298,20 @@ describe('Kairos.Engine', function () { }); it('should parse correctly expressions whith hours < 10 and > 99', function (done) { + Kairos.setPattern('hh:mm'); var a = new Kairos.Engine('60:00'); var b = new Kairos.Engine('80:00'); a.plus(b); - assert.equal(a.toString(), '140:00'); - - a.minus(new Kairos.Engine('139:00')); + assert.equal(a.toString('hhh:mm'), '140:00'); + + a.minus(new Kairos.Engine('139:00', 'hhh:mm')); assert.equal(a.toString(), '01:00'); done(); }); it('should execute commands in sequence and output the correct result', function (done) { + Kairos.setPattern('hh:mm'); var t = new Kairos.Engine('01:00').plus('02:00').minus('01:00').divide(2).multiply(10); assert.ok(t instanceof Kairos.Engine); assert.equal(t.toString(), '10:00'); diff --git a/test/browser/kairos.js b/test/browser/kairos.js index ec79b0b..f979f1a 100644 --- a/test/browser/kairos.js +++ b/test/browser/kairos.js @@ -13,10 +13,10 @@ if (typeof require !== 'undefined') { describe('Kairos', function () { // Setup ===================================================================== - + var loadDefaults = function () { Kairos._pattern = '#hh:mm:ss.SSS'; - Kairos._validator = /^[+-]?\d\d:\d\d:\d\d\.\d\d\d/; + Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); }; // Tests ===================================================================== @@ -137,6 +137,8 @@ describe('Kairos', function () { new Kairos.Engine('00:40', 'hh:mm')]).toString(), '+00:30:00.000'); assert.equal(Kairos.min('01:00:00.000', '05:00:00.000', '00:30:00.000', '00:40:00.000').toString('hh:mm'), '00:30'); + + assert.equal(Kairos.min(100, 200, 300).toString('SSS'), '100'); assert.equal(Kairos.min(new Kairos.Engine('01:00:00.000'), new Kairos.Engine('05:00:00.000'), @@ -158,6 +160,8 @@ describe('Kairos', function () { new Kairos.Engine('00:40', 'hh:mm')]).toString(), '+05:00:00.000'); assert.equal(Kairos.max('01:00:00.000', '05:00:00.000', '00:30:00.000', '00:40:00.000').toString('hh:mm'), '05:00'); + + assert.equal(Kairos.max(100, 200, 300).toString('SSS'), '300'); assert.equal(Kairos.max(new Kairos.Engine('01:00:00.000'), new Kairos.Engine('05:00:00.000'), @@ -186,4 +190,13 @@ describe('Kairos', function () { done(); }); + + it('should return an instance with absolute value', function (done) { + assert.equal(Kairos.absolute('-10:30:00.000').toString(), '+10:30:00.000'); + assert.equal(Kairos.absolute('-10:30', '#hh:mm').toString(), '+10:30:00.000'); + assert.equal(Kairos.absolute(new Kairos.Engine('-10:30:00.000')), '+10:30:00.000'); + assert.equal(Kairos.absolute(-500).toString(), '+00:00:00.500'); + + done(); + }); }); diff --git a/test/browser/lexicon.js b/test/browser/lexicon.js index 54cb282..8899ce8 100644 --- a/test/browser/lexicon.js +++ b/test/browser/lexicon.js @@ -11,5 +11,54 @@ if (typeof require !== 'undefined') { } describe('Kairos.Lexicon', function () { - + + it('should generate a validator from the given pattern', function (done) { + var validator = Kairos.Lexicon.getValidator('hh:mm'); + assert.ok(validator.test('10:30')); + assert.equal(validator.test('10'), false); + + validator = Kairos.Lexicon.getValidator(); + assert.ok(validator.test('10:30:00.000')); + assert.equal(validator.test('10:30'), false); + + validator = Kairos.Lexicon.getValidator(123456); + assert.ok(validator.test('10:30:00.000')); + assert.equal(validator.test('10:30'), false); + + done(); + }); + + it('should validate an expression using a pattern', function (done) { + assert.ok(Kairos.Lexicon.validate('10:00:30.000')); + assert.equal(Kairos.Lexicon.validate('10:00:30'), false); + assert.equal(Kairos.Lexicon.validate('10:00:30', 'hh:mm:ss'), true); + + done(); + }); + + it('should parse the given expression to a Kairos.Engine instance', function (done) { + var time = Kairos.Lexicon.parse('10:30:00.000'); + assert.ok(time instanceof Kairos.Engine); + assert.equal(time.toString(), '+10:30:00.000'); + + time = Kairos.Lexicon.parse('10:30', 'hh:mm'); + assert.ok(time instanceof Kairos.Engine); + assert.equal(time.toString(), '+10:30:00.000'); + + assert.throws(function () { + Kairos.Lexicon.parse('10:30'); + }, Error); + + done(); + }); + + it('should return a formated string from a Kairos.Engine ', function (done) { + var time = Kairos.Lexicon.format(Kairos.new('10:00:00.000'), 'hh:mm'); + assert.equal(time, '10:00'); + + time = Kairos.Lexicon.format(Kairos.new('10:00:00.000')); + assert.equal(time, '+10:00:00.000'); + + done(); + }); }); \ No newline at end of file From df943355dede580f76086a9748240b780f374f7e Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Mon, 28 Mar 2016 15:40:23 +0000 Subject: [PATCH 8/8] tests updated --- build/kairos-debug.js | 164 +++++++++++++++++++++++++++++++------- build/kairos-min.js | 6 +- build/kairos-node.js | 164 +++++++++++++++++++++++++++++++------- build/kairos.js | 164 +++++++++++++++++++++++++++++++------- examples/basic/index.html | 14 ++-- examples/basic/index.js | 2 + examples/calc/calc.js | 12 ++- examples/usecase/index.js | 5 +- examples/usecase/task.js | 2 +- package.json | 20 ++--- src/Engine.js | 20 +++-- src/Lexicon.js | 81 +++++++++++++++++-- src/kairos.js | 63 +++++++++++---- test/browser/engine.js | 20 ++++- test/browser/kairos.js | 17 ++++ test/browser/lexicon.js | 24 ++++++ 16 files changed, 624 insertions(+), 154 deletions(-) diff --git a/build/kairos-debug.js b/build/kairos-debug.js index 00dae38..535393c 100644 --- a/build/kairos-debug.js +++ b/build/kairos-debug.js @@ -14,10 +14,10 @@ var Kairos = {}; - // Set default pattern + // Set defaults Kairos._pattern = '#hh:mm:ss.SSS'; - // Set default regex Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); + Kairos._autoParser = false; // global on the server, window in the browser var previous_Kairos; @@ -54,6 +54,8 @@ * s -> seconds * S -> milliseconds * + * @memberof module:Kairos + * @method setPattern * @param {String} pattern The pattern to parse and format time expressions * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ @@ -65,15 +67,42 @@ /** * Gets current Kairos pattern. * + * @memberof module:Kairos + * @method getPattern * @returns {String} Current Kairos pattern */ Kairos.getPattern = function () { return Kairos._pattern; }; + /** + * Sets Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method setAutoParser + * @param {Boolean} yN True to use or false to not use auto parser + * @example Kairos.setAutoParser(true); + */ + Kairos.setAutoParser = function (yN) { + Kairos._autoParser = !!yN; + }; + + /** + * Gets current Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method getAutoParser + * @returns {Boolean} True if auto parse is being used or false if not + */ + Kairos.getAutoParser = function () { + return Kairos._autoParser; + }; + /** * Validates the give expression with the current or given pattern. * + * @memberof module:Kairos + * @method validate * @param {String} expression Time expression to validate * @param {String} pattern Pattern to test the expression * @example Kairos.validate('10:30', 'hh:mm'); @@ -89,7 +118,7 @@ * @memberof module:Kairos * @method new * @param {String|Number|kairos.Engine} time Time expression to create an instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ Kairos.new = function (time, pattern) { @@ -102,7 +131,7 @@ * @memberof module:Kairos * @method absolute * @param {String|Number|kairos.Engine} time Time expression to get its absolute value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ Kairos.absolute = function (time, pattern) { @@ -116,7 +145,7 @@ * @method plus * @param {String|Number|kairos.Engine} augend Augend time expression * @param {String|Number|kairos.Engine} addend Addend time expression - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ Kairos.plus = function (augend, addend, pattern) { @@ -130,7 +159,7 @@ * @method minus * @param {String|Number|kairos.Engine} minuend Minuend time expression * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ Kairos.minus = function (minuend, subtrahend, pattern) { @@ -144,7 +173,7 @@ * @method multiply * @param {String|Number|kairos.Engine} multiplier Multiplier time expression * @param {Number} multiplicand Multiplicand value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ Kairos.multiply = function (multiplier, multiplicand, pattern) { @@ -158,7 +187,7 @@ * @method divide * @param {String|Number|kairos.Engine} dividend Dividend time expression * @param {Number} divisor Divisor value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with division result */ Kairos.divide = function (dividend, divisor, pattern) { @@ -173,7 +202,7 @@ * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction * @param {Number} numerator Numerator value * @param {Number} denominator Denominator value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ Kairos.getFraction = function (time, numerator, denominator, pattern) { @@ -190,7 +219,7 @@ * @method getInterval * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 */ Kairos.getInterval = function (time1, time2, pattern) { @@ -203,7 +232,7 @@ * @memberof module:Kairos * @method toMilliseconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total milliseconds in the time expression */ Kairos.toMilliseconds = function (time, pattern) { @@ -216,7 +245,7 @@ * @memberof module:Kairos * @method toSeconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total seconds in the time expression */ Kairos.toSeconds = function (time, pattern) { @@ -229,7 +258,7 @@ * @memberof module:Kairos * @method toMinutes * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total minutes in the time expression */ Kairos.toMinutes = function (time, pattern) { @@ -242,7 +271,7 @@ * @memberof module:Kairos * @method toHours * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total hours in the time expression */ Kairos.toHours = function (time, pattern) { @@ -257,7 +286,7 @@ * @method compare * @param {String|Number} comparand Time to compare with * @param {String|Number} comparator Time to be compared with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ Kairos.compare = function (comparand, comparator, pattern) { @@ -270,7 +299,7 @@ * @memberof module:Kairos * @method min * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ Kairos.min = function (values, pattern) { @@ -292,7 +321,7 @@ * @memberof module:Kairos * @method max * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {String} Kairos.Engine instance with the greatest value found in the list */ Kairos.max = function (values, pattern) { @@ -331,7 +360,7 @@ }; }()); /** - * @module Kairos.Lexicon + * @module Lexicon */ (function () { @@ -350,7 +379,9 @@ /** * Gets a regex from a pattern. * - * @param {String} [Kairos pattern] pattern Pattern to convert + * @memberof module:Lexicon + * @method getValidator + * @param {String} [pattern] Pattern to convert * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); * @returns {RegExp} */ @@ -386,9 +417,11 @@ /** * Validates if given expression matches the current pattern. * + * @memberof module:Lexicon + * @method validate * @param {String} expression Time expression to be validated - * @param {String} [Kairos pattern] pattern Pattern to validate - * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @param {String} [pattern] Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.SSS'); * @returns {Boolean} True if expression is valid, false if expression is invalid */ Kairos.Lexicon.validate = function (expression, pattern) { @@ -398,8 +431,10 @@ /** * Parses given time expression to a Kairos.Engine instance. * + * @memberof module:Lexicon + * @method parse * @param {String} expression Time expression to be parsed - * @param {String} [Kairos pattern] pattern Pattern to parse + * @param {String} [pattern] Pattern to parse * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine */ @@ -457,12 +492,15 @@ /** * Returns a formated string from an Kairos.Engine instance. * + * @memberof module:Lexicon + * @method format * @param {Kairos.Engine} instance The instance to format - * @param {String} [Kairos pattern] pattern Pattern to format + * @param {String} [pattern] Pattern to format + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); * @returns {String} Formated time expression */ - Kairos.Lexicon.format = function (instance, pattern) { + Kairos.Lexicon.format = function (instance, pattern, allowOverflow) { if (!pattern) { pattern = Kairos._pattern; } @@ -473,7 +511,9 @@ seconds = String(Math.abs(instance.getSeconds())), milliseconds = String(Math.abs(instance.getMilliseconds())); - var result = ''; + var result = '', + hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; switch (cur) { @@ -481,6 +521,13 @@ result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: + if (hasOverflow) { + if (allowOverflow) { + result = hours + result; + allowOverflow = false; + } + break; + } result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); @@ -511,6 +558,53 @@ return result; }; + + /** + * Tries to extract a pattern from the given expression. + * + * @memberof module:Lexicon + * @method findPattern + * @param {String} expression Expression to be analysed + * @example Kairos.Lexicon.findPattern('01:05:30'); + * @returns {String} Extracted pattern + */ + Kairos.Lexicon.findPattern = function (expression) { + var pattern = '', + currentStep = TOKENS.HOURS; + for (var i = 0, len = expression.length; len > i; i++) { + var cur = expression[i]; + + if (['+', '-'].indexOf(cur) !== -1) { + pattern += TOKENS.SIGN; + continue; + } + + if (!isNaN(cur)) { + pattern += currentStep || cur; + continue; + } + + if (isNaN(cur)) { + pattern += cur; + switch (currentStep) { + case TOKENS.HOURS: + currentStep = TOKENS.MINUTES; + break; + case TOKENS.MINUTES: + currentStep = TOKENS.SECONDS; + break; + case TOKENS.SECONDS: + currentStep = TOKENS.MILLISECONDS; + break; + default: + currentStep = false; + } + continue; + } + } + + return pattern; + }; }()); (function () { @@ -529,7 +623,7 @@ * Kairos time engine. * * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance - * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @pattern {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ @@ -548,6 +642,9 @@ } if (typeof expression === 'string' && expression.length > 0) { + if (Kairos.getAutoParser()) { + pattern = Kairos.Lexicon.findPattern(expression); + } return new Kairos.Lexicon.parse(expression, pattern); } @@ -825,7 +922,7 @@ * Sums the given addend. * * @param {Number|String|Kairos.Engine} addend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -839,7 +936,7 @@ * Subtracts the given subtrahend. * * @param {Number|String|Kairos.Engine} subtrahend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -877,7 +974,7 @@ * Compares with another instance. * * @param {String|Number|Kairos.Engine} another Expression to compare with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').compareTo('00:30'); * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ @@ -899,10 +996,15 @@ * Returns a string representation of the object. * * @param {String} pattern Pattern to format the time expression + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example new Kairos.Engine('22:10').toString('hh:mm'); * @returns {String} String representing the instance time */ - Kairos.Engine.prototype.toString = function (pattern) { - return Kairos.Lexicon.format(this, pattern); + Kairos.Engine.prototype.toString = function (pattern, allowOverflow) { + if (typeof pattern === 'boolean') { + allowOverflow = pattern; + pattern = null; + } + return Kairos.Lexicon.format(this, pattern, allowOverflow); }; }()); \ No newline at end of file diff --git a/build/kairos-min.js b/build/kairos-min.js index 02841fe..03fc03d 100644 --- a/build/kairos-min.js +++ b/build/kairos-min.js @@ -5,6 +5,6 @@ * @link https://github.com/kairos * @license BSD-2-Clause */ -!function(){"use strict";var n={};n._pattern="#hh:mm:ss.SSS",n._validator=new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/);var t,e="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==e&&(t=e.Kairos),n.noConflict=function(){return e.Kairos=t,n},n.setPattern=function(t){n._validator=n.Lexicon.getValidator(t),n._pattern=t},n.getPattern=function(){return n._pattern},n.validate=function(t,e){return n.Lexicon.validate(t,e)},n["new"]=function(t,e){return new n.Engine(t,e)},n.absolute=function(t,e){return n["new"](t,e).toAbsolute()},n.plus=function(t,e,r){return n["new"](t,r).plus(e,r)},n.minus=function(t,e,r){return n["new"](t,r).minus(e,r)},n.multiply=function(t,e,r){return n["new"](t,r).multiply(e)},n.divide=function(t,e,r){return n["new"](t,r).divide(e)},n.getFraction=function(t,e,r,o){if(e>r)throw new Error("Improper fraction");return n["new"](t,o).multiply(e).divide(r)},n.getInterval=function(t,e,r){return n["new"](t,r).minus(e,r).toAbsolute()},n.toMilliseconds=function(t,e){return n["new"](t,e).toMilliseconds()},n.toSeconds=function(t,e){return n["new"](t,e).toSeconds()},n.toMinutes=function(t,e){return n["new"](t,e).toMinutes()},n.toHours=function(t,e){return n["new"](t,e).toHours()},n.compare=function(t,e,r){return n["new"](t,r).compareTo(e,r)},n.min=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n.compare(t,r,e)<0?t:r});return n["new"](r,e)},n.max=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n["new"](t,e).compareTo(r,e)>0?t:r});return n["new"](r,e)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):e.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); -!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var r="",s=0,t=a.length;t>s;s++){var i=a[s];switch(i){case e.SIGN:r+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:r+="\\d";break;default:r+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(r)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,r){if(r||(r=Kairos._pattern),!Kairos.Lexicon.validate(a,r))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=r.length;l>o;o++){var S=r[o];switch(S){case e.SIGN:var d=-1!==["+","-"].indexOf(a[o]);d?s="+"===a[o]:(r=r.slice(0,o)+r.slice(o+1),l--,o--);break;case e.HOURS:t+=a[o];break;case e.MINUTES:i+=a[o];break;case e.SECONDS:n+=a[o];break;case e.MILLISECONDS:c+=a[o]}}var g=Kairos["new"]().addHours(t?+t:0).addMinutes(i?+i:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return s||(g.milliseconds=-g.milliseconds),g},Kairos.Lexicon.format=function(a,r){r||(r=Kairos._pattern);for(var s=a.milliseconds>=0,t=String(Math.abs(a.getHours())),i=String(Math.abs(a.getMinutes())),n=String(Math.abs(a.getSeconds())),c=String(Math.abs(a.getMilliseconds())),o="",l=r.length-1;l>=0;l--){var S=r[l];switch(S){case e.SIGN:o=(s?"+":"-")+o;break;case e.HOURS:o=(t.slice(-1)||"0")+o,t.length>0&&(t=t.slice(0,t.length-1));break;case e.MINUTES:o=(i.slice(-1)||"0")+o,i.length>0&&(i=i.slice(0,i.length-1));break;case e.SECONDS:o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.MILLISECONDS:o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;default:o=S+o}}return o}}(); -!function(){"use strict";var i={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Engine=function(i,t){if(i){if(i instanceof Kairos.Engine)return i;if("number"==typeof i)return this.milliseconds=i,this;if("string"==typeof i&&i.length>0)return new Kairos.Lexicon.parse(i,t);throw new Error("Invalid arguments")}},Kairos.Engine.prototype._resolveStep=function(t,n){switch(t){case 1:this.removeMilliseconds(this.getMilliseconds());break;case i.SECOND:this.removeSeconds(this.getSeconds());break;case i.MINUTE:this.removeMinutes(this.getMinutes());break;case i.HOUR:this.removeHours(this.getHours())}return this.milliseconds+n*t},Kairos.Engine.prototype.milliseconds=0,Kairos.Engine.prototype.setHours=function(t){return this.milliseconds=this._resolveStep(i.HOUR,t),this},Kairos.Engine.prototype.getHours=function(){return Math.trunc(this.milliseconds/i.HOUR)},Kairos.Engine.prototype.setMinutes=function(t){return this.milliseconds=this._resolveStep(i.MINUTE,t),this},Kairos.Engine.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*i.HOUR)/i.MINUTE)},Kairos.Engine.prototype.setSeconds=function(t){return this.milliseconds=this._resolveStep(i.SECOND,t),this},Kairos.Engine.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*i.MINUTE)/i.SECOND)},Kairos.Engine.prototype.setMilliseconds=function(i){return this.milliseconds=this._resolveStep(1,i),this},Kairos.Engine.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*i.SECOND)},Kairos.Engine.prototype.addHours=function(t){return this.milliseconds+=i.HOUR*t,this},Kairos.Engine.prototype.addMinutes=function(t){return this.milliseconds+=i.MINUTE*t,this},Kairos.Engine.prototype.addSeconds=function(t){return this.milliseconds+=i.SECOND*t,this},Kairos.Engine.prototype.addMilliseconds=function(i){return this.milliseconds+=i,this},Kairos.Engine.prototype.removeHours=function(t){return this.milliseconds-=i.HOUR*t,this},Kairos.Engine.prototype.removeMinutes=function(t){return this.milliseconds-=i.MINUTE*t,this},Kairos.Engine.prototype.removeSeconds=function(t){return this.milliseconds-=i.SECOND*t,this},Kairos.Engine.prototype.removeMilliseconds=function(i){return this.milliseconds-=i,this},Kairos.Engine.prototype.toHours=function(){return this.milliseconds/i.HOUR},Kairos.Engine.prototype.toMinutes=function(){return this.milliseconds/i.MINUTE},Kairos.Engine.prototype.toSeconds=function(){return this.milliseconds/i.SECOND},Kairos.Engine.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Engine.prototype.toAbsolute=function(){return this.milliseconds=Math.abs(this.milliseconds),this},Kairos.Engine.prototype.plus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds+=i.toMilliseconds(),this},Kairos.Engine.prototype.minus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds-=i.toMilliseconds(),this},Kairos.Engine.prototype.multiply=function(i){return this.milliseconds*=i,this},Kairos.Engine.prototype.divide=function(i){return this.milliseconds/=i,this},Kairos.Engine.prototype.compareTo=function(i,t){return i=new Kairos.Engine(i,t),this.millisecondsi.toMilliseconds()?1:void 0},Kairos.Engine.prototype.toString=function(i){return Kairos.Lexicon.format(this,i)}}(); \ No newline at end of file +!function(){"use strict";var n={};n._pattern="#hh:mm:ss.SSS",n._validator=new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/),n._autoParser=!1;var t,e="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this;null!==e&&(t=e.Kairos),n.noConflict=function(){return e.Kairos=t,n},n.setPattern=function(t){n._validator=n.Lexicon.getValidator(t),n._pattern=t},n.getPattern=function(){return n._pattern},n.setAutoParser=function(t){n._autoParser=!!t},n.getAutoParser=function(){return n._autoParser},n.validate=function(t,e){return n.Lexicon.validate(t,e)},n["new"]=function(t,e){return new n.Engine(t,e)},n.absolute=function(t,e){return n["new"](t,e).toAbsolute()},n.plus=function(t,e,r){return n["new"](t,r).plus(e,r)},n.minus=function(t,e,r){return n["new"](t,r).minus(e,r)},n.multiply=function(t,e,r){return n["new"](t,r).multiply(e)},n.divide=function(t,e,r){return n["new"](t,r).divide(e)},n.getFraction=function(t,e,r,o){if(e>r)throw new Error("Improper fraction");return n["new"](t,o).multiply(e).divide(r)},n.getInterval=function(t,e,r){return n["new"](t,r).minus(e,r).toAbsolute()},n.toMilliseconds=function(t,e){return n["new"](t,e).toMilliseconds()},n.toSeconds=function(t,e){return n["new"](t,e).toSeconds()},n.toMinutes=function(t,e){return n["new"](t,e).toMinutes()},n.toHours=function(t,e){return n["new"](t,e).toHours()},n.compare=function(t,e,r){return n["new"](t,r).compareTo(e,r)},n.min=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n.compare(t,r,e)<0?t:r});return n["new"](r,e)},n.max=function(t,e){t instanceof Array||(e=null,t=Array.prototype.slice.call(arguments));var r=t.reduce(function(t,r){return n["new"](t,e).compareTo(r,e)>0?t:r});return n["new"](r,e)},"object"==typeof module&&module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):e.Kairos=n,Math.trunc=Math.trunc||function(n){return 0>n?Math.ceil(n):Math.floor(n)}}(); +!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var r="",s=0,t=a.length;t>s;s++){var i=a[s];switch(i){case e.SIGN:r+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:r+="\\d";break;default:r+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(r)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,r){if(r||(r=Kairos._pattern),!Kairos.Lexicon.validate(a,r))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var s=!0,t="",i="",n="",c="",o=0,l=r.length;l>o;o++){var S=r[o];switch(S){case e.SIGN:var d=-1!==["+","-"].indexOf(a[o]);d?s="+"===a[o]:(r=r.slice(0,o)+r.slice(o+1),l--,o--);break;case e.HOURS:t+=a[o];break;case e.MINUTES:i+=a[o];break;case e.SECONDS:n+=a[o];break;case e.MILLISECONDS:c+=a[o]}}var g=Kairos["new"]().addHours(t?+t:0).addMinutes(i?+i:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return s||(g.milliseconds=-g.milliseconds),g},Kairos.Lexicon.format=function(a,r,s){r||(r=Kairos._pattern);for(var t=a.milliseconds>=0,i=String(Math.abs(a.getHours())),n=String(Math.abs(a.getMinutes())),c=String(Math.abs(a.getSeconds())),o=String(Math.abs(a.getMilliseconds())),l="",S=i.length>(r.match(/h/g)||[]).length,d=r.length-1;d>=0;d--){var g=r[d];switch(g){case e.SIGN:l=(t?"+":"-")+l;break;case e.HOURS:if(S){s&&(l=i+l,s=!1);break}l=(i.slice(-1)||"0")+l,i.length>0&&(i=i.slice(0,i.length-1));break;case e.MINUTES:l=(n.slice(-1)||"0")+l,n.length>0&&(n=n.slice(0,n.length-1));break;case e.SECONDS:l=(c.slice(-1)||"0")+l,c.length>0&&(c=c.slice(0,c.length-1));break;case e.MILLISECONDS:l=(o.slice(-1)||"0")+l,o.length>0&&(o=o.slice(0,o.length-1));break;default:l=g+l}}return l},Kairos.Lexicon.findPattern=function(a){for(var r="",s=e.HOURS,t=0,i=a.length;i>t;t++){var n=a[t];if(-1===["+","-"].indexOf(n))if(isNaN(n))if(isNaN(n))switch(r+=n,s){case e.HOURS:s=e.MINUTES;break;case e.MINUTES:s=e.SECONDS;break;case e.SECONDS:s=e.MILLISECONDS;break;default:s=!1}else;else r+=s||n;else r+=e.SIGN}return r}}(); +!function(){"use strict";var i={SECOND:1e3,MINUTE:6e4,HOUR:36e5};Kairos.Engine=function(i,t){if(i){if(i instanceof Kairos.Engine)return i;if("number"==typeof i)return this.milliseconds=i,this;if("string"==typeof i&&i.length>0)return Kairos.getAutoParser()&&(t=Kairos.Lexicon.findPattern(i)),new Kairos.Lexicon.parse(i,t);throw new Error("Invalid arguments")}},Kairos.Engine.prototype._resolveStep=function(t,n){switch(t){case 1:this.removeMilliseconds(this.getMilliseconds());break;case i.SECOND:this.removeSeconds(this.getSeconds());break;case i.MINUTE:this.removeMinutes(this.getMinutes());break;case i.HOUR:this.removeHours(this.getHours())}return this.milliseconds+n*t},Kairos.Engine.prototype.milliseconds=0,Kairos.Engine.prototype.setHours=function(t){return this.milliseconds=this._resolveStep(i.HOUR,t),this},Kairos.Engine.prototype.getHours=function(){return Math.trunc(this.milliseconds/i.HOUR)},Kairos.Engine.prototype.setMinutes=function(t){return this.milliseconds=this._resolveStep(i.MINUTE,t),this},Kairos.Engine.prototype.getMinutes=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toHours())*i.HOUR)/i.MINUTE)},Kairos.Engine.prototype.setSeconds=function(t){return this.milliseconds=this._resolveStep(i.SECOND,t),this},Kairos.Engine.prototype.getSeconds=function(){return Math.trunc(Math.trunc(this.milliseconds-Math.trunc(this.toMinutes())*i.MINUTE)/i.SECOND)},Kairos.Engine.prototype.setMilliseconds=function(i){return this.milliseconds=this._resolveStep(1,i),this},Kairos.Engine.prototype.getMilliseconds=function(){return Math.trunc(this.milliseconds-Math.trunc(this.toSeconds())*i.SECOND)},Kairos.Engine.prototype.addHours=function(t){return this.milliseconds+=i.HOUR*t,this},Kairos.Engine.prototype.addMinutes=function(t){return this.milliseconds+=i.MINUTE*t,this},Kairos.Engine.prototype.addSeconds=function(t){return this.milliseconds+=i.SECOND*t,this},Kairos.Engine.prototype.addMilliseconds=function(i){return this.milliseconds+=i,this},Kairos.Engine.prototype.removeHours=function(t){return this.milliseconds-=i.HOUR*t,this},Kairos.Engine.prototype.removeMinutes=function(t){return this.milliseconds-=i.MINUTE*t,this},Kairos.Engine.prototype.removeSeconds=function(t){return this.milliseconds-=i.SECOND*t,this},Kairos.Engine.prototype.removeMilliseconds=function(i){return this.milliseconds-=i,this},Kairos.Engine.prototype.toHours=function(){return this.milliseconds/i.HOUR},Kairos.Engine.prototype.toMinutes=function(){return this.milliseconds/i.MINUTE},Kairos.Engine.prototype.toSeconds=function(){return this.milliseconds/i.SECOND},Kairos.Engine.prototype.toMilliseconds=function(){return this.milliseconds},Kairos.Engine.prototype.toAbsolute=function(){return this.milliseconds=Math.abs(this.milliseconds),this},Kairos.Engine.prototype.plus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds+=i.toMilliseconds(),this},Kairos.Engine.prototype.minus=function(i,t){return i=new Kairos.Engine(i,t),this.milliseconds-=i.toMilliseconds(),this},Kairos.Engine.prototype.multiply=function(i){return this.milliseconds*=i,this},Kairos.Engine.prototype.divide=function(i){return this.milliseconds/=i,this},Kairos.Engine.prototype.compareTo=function(i,t){return i=new Kairos.Engine(i,t),this.millisecondsi.toMilliseconds()?1:void 0},Kairos.Engine.prototype.toString=function(i,t){return"boolean"==typeof i&&(t=i,i=null),Kairos.Lexicon.format(this,i,t)}}(); \ No newline at end of file diff --git a/build/kairos-node.js b/build/kairos-node.js index 3d49247..3fdc35d 100644 --- a/build/kairos-node.js +++ b/build/kairos-node.js @@ -14,10 +14,10 @@ var Kairos = {}; - // Set default pattern + // Set defaults Kairos._pattern = '#hh:mm:ss.SSS'; - // Set default regex Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); + Kairos._autoParser = false; // global on the server, window in the browser var previous_Kairos; @@ -54,6 +54,8 @@ * s -> seconds * S -> milliseconds * + * @memberof module:Kairos + * @method setPattern * @param {String} pattern The pattern to parse and format time expressions * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ @@ -65,15 +67,42 @@ /** * Gets current Kairos pattern. * + * @memberof module:Kairos + * @method getPattern * @returns {String} Current Kairos pattern */ Kairos.getPattern = function () { return Kairos._pattern; }; + /** + * Sets Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method setAutoParser + * @param {Boolean} yN True to use or false to not use auto parser + * @example Kairos.setAutoParser(true); + */ + Kairos.setAutoParser = function (yN) { + Kairos._autoParser = !!yN; + }; + + /** + * Gets current Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method getAutoParser + * @returns {Boolean} True if auto parse is being used or false if not + */ + Kairos.getAutoParser = function () { + return Kairos._autoParser; + }; + /** * Validates the give expression with the current or given pattern. * + * @memberof module:Kairos + * @method validate * @param {String} expression Time expression to validate * @param {String} pattern Pattern to test the expression * @example Kairos.validate('10:30', 'hh:mm'); @@ -89,7 +118,7 @@ * @memberof module:Kairos * @method new * @param {String|Number|kairos.Engine} time Time expression to create an instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ Kairos.new = function (time, pattern) { @@ -102,7 +131,7 @@ * @memberof module:Kairos * @method absolute * @param {String|Number|kairos.Engine} time Time expression to get its absolute value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ Kairos.absolute = function (time, pattern) { @@ -116,7 +145,7 @@ * @method plus * @param {String|Number|kairos.Engine} augend Augend time expression * @param {String|Number|kairos.Engine} addend Addend time expression - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ Kairos.plus = function (augend, addend, pattern) { @@ -130,7 +159,7 @@ * @method minus * @param {String|Number|kairos.Engine} minuend Minuend time expression * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ Kairos.minus = function (minuend, subtrahend, pattern) { @@ -144,7 +173,7 @@ * @method multiply * @param {String|Number|kairos.Engine} multiplier Multiplier time expression * @param {Number} multiplicand Multiplicand value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ Kairos.multiply = function (multiplier, multiplicand, pattern) { @@ -158,7 +187,7 @@ * @method divide * @param {String|Number|kairos.Engine} dividend Dividend time expression * @param {Number} divisor Divisor value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with division result */ Kairos.divide = function (dividend, divisor, pattern) { @@ -173,7 +202,7 @@ * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction * @param {Number} numerator Numerator value * @param {Number} denominator Denominator value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ Kairos.getFraction = function (time, numerator, denominator, pattern) { @@ -190,7 +219,7 @@ * @method getInterval * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 */ Kairos.getInterval = function (time1, time2, pattern) { @@ -203,7 +232,7 @@ * @memberof module:Kairos * @method toMilliseconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total milliseconds in the time expression */ Kairos.toMilliseconds = function (time, pattern) { @@ -216,7 +245,7 @@ * @memberof module:Kairos * @method toSeconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total seconds in the time expression */ Kairos.toSeconds = function (time, pattern) { @@ -229,7 +258,7 @@ * @memberof module:Kairos * @method toMinutes * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total minutes in the time expression */ Kairos.toMinutes = function (time, pattern) { @@ -242,7 +271,7 @@ * @memberof module:Kairos * @method toHours * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total hours in the time expression */ Kairos.toHours = function (time, pattern) { @@ -257,7 +286,7 @@ * @method compare * @param {String|Number} comparand Time to compare with * @param {String|Number} comparator Time to be compared with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ Kairos.compare = function (comparand, comparator, pattern) { @@ -270,7 +299,7 @@ * @memberof module:Kairos * @method min * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ Kairos.min = function (values, pattern) { @@ -292,7 +321,7 @@ * @memberof module:Kairos * @method max * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {String} Kairos.Engine instance with the greatest value found in the list */ Kairos.max = function (values, pattern) { @@ -311,7 +340,7 @@ // Node.js if (typeof module === 'object' && module.exports) { /** - * @module Kairos.Lexicon + * @module Lexicon */ (function () { @@ -330,7 +359,9 @@ /** * Gets a regex from a pattern. * - * @param {String} [Kairos pattern] pattern Pattern to convert + * @memberof module:Lexicon + * @method getValidator + * @param {String} [pattern] Pattern to convert * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); * @returns {RegExp} */ @@ -366,9 +397,11 @@ /** * Validates if given expression matches the current pattern. * + * @memberof module:Lexicon + * @method validate * @param {String} expression Time expression to be validated - * @param {String} [Kairos pattern] pattern Pattern to validate - * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @param {String} [pattern] Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.SSS'); * @returns {Boolean} True if expression is valid, false if expression is invalid */ Kairos.Lexicon.validate = function (expression, pattern) { @@ -378,8 +411,10 @@ /** * Parses given time expression to a Kairos.Engine instance. * + * @memberof module:Lexicon + * @method parse * @param {String} expression Time expression to be parsed - * @param {String} [Kairos pattern] pattern Pattern to parse + * @param {String} [pattern] Pattern to parse * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine */ @@ -437,12 +472,15 @@ /** * Returns a formated string from an Kairos.Engine instance. * + * @memberof module:Lexicon + * @method format * @param {Kairos.Engine} instance The instance to format - * @param {String} [Kairos pattern] pattern Pattern to format + * @param {String} [pattern] Pattern to format + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); * @returns {String} Formated time expression */ - Kairos.Lexicon.format = function (instance, pattern) { + Kairos.Lexicon.format = function (instance, pattern, allowOverflow) { if (!pattern) { pattern = Kairos._pattern; } @@ -453,7 +491,9 @@ seconds = String(Math.abs(instance.getSeconds())), milliseconds = String(Math.abs(instance.getMilliseconds())); - var result = ''; + var result = '', + hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; switch (cur) { @@ -461,6 +501,13 @@ result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: + if (hasOverflow) { + if (allowOverflow) { + result = hours + result; + allowOverflow = false; + } + break; + } result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); @@ -491,6 +538,53 @@ return result; }; + + /** + * Tries to extract a pattern from the given expression. + * + * @memberof module:Lexicon + * @method findPattern + * @param {String} expression Expression to be analysed + * @example Kairos.Lexicon.findPattern('01:05:30'); + * @returns {String} Extracted pattern + */ + Kairos.Lexicon.findPattern = function (expression) { + var pattern = '', + currentStep = TOKENS.HOURS; + for (var i = 0, len = expression.length; len > i; i++) { + var cur = expression[i]; + + if (['+', '-'].indexOf(cur) !== -1) { + pattern += TOKENS.SIGN; + continue; + } + + if (!isNaN(cur)) { + pattern += currentStep || cur; + continue; + } + + if (isNaN(cur)) { + pattern += cur; + switch (currentStep) { + case TOKENS.HOURS: + currentStep = TOKENS.MINUTES; + break; + case TOKENS.MINUTES: + currentStep = TOKENS.SECONDS; + break; + case TOKENS.SECONDS: + currentStep = TOKENS.MILLISECONDS; + break; + default: + currentStep = false; + } + continue; + } + } + + return pattern; + }; }()); (function () { @@ -509,7 +603,7 @@ * Kairos time engine. * * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance - * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @pattern {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ @@ -528,6 +622,9 @@ } if (typeof expression === 'string' && expression.length > 0) { + if (Kairos.getAutoParser()) { + pattern = Kairos.Lexicon.findPattern(expression); + } return new Kairos.Lexicon.parse(expression, pattern); } @@ -805,7 +902,7 @@ * Sums the given addend. * * @param {Number|String|Kairos.Engine} addend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -819,7 +916,7 @@ * Subtracts the given subtrahend. * * @param {Number|String|Kairos.Engine} subtrahend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -857,7 +954,7 @@ * Compares with another instance. * * @param {String|Number|Kairos.Engine} another Expression to compare with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').compareTo('00:30'); * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ @@ -879,11 +976,16 @@ * Returns a string representation of the object. * * @param {String} pattern Pattern to format the time expression + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example new Kairos.Engine('22:10').toString('hh:mm'); * @returns {String} String representing the instance time */ - Kairos.Engine.prototype.toString = function (pattern) { - return Kairos.Lexicon.format(this, pattern); + Kairos.Engine.prototype.toString = function (pattern, allowOverflow) { + if (typeof pattern === 'boolean') { + allowOverflow = pattern; + pattern = null; + } + return Kairos.Lexicon.format(this, pattern, allowOverflow); }; }()); module.exports = Kairos; diff --git a/build/kairos.js b/build/kairos.js index 00dae38..535393c 100644 --- a/build/kairos.js +++ b/build/kairos.js @@ -14,10 +14,10 @@ var Kairos = {}; - // Set default pattern + // Set defaults Kairos._pattern = '#hh:mm:ss.SSS'; - // Set default regex Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); + Kairos._autoParser = false; // global on the server, window in the browser var previous_Kairos; @@ -54,6 +54,8 @@ * s -> seconds * S -> milliseconds * + * @memberof module:Kairos + * @method setPattern * @param {String} pattern The pattern to parse and format time expressions * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ @@ -65,15 +67,42 @@ /** * Gets current Kairos pattern. * + * @memberof module:Kairos + * @method getPattern * @returns {String} Current Kairos pattern */ Kairos.getPattern = function () { return Kairos._pattern; }; + /** + * Sets Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method setAutoParser + * @param {Boolean} yN True to use or false to not use auto parser + * @example Kairos.setAutoParser(true); + */ + Kairos.setAutoParser = function (yN) { + Kairos._autoParser = !!yN; + }; + + /** + * Gets current Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method getAutoParser + * @returns {Boolean} True if auto parse is being used or false if not + */ + Kairos.getAutoParser = function () { + return Kairos._autoParser; + }; + /** * Validates the give expression with the current or given pattern. * + * @memberof module:Kairos + * @method validate * @param {String} expression Time expression to validate * @param {String} pattern Pattern to test the expression * @example Kairos.validate('10:30', 'hh:mm'); @@ -89,7 +118,7 @@ * @memberof module:Kairos * @method new * @param {String|Number|kairos.Engine} time Time expression to create an instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ Kairos.new = function (time, pattern) { @@ -102,7 +131,7 @@ * @memberof module:Kairos * @method absolute * @param {String|Number|kairos.Engine} time Time expression to get its absolute value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ Kairos.absolute = function (time, pattern) { @@ -116,7 +145,7 @@ * @method plus * @param {String|Number|kairos.Engine} augend Augend time expression * @param {String|Number|kairos.Engine} addend Addend time expression - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ Kairos.plus = function (augend, addend, pattern) { @@ -130,7 +159,7 @@ * @method minus * @param {String|Number|kairos.Engine} minuend Minuend time expression * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ Kairos.minus = function (minuend, subtrahend, pattern) { @@ -144,7 +173,7 @@ * @method multiply * @param {String|Number|kairos.Engine} multiplier Multiplier time expression * @param {Number} multiplicand Multiplicand value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ Kairos.multiply = function (multiplier, multiplicand, pattern) { @@ -158,7 +187,7 @@ * @method divide * @param {String|Number|kairos.Engine} dividend Dividend time expression * @param {Number} divisor Divisor value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with division result */ Kairos.divide = function (dividend, divisor, pattern) { @@ -173,7 +202,7 @@ * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction * @param {Number} numerator Numerator value * @param {Number} denominator Denominator value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ Kairos.getFraction = function (time, numerator, denominator, pattern) { @@ -190,7 +219,7 @@ * @method getInterval * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 */ Kairos.getInterval = function (time1, time2, pattern) { @@ -203,7 +232,7 @@ * @memberof module:Kairos * @method toMilliseconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total milliseconds in the time expression */ Kairos.toMilliseconds = function (time, pattern) { @@ -216,7 +245,7 @@ * @memberof module:Kairos * @method toSeconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total seconds in the time expression */ Kairos.toSeconds = function (time, pattern) { @@ -229,7 +258,7 @@ * @memberof module:Kairos * @method toMinutes * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total minutes in the time expression */ Kairos.toMinutes = function (time, pattern) { @@ -242,7 +271,7 @@ * @memberof module:Kairos * @method toHours * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total hours in the time expression */ Kairos.toHours = function (time, pattern) { @@ -257,7 +286,7 @@ * @method compare * @param {String|Number} comparand Time to compare with * @param {String|Number} comparator Time to be compared with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ Kairos.compare = function (comparand, comparator, pattern) { @@ -270,7 +299,7 @@ * @memberof module:Kairos * @method min * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ Kairos.min = function (values, pattern) { @@ -292,7 +321,7 @@ * @memberof module:Kairos * @method max * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {String} Kairos.Engine instance with the greatest value found in the list */ Kairos.max = function (values, pattern) { @@ -331,7 +360,7 @@ }; }()); /** - * @module Kairos.Lexicon + * @module Lexicon */ (function () { @@ -350,7 +379,9 @@ /** * Gets a regex from a pattern. * - * @param {String} [Kairos pattern] pattern Pattern to convert + * @memberof module:Lexicon + * @method getValidator + * @param {String} [pattern] Pattern to convert * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); * @returns {RegExp} */ @@ -386,9 +417,11 @@ /** * Validates if given expression matches the current pattern. * + * @memberof module:Lexicon + * @method validate * @param {String} expression Time expression to be validated - * @param {String} [Kairos pattern] pattern Pattern to validate - * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @param {String} [pattern] Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.SSS'); * @returns {Boolean} True if expression is valid, false if expression is invalid */ Kairos.Lexicon.validate = function (expression, pattern) { @@ -398,8 +431,10 @@ /** * Parses given time expression to a Kairos.Engine instance. * + * @memberof module:Lexicon + * @method parse * @param {String} expression Time expression to be parsed - * @param {String} [Kairos pattern] pattern Pattern to parse + * @param {String} [pattern] Pattern to parse * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine */ @@ -457,12 +492,15 @@ /** * Returns a formated string from an Kairos.Engine instance. * + * @memberof module:Lexicon + * @method format * @param {Kairos.Engine} instance The instance to format - * @param {String} [Kairos pattern] pattern Pattern to format + * @param {String} [pattern] Pattern to format + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); * @returns {String} Formated time expression */ - Kairos.Lexicon.format = function (instance, pattern) { + Kairos.Lexicon.format = function (instance, pattern, allowOverflow) { if (!pattern) { pattern = Kairos._pattern; } @@ -473,7 +511,9 @@ seconds = String(Math.abs(instance.getSeconds())), milliseconds = String(Math.abs(instance.getMilliseconds())); - var result = ''; + var result = '', + hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; switch (cur) { @@ -481,6 +521,13 @@ result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: + if (hasOverflow) { + if (allowOverflow) { + result = hours + result; + allowOverflow = false; + } + break; + } result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); @@ -511,6 +558,53 @@ return result; }; + + /** + * Tries to extract a pattern from the given expression. + * + * @memberof module:Lexicon + * @method findPattern + * @param {String} expression Expression to be analysed + * @example Kairos.Lexicon.findPattern('01:05:30'); + * @returns {String} Extracted pattern + */ + Kairos.Lexicon.findPattern = function (expression) { + var pattern = '', + currentStep = TOKENS.HOURS; + for (var i = 0, len = expression.length; len > i; i++) { + var cur = expression[i]; + + if (['+', '-'].indexOf(cur) !== -1) { + pattern += TOKENS.SIGN; + continue; + } + + if (!isNaN(cur)) { + pattern += currentStep || cur; + continue; + } + + if (isNaN(cur)) { + pattern += cur; + switch (currentStep) { + case TOKENS.HOURS: + currentStep = TOKENS.MINUTES; + break; + case TOKENS.MINUTES: + currentStep = TOKENS.SECONDS; + break; + case TOKENS.SECONDS: + currentStep = TOKENS.MILLISECONDS; + break; + default: + currentStep = false; + } + continue; + } + } + + return pattern; + }; }()); (function () { @@ -529,7 +623,7 @@ * Kairos time engine. * * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance - * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @pattern {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ @@ -548,6 +642,9 @@ } if (typeof expression === 'string' && expression.length > 0) { + if (Kairos.getAutoParser()) { + pattern = Kairos.Lexicon.findPattern(expression); + } return new Kairos.Lexicon.parse(expression, pattern); } @@ -825,7 +922,7 @@ * Sums the given addend. * * @param {Number|String|Kairos.Engine} addend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -839,7 +936,7 @@ * Subtracts the given subtrahend. * * @param {Number|String|Kairos.Engine} subtrahend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -877,7 +974,7 @@ * Compares with another instance. * * @param {String|Number|Kairos.Engine} another Expression to compare with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').compareTo('00:30'); * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ @@ -899,10 +996,15 @@ * Returns a string representation of the object. * * @param {String} pattern Pattern to format the time expression + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example new Kairos.Engine('22:10').toString('hh:mm'); * @returns {String} String representing the instance time */ - Kairos.Engine.prototype.toString = function (pattern) { - return Kairos.Lexicon.format(this, pattern); + Kairos.Engine.prototype.toString = function (pattern, allowOverflow) { + if (typeof pattern === 'boolean') { + allowOverflow = pattern; + pattern = null; + } + return Kairos.Lexicon.format(this, pattern, allowOverflow); }; }()); \ No newline at end of file diff --git a/examples/basic/index.html b/examples/basic/index.html index fd713a1..c46e03c 100644 --- a/examples/basic/index.html +++ b/examples/basic/index.html @@ -7,23 +7,23 @@ - + + - + =

- + - - + =

- + * = @@ -31,11 +31,11 @@

- + / = - + diff --git a/examples/basic/index.js b/examples/basic/index.js index e63845b..6302e18 100644 --- a/examples/basic/index.js +++ b/examples/basic/index.js @@ -14,6 +14,8 @@ var dividend = document.getElementById('dividend'); var divisor = document.getElementById('divisor'); var divideResult = document.getElementById('divideResult'); +Kairos.setPattern('hh:mm'); + function plus() { plusResult.value = Kairos.plus(augend.value, addend.value); } diff --git a/examples/calc/calc.js b/examples/calc/calc.js index 2086d08..b41858b 100644 --- a/examples/calc/calc.js +++ b/examples/calc/calc.js @@ -4,7 +4,7 @@ _operator, _doNotParse = false, _error; - + var _sendNum = function () { var val = this.textContent; if (!_operator) { @@ -105,8 +105,12 @@ val1.plus(val2); break; } - - _val1 = val1.toExpression(); + + if (val1.toMilliseconds() >= 0) { + _val1 = val1.toString('hh:mm:ss.SSS', true); + } else { + _val1 = val1.toString(true); + } _val2 = ''; _operator = null; } catch (err) { @@ -123,6 +127,8 @@ }; var _init = function () { + Kairos.setAutoParser(true); + var nums = document.getElementsByClassName('num'); for (var i = 0, len = nums.length; i < len; i++) { var num = nums[i]; diff --git a/examples/usecase/index.js b/examples/usecase/index.js index 6e0a928..9d92b6f 100644 --- a/examples/usecase/index.js +++ b/examples/usecase/index.js @@ -36,7 +36,7 @@ row.appendChild(taskCol); var updateInterval = setInterval(function () { - executedForCol.innerHTML = task.getTimeElapsed().toExpression(); + executedForCol.innerHTML = task.getTimeElapsed().toString(); _updateTotal(); }, 1000); row.appendChild(executedForCol); @@ -60,12 +60,13 @@ g.plus(_tasks[i].getTimeElapsed()); } - _totalTime.innerHTML = g.toExpression(); + _totalTime.innerHTML = g.toString(); }; var _init = function () { _initSelectors(); _initEventHandlers(); + Kairos.setPattern('hh:mm:ss'); }; exports.init = _init; diff --git a/examples/usecase/task.js b/examples/usecase/task.js index 751940a..968878c 100644 --- a/examples/usecase/task.js +++ b/examples/usecase/task.js @@ -43,7 +43,7 @@ */ Task.prototype.getTimeElapsed = function () { var diff = ((this.finishedAt || new Date()).getTime() - this.startedAt.getTime()); - var engine = new Kairos.Engine(diff); + var engine = Kairos.new(diff); engine.removeMilliseconds(engine.getMilliseconds()); return engine; }; diff --git a/package.json b/package.json index 26b62c0..932ae32 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ ], "devDependencies": { "assert": "^1.3.0", - "codeclimate-test-reporter": "^0.3.0", + "codeclimate-test-reporter": "^0.3.1", "del": "^2.2.0", - "gulp": "^3.9.0", + "gulp": "^3.9.1", "gulp-autoprefixer": "^3.1.0", "gulp-bower": "0.0.13", "gulp-concat": "^2.6.0", @@ -35,24 +35,24 @@ "gulp-include": "^2.1.0", "gulp-jsdoc": "^0.1.5", "gulp-jshint": "^2.0.0", - "gulp-load-plugins": "^1.1.0", + "gulp-load-plugins": "^1.2.0", "gulp-strip-debug": "^1.1.0", - "gulp-uglify": "^1.5.1", + "gulp-uglify": "^1.5.3", "gulp-webserver": "^0.9.1", "istanbul": "^0.4.2", "jasmine-core": "^2.4.1", "jshint": "^2.9.1", "jshint-stylish": "^2.1.0", - "karma": "^0.13.15", + "karma": "^0.13.22", "karma-chrome-launcher": "^0.2.2", - "karma-coverage": "^0.5.3", + "karma-coverage": "^0.5.5", "karma-firefox-launcher": "^0.1.7", - "karma-jasmine": "^0.3.6", - "karma-mocha": "^0.2.1", + "karma-jasmine": "^0.3.8", + "karma-mocha": "^0.2.2", "karma-phantomjs-launcher": "^1.0.0", "mocha": "^2.4.5", - "phantom": "^2.0.0-alpha.2", - "phantomjs-prebuilt": "^2.1.3", + "phantom": "^2.0.6", + "phantomjs-prebuilt": "^2.1.5", "run-sequence": "^1.1.5" } } diff --git a/src/Engine.js b/src/Engine.js index 301161c..222877d 100644 --- a/src/Engine.js +++ b/src/Engine.js @@ -15,7 +15,7 @@ * Kairos time engine. * * @param {String|Number|Kairos.Engine} expression Literal time expression, milliseconds or a Kairos.Engine instance - * @pattern {String} [Kairos pattern] pattern Overrides Kairos pattern + * @pattern {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('10:30', 'hh:mm'); * @constructor */ @@ -34,6 +34,9 @@ } if (typeof expression === 'string' && expression.length > 0) { + if (Kairos.getAutoParser()) { + pattern = Kairos.Lexicon.findPattern(expression); + } return new Kairos.Lexicon.parse(expression, pattern); } @@ -311,7 +314,7 @@ * Sums the given addend. * * @param {Number|String|Kairos.Engine} addend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -325,7 +328,7 @@ * Subtracts the given subtrahend. * * @param {Number|String|Kairos.Engine} subtrahend - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').minus('00:30'); * @returns {Kairos.Engine} Self */ @@ -363,7 +366,7 @@ * Compares with another instance. * * @param {String|Number|Kairos.Engine} another Expression to compare with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @example new Kairos.Engine('01:00').compareTo('00:30'); * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ @@ -385,10 +388,15 @@ * Returns a string representation of the object. * * @param {String} pattern Pattern to format the time expression + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example new Kairos.Engine('22:10').toString('hh:mm'); * @returns {String} String representing the instance time */ - Kairos.Engine.prototype.toString = function (pattern) { - return Kairos.Lexicon.format(this, pattern); + Kairos.Engine.prototype.toString = function (pattern, allowOverflow) { + if (typeof pattern === 'boolean') { + allowOverflow = pattern; + pattern = null; + } + return Kairos.Lexicon.format(this, pattern, allowOverflow); }; }()); \ No newline at end of file diff --git a/src/Lexicon.js b/src/Lexicon.js index f024481..744552a 100644 --- a/src/Lexicon.js +++ b/src/Lexicon.js @@ -1,5 +1,5 @@ /** - * @module Kairos.Lexicon + * @module Lexicon */ (function () { @@ -18,7 +18,9 @@ /** * Gets a regex from a pattern. * - * @param {String} [Kairos pattern] pattern Pattern to convert + * @memberof module:Lexicon + * @method getValidator + * @param {String} [pattern] Pattern to convert * @example Kairos.Lexicon.getValidator('#hh:mm:ss.SSS'); * @returns {RegExp} */ @@ -54,9 +56,11 @@ /** * Validates if given expression matches the current pattern. * + * @memberof module:Lexicon + * @method validate * @param {String} expression Time expression to be validated - * @param {String} [Kairos pattern] pattern Pattern to validate - * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.fff'); + * @param {String} [pattern] Pattern to validate + * @example Kairos.Lexicon.validate('10:00:00.000', 'hh:mm:ss.SSS'); * @returns {Boolean} True if expression is valid, false if expression is invalid */ Kairos.Lexicon.validate = function (expression, pattern) { @@ -66,8 +70,10 @@ /** * Parses given time expression to a Kairos.Engine instance. * + * @memberof module:Lexicon + * @method parse * @param {String} expression Time expression to be parsed - * @param {String} [Kairos pattern] pattern Pattern to parse + * @param {String} [pattern] Pattern to parse * @example Kairos.Lexicon.parse('01:00:03', 'hh:mm:ss'); * @returns {Kairos.Engine} Given expression parsed to Kairos.Engine */ @@ -125,12 +131,15 @@ /** * Returns a formated string from an Kairos.Engine instance. * + * @memberof module:Lexicon + * @method format * @param {Kairos.Engine} instance The instance to format - * @param {String} [Kairos pattern] pattern Pattern to format + * @param {String} [pattern] Pattern to format + * @param {Boolean} allowOverflow If true, when hour field is bigger than the pattern definition, it will be printed anyway * @example Kairos.Lexicon.format(Kairos.new('10:30'), 'mm:hh'); * @returns {String} Formated time expression */ - Kairos.Lexicon.format = function (instance, pattern) { + Kairos.Lexicon.format = function (instance, pattern, allowOverflow) { if (!pattern) { pattern = Kairos._pattern; } @@ -141,7 +150,9 @@ seconds = String(Math.abs(instance.getSeconds())), milliseconds = String(Math.abs(instance.getMilliseconds())); - var result = ''; + var result = '', + hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; switch (cur) { @@ -149,6 +160,13 @@ result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: + if (hasOverflow) { + if (allowOverflow) { + result = hours + result; + allowOverflow = false; + } + break; + } result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); @@ -179,4 +197,51 @@ return result; }; + + /** + * Tries to extract a pattern from the given expression. + * + * @memberof module:Lexicon + * @method findPattern + * @param {String} expression Expression to be analysed + * @example Kairos.Lexicon.findPattern('01:05:30'); + * @returns {String} Extracted pattern + */ + Kairos.Lexicon.findPattern = function (expression) { + var pattern = '', + currentStep = TOKENS.HOURS; + for (var i = 0, len = expression.length; len > i; i++) { + var cur = expression[i]; + + if (['+', '-'].indexOf(cur) !== -1) { + pattern += TOKENS.SIGN; + continue; + } + + if (!isNaN(cur)) { + pattern += currentStep || cur; + continue; + } + + if (isNaN(cur)) { + pattern += cur; + switch (currentStep) { + case TOKENS.HOURS: + currentStep = TOKENS.MINUTES; + break; + case TOKENS.MINUTES: + currentStep = TOKENS.SECONDS; + break; + case TOKENS.SECONDS: + currentStep = TOKENS.MILLISECONDS; + break; + default: + currentStep = false; + } + continue; + } + } + + return pattern; + }; }()); \ No newline at end of file diff --git a/src/kairos.js b/src/kairos.js index 03da33f..806bf59 100644 --- a/src/kairos.js +++ b/src/kairos.js @@ -7,10 +7,10 @@ var Kairos = {}; - // Set default pattern + // Set defaults Kairos._pattern = '#hh:mm:ss.SSS'; - // Set default regex Kairos._validator = new RegExp(/^[+-]?\d\d:\d\d:\d\d\.\d\d\d/); + Kairos._autoParser = false; // global on the server, window in the browser var previous_Kairos; @@ -47,6 +47,8 @@ * s -> seconds * S -> milliseconds * + * @memberof module:Kairos + * @method setPattern * @param {String} pattern The pattern to parse and format time expressions * @example Kairos.setPattern('#hh:mm:ss.SSS'); */ @@ -58,15 +60,42 @@ /** * Gets current Kairos pattern. * + * @memberof module:Kairos + * @method getPattern * @returns {String} Current Kairos pattern */ Kairos.getPattern = function () { return Kairos._pattern; }; + /** + * Sets Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method setAutoParser + * @param {Boolean} yN True to use or false to not use auto parser + * @example Kairos.setAutoParser(true); + */ + Kairos.setAutoParser = function (yN) { + Kairos._autoParser = !!yN; + }; + + /** + * Gets current Kairos configuration for auto parse feature. + * + * @memberof module:Kairos + * @method getAutoParser + * @returns {Boolean} True if auto parse is being used or false if not + */ + Kairos.getAutoParser = function () { + return Kairos._autoParser; + }; + /** * Validates the give expression with the current or given pattern. * + * @memberof module:Kairos + * @method validate * @param {String} expression Time expression to validate * @param {String} pattern Pattern to test the expression * @example Kairos.validate('10:30', 'hh:mm'); @@ -82,7 +111,7 @@ * @memberof module:Kairos * @method new * @param {String|Number|kairos.Engine} time Time expression to create an instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance from the given time */ Kairos.new = function (time, pattern) { @@ -95,7 +124,7 @@ * @memberof module:Kairos * @method absolute * @param {String|Number|kairos.Engine} time Time expression to get its absolute value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with absolute value */ Kairos.absolute = function (time, pattern) { @@ -109,7 +138,7 @@ * @method plus * @param {String|Number|kairos.Engine} augend Augend time expression * @param {String|Number|kairos.Engine} addend Addend time expression - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the sum result */ Kairos.plus = function (augend, addend, pattern) { @@ -123,7 +152,7 @@ * @method minus * @param {String|Number|kairos.Engine} minuend Minuend time expression * @param {String|Number|kairos.Engine} subtrahend Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with subtract result */ Kairos.minus = function (minuend, subtrahend, pattern) { @@ -137,7 +166,7 @@ * @method multiply * @param {String|Number|kairos.Engine} multiplier Multiplier time expression * @param {Number} multiplicand Multiplicand value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with multiplication result */ Kairos.multiply = function (multiplier, multiplicand, pattern) { @@ -151,7 +180,7 @@ * @method divide * @param {String|Number|kairos.Engine} dividend Dividend time expression * @param {Number} divisor Divisor value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with division result */ Kairos.divide = function (dividend, divisor, pattern) { @@ -166,7 +195,7 @@ * @param {String|Number|Kairos.Engine} time Time expression to extract a fraction * @param {Number} numerator Numerator value * @param {Number} denominator Denominator value - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the fraction extracted */ Kairos.getFraction = function (time, numerator, denominator, pattern) { @@ -183,7 +212,7 @@ * @method getInterval * @param {String|Number|Kairos.Engine} time1 Literal time expression, milliseconds or a Kairos.Engine instance * @param {String|Number|Kairos.Engine} time2 Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the interval between time1 and time2 */ Kairos.getInterval = function (time1, time2, pattern) { @@ -196,7 +225,7 @@ * @memberof module:Kairos * @method toMilliseconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total milliseconds in the time expression */ Kairos.toMilliseconds = function (time, pattern) { @@ -209,7 +238,7 @@ * @memberof module:Kairos * @method toSeconds * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total seconds in the time expression */ Kairos.toSeconds = function (time, pattern) { @@ -222,7 +251,7 @@ * @memberof module:Kairos * @method toMinutes * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total minutes in the time expression */ Kairos.toMinutes = function (time, pattern) { @@ -235,7 +264,7 @@ * @memberof module:Kairos * @method toHours * @param {String|Number} time Literal time expression, milliseconds or a Kairos.Engine instance - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Total hours in the time expression */ Kairos.toHours = function (time, pattern) { @@ -250,7 +279,7 @@ * @method compare * @param {String|Number} comparand Time to compare with * @param {String|Number} comparator Time to be compared with - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Number} Smaller -1 | Equals 0 | Bigger 1 */ Kairos.compare = function (comparand, comparator, pattern) { @@ -263,7 +292,7 @@ * @memberof module:Kairos * @method min * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {Kairos.Engine} Kairos.Engine instance with the lowest value found in the list */ Kairos.min = function (values, pattern) { @@ -285,7 +314,7 @@ * @memberof module:Kairos * @method max * @param {String[]|Number[]|Kairos.Engine[]} values Array with time expressions - * @param {String} [Kairos pattern] pattern Overrides Kairos pattern + * @param {String} [pattern] Overrides Kairos pattern * @returns {String} Kairos.Engine instance with the greatest value found in the list */ Kairos.max = function (values, pattern) { diff --git a/test/browser/engine.js b/test/browser/engine.js index e981419..44c1a41 100644 --- a/test/browser/engine.js +++ b/test/browser/engine.js @@ -287,7 +287,7 @@ describe('Kairos.Engine', function () { assert.equal(t.toString(), '+00:45:15.061'); done(); }); - + it('should compare first time with second time and return -1 for smaller, 0 for equals and 1 for bigger', function (done) { Kairos.setPattern('hh:mm'); engine = new Kairos.Engine('01:00'); @@ -296,7 +296,7 @@ describe('Kairos.Engine', function () { assert.equal(engine.compareTo(new Kairos.Engine('00:30')), 1); done(); }); - + it('should parse correctly expressions whith hours < 10 and > 99', function (done) { Kairos.setPattern('hh:mm'); var a = new Kairos.Engine('60:00'); @@ -306,10 +306,10 @@ describe('Kairos.Engine', function () { a.minus(new Kairos.Engine('139:00', 'hhh:mm')); assert.equal(a.toString(), '01:00'); - + done(); }); - + it('should execute commands in sequence and output the correct result', function (done) { Kairos.setPattern('hh:mm'); var t = new Kairos.Engine('01:00').plus('02:00').minus('01:00').divide(2).multiply(10); @@ -317,4 +317,16 @@ describe('Kairos.Engine', function () { assert.equal(t.toString(), '10:00'); done(); }); + + it('should parse instance to string', function (done) { + var time = Kairos.new('10:00:00.000'); + assert.equal(time.toString(), '+10:00:00.000'); + assert.equal(time.toString('hh:mm'), '10:00'); + + time = Kairos.new('100:00', 'hhh:mm'); + assert.equal(time.toString(true), '+100:00:00.000'); + assert.equal(time.toString('hh:mm', true), '100:00'); + + done(); + }); }); diff --git a/test/browser/kairos.js b/test/browser/kairos.js index f979f1a..7987b9a 100644 --- a/test/browser/kairos.js +++ b/test/browser/kairos.js @@ -39,6 +39,23 @@ describe('Kairos', function () { done(); }); + it('should set auto parser to true or false', function (done) { + Kairos.setAutoParser(true); + assert.equal(Kairos.getAutoParser(), true); + + var time = Kairos.new('10:00'); + assert.equal(time.toString(), '+10:00:00.000'); + + Kairos.setAutoParser(false); + assert.equal(Kairos.getAutoParser(), false); + + assert.throws(function () { + Kairos.new('10:00'); + }, Error); + + done(); + }); + it('should validate the expression with the given pattern or the current Kairos pattern', function (done) { assert.equal(Kairos.validate('22:30', 'hh:mm'), true); assert.equal(Kairos.validate('22:30', 'hh'), true); diff --git a/test/browser/lexicon.js b/test/browser/lexicon.js index 8899ce8..31519bd 100644 --- a/test/browser/lexicon.js +++ b/test/browser/lexicon.js @@ -11,6 +11,19 @@ if (typeof require !== 'undefined') { } describe('Kairos.Lexicon', function () { + + // Setup ===================================================================== + + var loadDefaults = function () { + Kairos._autoParser = false; + }; + + // Tests ===================================================================== + + afterEach(function (done) { + loadDefaults(); + done(); + }); it('should generate a validator from the given pattern', function (done) { var validator = Kairos.Lexicon.getValidator('hh:mm'); @@ -59,6 +72,17 @@ describe('Kairos.Lexicon', function () { time = Kairos.Lexicon.format(Kairos.new('10:00:00.000')); assert.equal(time, '+10:00:00.000'); + Kairos.setAutoParser(true); + time = Kairos.Lexicon.format(Kairos.new('100:00:00.000'), null, true); + assert.equal(time, '+100:00:00.000'); + + done(); + }); + + it('should find the pattern for the given expression', function (done) { + var time = Kairos.Lexicon.findPattern('+10:00:00.000'); + assert.equal(time, '#hh:mm:ss.SSS'); + done(); }); }); \ No newline at end of file