From b0c16ae27b6bb0f21f13db25fb84fd7a5b62cc2f Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Tue, 10 Jul 2018 13:53:41 -0300 Subject: [PATCH] Fixed escaping chars in the time pattern --- bower.json | 2 +- build/kairos-debug.js | 55 +++++++++++++++++------------------------ build/kairos-min.js | 4 +-- build/kairos-node.js | 55 +++++++++++++++++------------------------ build/kairos.js | 55 +++++++++++++++++------------------------ package-lock.json | 2 +- package.json | 2 +- src/Lexicon.js | 51 ++++++++++++++------------------------ test/browser/lexicon.js | 8 +++++- 9 files changed, 96 insertions(+), 138 deletions(-) diff --git a/bower.json b/bower.json index 0fb77b0..4506776 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "kairos", - "version": "2.1.0", + "version": "2.1.1", "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 7858a16..11edb69 100644 --- a/build/kairos-debug.js +++ b/build/kairos-debug.js @@ -1,7 +1,7 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v2.1.0 + * @version v2.1.1 * @link https://github.com/kairos * @license BSD-2-Clause */ @@ -552,13 +552,15 @@ } var sign = instance.milliseconds >= 0, - hours = String(Math.abs(instance.getHours())), - minutes = String(Math.abs(instance.getMinutes())), - seconds = String(Math.abs(instance.getSeconds())), - milliseconds = String(Math.abs(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 = '', - hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + var result = ''; + var escapedHourTokens = (pattern.match(/\\h/g) || []).length; + var hourTokens = ((pattern.match(/h/g) || []).length - escapedHourTokens); + var usedHourTokens = 0; for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; @@ -567,65 +569,52 @@ if (hasLeadingEscape) { result = cur + result; i--; + continue; } switch (cur) { case TOKENS.SIGN: - if (!hasLeadingEscape) result = (sign ? '+' : '-') + result; + result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: - if (hasLeadingEscape && hours.length > 0) { - hours = hours.slice(0, hours.length - 1); - break; - } + usedHourTokens++; + + var isLastHourToken = usedHourTokens === hourTokens; + var isOverflowing = isLastHourToken && hours.length > 1; - if (hasOverflow) { - if (allowOverflow) { - result = hours + result; - allowOverflow = false; - } + if (isOverflowing && allowOverflow) { + result = hours + result; + allowOverflow = false; break; } + result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); } break; case TOKENS.MINUTES: - if (hasLeadingEscape && minutes.length > 0) { - minutes = minutes.slice(0, minutes.length - 1); - break; - } - result = (minutes.slice(-1) || '0') + result; if (minutes.length > 0) { minutes = minutes.slice(0, minutes.length - 1); } break; case TOKENS.SECONDS: - if (hasLeadingEscape && seconds.length > 0) { - seconds = seconds.slice(0, seconds.length - 1); - break; - } - result = (seconds.slice(-1) || '0') + result; if (seconds.length > 0) { seconds = seconds.slice(0, seconds.length - 1); } break; case TOKENS.MILLISECONDS: - if (hasLeadingEscape && milliseconds.length > 0) { - milliseconds = milliseconds.slice(0, milliseconds.length - 1); - break; - } - result = (milliseconds.slice(-1) || '0') + result; if (milliseconds.length > 0) { milliseconds = milliseconds.slice(0, milliseconds.length - 1); } break; default: - if (!hasLeadingEscape) result = cur + result; + if (!hasLeadingEscape) { + result = cur + result; + } } } diff --git a/build/kairos-min.js b/build/kairos-min.js index d49fb47..a4eab50 100644 --- a/build/kairos-min.js +++ b/build/kairos-min.js @@ -1,10 +1,10 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v2.1.0 + * @version v2.1.1 * @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/),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.compare(t,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 n<0?Math.ceil(n):Math.floor(n)}}(); -!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S",ESCAPE:"\\"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var t="",i=0,r=a.length;r>i;i++){var s=a[i];switch(s){case e.SIGN:t+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:t+="\\d";break;default:t+=s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(t)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,t){if(t||(t=Kairos._pattern),!Kairos.Lexicon.validate(a,t))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var i=!0,r="",s="",n="",c="",l=0,o=t.length;o>l;l++){switch(t[l]){case e.SIGN:-1!==["+","-"].indexOf(a[l])?i="+"===a[l]:(t=t.slice(0,l)+t.slice(l+1),o--,l--);break;case e.HOURS:r+=a[l];break;case e.MINUTES:s+=a[l];break;case e.SECONDS:n+=a[l];break;case e.MILLISECONDS:c+=a[l]}}var S=Kairos.new().addHours(r?+r:0).addMinutes(s?+s:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return i||(S.milliseconds=-S.milliseconds),S},Kairos.Lexicon.format=function(a,t,i){t||(t=Kairos._pattern);for(var r=a.milliseconds>=0,s=String(Math.abs(a.getHours())),n=String(Math.abs(a.getMinutes())),c=String(Math.abs(a.getSeconds())),l=String(Math.abs(a.getMilliseconds())),o="",S=s.length>(t.match(/h/g)||[]).length,g=t.length-1;g>=0;g--){var h=t[g],f=t[g-1]===e.ESCAPE;switch(f&&(o=h+o,g--),h){case e.SIGN:f||(o=(r?"+":"-")+o);break;case e.HOURS:if(f&&s.length>0){s=s.slice(0,s.length-1);break}if(S){i&&(o=s+o,i=!1);break}o=(s.slice(-1)||"0")+o,s.length>0&&(s=s.slice(0,s.length-1));break;case e.MINUTES:if(f&&n.length>0){n=n.slice(0,n.length-1);break}o=(n.slice(-1)||"0")+o,n.length>0&&(n=n.slice(0,n.length-1));break;case e.SECONDS:if(f&&c.length>0){c=c.slice(0,c.length-1);break}o=(c.slice(-1)||"0")+o,c.length>0&&(c=c.slice(0,c.length-1));break;case e.MILLISECONDS:if(f&&l.length>0){l=l.slice(0,l.length-1);break}o=(l.slice(-1)||"0")+o,l.length>0&&(l=l.slice(0,l.length-1));break;default:f||(o=h+o)}}return o},Kairos.Lexicon.findPattern=function(a){for(var t="",i=e.HOURS,r=0,s=a.length;s>r;r++){var n=a[r];if(-1===["+","-"].indexOf(n))if(isNaN(n)){if(isNaN(n))switch(t+=n,i){case e.HOURS:i=e.MINUTES;break;case e.MINUTES:i=e.SECONDS;break;case e.SECONDS:i=e.MILLISECONDS;break;default:i=!1}}else t+=i||n;else t+=e.SIGN}return t}}(); +!function(){"use strict";var e={SIGN:"#",HOURS:"h",MINUTES:"m",SECONDS:"s",MILLISECONDS:"S",ESCAPE:"\\"};Kairos.Lexicon={},Kairos.Lexicon.getValidator=function(a){if("string"!=typeof a&&(a=Kairos._pattern),a===Kairos._pattern)return Kairos._validator;for(var t="",r=0,s=a.length;s>r;r++){var i=a[r];switch(i){case e.SIGN:t+="^[+-]?";break;case e.HOURS:case e.MINUTES:case e.SECONDS:case e.MILLISECONDS:t+="\\d";break;default:t+=i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")}}return new RegExp(t)},Kairos.Lexicon.validate=function(e,a){return Kairos.Lexicon.getValidator(a).test(e)},Kairos.Lexicon.parse=function(a,t){if(t||(t=Kairos._pattern),!Kairos.Lexicon.validate(a,t))throw new Error("Cannot parse expression. Time format doesn't match the current time pattern.");for(var r=!0,s="",i="",n="",c="",o=0,S=t.length;S>o;o++){switch(t[o]){case e.SIGN:-1!==["+","-"].indexOf(a[o])?r="+"===a[o]:(t=t.slice(0,o)+t.slice(o+1),S--,o--);break;case e.HOURS:s+=a[o];break;case e.MINUTES:i+=a[o];break;case e.SECONDS:n+=a[o];break;case e.MILLISECONDS:c+=a[o]}}var l=Kairos.new().addHours(s?+s:0).addMinutes(i?+i:0).addSeconds(n?+n:0).addMilliseconds(c?+c:0);return r||(l.milliseconds=-l.milliseconds),l},Kairos.Lexicon.format=function(a,t,r){t||(t=Kairos._pattern);for(var s=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())),S="",l=(t.match(/\\h/g)||[]).length,h=(t.match(/h/g)||[]).length-l,g=0,d=t.length-1;d>=0;d--){var f=t[d],N=t[d-1]===e.ESCAPE;if(N)S=f+S,d--;else switch(f){case e.SIGN:S=(s?"+":"-")+S;break;case e.HOURS:g++;if(g===h&&i.length>1&&r){S=i+S,r=!1;break}S=(i.slice(-1)||"0")+S,i.length>0&&(i=i.slice(0,i.length-1));break;case e.MINUTES:S=(n.slice(-1)||"0")+S,n.length>0&&(n=n.slice(0,n.length-1));break;case e.SECONDS:S=(c.slice(-1)||"0")+S,c.length>0&&(c=c.slice(0,c.length-1));break;case e.MILLISECONDS:S=(o.slice(-1)||"0")+S,o.length>0&&(o=o.slice(0,o.length-1));break;default:N||(S=f+S)}}return S},Kairos.Lexicon.findPattern=function(a){for(var t="",r=e.HOURS,s=0,i=a.length;i>s;s++){var n=a[s];if(-1===["+","-"].indexOf(n))if(isNaN(n)){if(isNaN(n))switch(t+=n,r){case e.HOURS:r=e.MINUTES;break;case e.MINUTES:r=e.SECONDS;break;case e.SECONDS:r=e.MILLISECONDS;break;default:r=!1}}else t+=r||n;else t+=e.SIGN}return t}}(); !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 9d06931..e943a07 100644 --- a/build/kairos-node.js +++ b/build/kairos-node.js @@ -1,7 +1,7 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v2.1.0 + * @version v2.1.1 * @link https://github.com/kairos * @license BSD-2-Clause */ @@ -531,13 +531,15 @@ } var sign = instance.milliseconds >= 0, - hours = String(Math.abs(instance.getHours())), - minutes = String(Math.abs(instance.getMinutes())), - seconds = String(Math.abs(instance.getSeconds())), - milliseconds = String(Math.abs(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 = '', - hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + var result = ''; + var escapedHourTokens = (pattern.match(/\\h/g) || []).length; + var hourTokens = ((pattern.match(/h/g) || []).length - escapedHourTokens); + var usedHourTokens = 0; for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; @@ -546,65 +548,52 @@ if (hasLeadingEscape) { result = cur + result; i--; + continue; } switch (cur) { case TOKENS.SIGN: - if (!hasLeadingEscape) result = (sign ? '+' : '-') + result; + result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: - if (hasLeadingEscape && hours.length > 0) { - hours = hours.slice(0, hours.length - 1); - break; - } + usedHourTokens++; + + var isLastHourToken = usedHourTokens === hourTokens; + var isOverflowing = isLastHourToken && hours.length > 1; - if (hasOverflow) { - if (allowOverflow) { - result = hours + result; - allowOverflow = false; - } + if (isOverflowing && allowOverflow) { + result = hours + result; + allowOverflow = false; break; } + result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); } break; case TOKENS.MINUTES: - if (hasLeadingEscape && minutes.length > 0) { - minutes = minutes.slice(0, minutes.length - 1); - break; - } - result = (minutes.slice(-1) || '0') + result; if (minutes.length > 0) { minutes = minutes.slice(0, minutes.length - 1); } break; case TOKENS.SECONDS: - if (hasLeadingEscape && seconds.length > 0) { - seconds = seconds.slice(0, seconds.length - 1); - break; - } - result = (seconds.slice(-1) || '0') + result; if (seconds.length > 0) { seconds = seconds.slice(0, seconds.length - 1); } break; case TOKENS.MILLISECONDS: - if (hasLeadingEscape && milliseconds.length > 0) { - milliseconds = milliseconds.slice(0, milliseconds.length - 1); - break; - } - result = (milliseconds.slice(-1) || '0') + result; if (milliseconds.length > 0) { milliseconds = milliseconds.slice(0, milliseconds.length - 1); } break; default: - if (!hasLeadingEscape) result = cur + result; + if (!hasLeadingEscape) { + result = cur + result; + } } } diff --git a/build/kairos.js b/build/kairos.js index 7858a16..11edb69 100644 --- a/build/kairos.js +++ b/build/kairos.js @@ -1,7 +1,7 @@ /** * Kairos.js - A non date-based time calculator * @author Rodrigo Gomes da Silva - * @version v2.1.0 + * @version v2.1.1 * @link https://github.com/kairos * @license BSD-2-Clause */ @@ -552,13 +552,15 @@ } var sign = instance.milliseconds >= 0, - hours = String(Math.abs(instance.getHours())), - minutes = String(Math.abs(instance.getMinutes())), - seconds = String(Math.abs(instance.getSeconds())), - milliseconds = String(Math.abs(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 = '', - hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + var result = ''; + var escapedHourTokens = (pattern.match(/\\h/g) || []).length; + var hourTokens = ((pattern.match(/h/g) || []).length - escapedHourTokens); + var usedHourTokens = 0; for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; @@ -567,65 +569,52 @@ if (hasLeadingEscape) { result = cur + result; i--; + continue; } switch (cur) { case TOKENS.SIGN: - if (!hasLeadingEscape) result = (sign ? '+' : '-') + result; + result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: - if (hasLeadingEscape && hours.length > 0) { - hours = hours.slice(0, hours.length - 1); - break; - } + usedHourTokens++; + + var isLastHourToken = usedHourTokens === hourTokens; + var isOverflowing = isLastHourToken && hours.length > 1; - if (hasOverflow) { - if (allowOverflow) { - result = hours + result; - allowOverflow = false; - } + if (isOverflowing && allowOverflow) { + result = hours + result; + allowOverflow = false; break; } + result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); } break; case TOKENS.MINUTES: - if (hasLeadingEscape && minutes.length > 0) { - minutes = minutes.slice(0, minutes.length - 1); - break; - } - result = (minutes.slice(-1) || '0') + result; if (minutes.length > 0) { minutes = minutes.slice(0, minutes.length - 1); } break; case TOKENS.SECONDS: - if (hasLeadingEscape && seconds.length > 0) { - seconds = seconds.slice(0, seconds.length - 1); - break; - } - result = (seconds.slice(-1) || '0') + result; if (seconds.length > 0) { seconds = seconds.slice(0, seconds.length - 1); } break; case TOKENS.MILLISECONDS: - if (hasLeadingEscape && milliseconds.length > 0) { - milliseconds = milliseconds.slice(0, milliseconds.length - 1); - break; - } - result = (milliseconds.slice(-1) || '0') + result; if (milliseconds.length > 0) { milliseconds = milliseconds.slice(0, milliseconds.length - 1); } break; default: - if (!hasLeadingEscape) result = cur + result; + if (!hasLeadingEscape) { + result = cur + result; + } } } diff --git a/package-lock.json b/package-lock.json index 9d62974..e3412cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "kairos", - "version": "2.0.2", + "version": "2.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1bfb1ea..c8030eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kairos", - "version": "2.1.0", + "version": "2.1.1", "description": "A non date-based time calculator", "license": "BSD-2-Clause", "repository": "kairos", diff --git a/src/Lexicon.js b/src/Lexicon.js index 94d591c..ba5264f 100644 --- a/src/Lexicon.js +++ b/src/Lexicon.js @@ -147,13 +147,15 @@ } var sign = instance.milliseconds >= 0, - hours = String(Math.abs(instance.getHours())), - minutes = String(Math.abs(instance.getMinutes())), - seconds = String(Math.abs(instance.getSeconds())), - milliseconds = String(Math.abs(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 = '', - hasOverflow = (hours.length > (pattern.match(/h/g) || []).length); + var result = ''; + var escapedHourTokens = (pattern.match(/\\h/g) || []).length; + var hourTokens = ((pattern.match(/h/g) || []).length - escapedHourTokens); + var usedHourTokens = 0; for (var i = pattern.length - 1; i >= 0; i--) { var cur = pattern[i]; @@ -162,60 +164,43 @@ if (hasLeadingEscape) { result = cur + result; i--; + continue; } switch (cur) { case TOKENS.SIGN: - if (!hasLeadingEscape) { - result = (sign ? '+' : '-') + result; - } + result = (sign ? '+' : '-') + result; break; case TOKENS.HOURS: - if (hasLeadingEscape && hours.length > 0) { - hours = hours.slice(0, hours.length - 1); - break; - } + usedHourTokens++; + + var isLastHourToken = usedHourTokens === hourTokens; + var isOverflowing = isLastHourToken && hours.length > 1; - if (hasOverflow) { - if (allowOverflow) { - result = hours + result; - allowOverflow = false; - } + if (isOverflowing && allowOverflow) { + result = hours + result; + allowOverflow = false; break; } + result = (hours.slice(-1) || '0') + result; if (hours.length > 0) { hours = hours.slice(0, hours.length - 1); } break; case TOKENS.MINUTES: - if (hasLeadingEscape && minutes.length > 0) { - minutes = minutes.slice(0, minutes.length - 1); - break; - } - result = (minutes.slice(-1) || '0') + result; if (minutes.length > 0) { minutes = minutes.slice(0, minutes.length - 1); } break; case TOKENS.SECONDS: - if (hasLeadingEscape && seconds.length > 0) { - seconds = seconds.slice(0, seconds.length - 1); - break; - } - result = (seconds.slice(-1) || '0') + result; if (seconds.length > 0) { seconds = seconds.slice(0, seconds.length - 1); } break; case TOKENS.MILLISECONDS: - if (hasLeadingEscape && milliseconds.length > 0) { - milliseconds = milliseconds.slice(0, milliseconds.length - 1); - break; - } - result = (milliseconds.slice(-1) || '0') + result; if (milliseconds.length > 0) { milliseconds = milliseconds.slice(0, milliseconds.length - 1); diff --git a/test/browser/lexicon.js b/test/browser/lexicon.js index 04caaa5..ae71287 100644 --- a/test/browser/lexicon.js +++ b/test/browser/lexicon.js @@ -77,7 +77,13 @@ describe('Kairos.Lexicon', function () { assert.equal(time, '+100:00:00.000'); var escaping = Kairos.Lexicon.format(Kairos.new('15:01:00.000'), 'h\\h:m\\m'); - assert.equal(escaping, '1h:0m'); + assert.equal(escaping, '5h:1m'); + + var escapingWithOverflow = Kairos.Lexicon.format(Kairos.new('15:01:00.000'), 'h\\h:m\\m', true); + assert.equal(escapingWithOverflow, '15h:1m'); + + var escapingFromMillis = Kairos.Lexicon.format(Kairos.new(5850000), 'hh\\hmm'); + assert.equal(escapingFromMillis, '01h37'); done(); });