date-and-time
Advanced tools
Comparing version 0.12.0 to 0.13.1
@@ -121,6 +121,4 @@ /** | ||
for (var key in props || {}) { | ||
if (props.hasOwnProperty(key)) { | ||
value = props[key]; | ||
newLocale[key] = value.slice ? value.slice() : value; | ||
} | ||
value = props[key]; | ||
newLocale[key] = value.slice ? value.slice() : value; | ||
} | ||
@@ -137,29 +135,9 @@ return newLocale; | ||
/** | ||
* formatting a date | ||
* @param {Date} dateObj - a Date object | ||
* compiling a format string | ||
* @param {string} formatString - a format string | ||
* @param {boolean} [utc] - output as UTC | ||
* @returns {string} a formatted string | ||
*/ | ||
date.format = function (dateObj, formatString, utc) { | ||
var d = date.addMinutes(dateObj, utc ? dateObj.getTimezoneOffset() : 0), | ||
formatter = locales[lang].formatter; | ||
d.utc = utc; | ||
return formatString.replace(/\[[^\[\]]*]|\[.*\][^\[]*\]|([A-Za-z])\1*|./g, function (token) { | ||
return formatter[token] ? formatter.post(formatter[token](d, formatString)) : token.replace(/\[(.*)]/, '$1'); | ||
}); | ||
}; | ||
/** | ||
* compiling a format string for the parser | ||
* @param {string} formatString - a format string | ||
* @returns {Array.<string>} a compiled object | ||
*/ | ||
date.compile = function (formatString) { | ||
var re = /([A-Za-z])\1*|./g, keys, pattern = [formatString]; | ||
var re = /\[([^\[\]]*|\[[^\[\]]*\])*\]|([A-Za-z])\2+|\.{3}|./g, keys, pattern = [formatString]; | ||
formatString = formatString.replace(/\[[^\[\]]*]|\[.*\][^\[]*\]/g, function (str) { | ||
return str.replace(/./g, ' ').slice(2); | ||
}); | ||
while ((keys = re.exec(formatString))) { | ||
@@ -172,2 +150,22 @@ pattern[pattern.length] = keys[0]; | ||
/** | ||
* formatting a date | ||
* @param {Date} dateObj - a Date object | ||
* @param {string|Array.<string>} arg - a format string or a compiled object | ||
* @param {boolean} [utc] - output as UTC | ||
* @returns {string} a formatted string | ||
*/ | ||
date.format = function (dateObj, arg, utc) { | ||
var pattern = typeof arg === 'string' ? date.compile(arg) : arg, | ||
d = date.addMinutes(dateObj, utc ? dateObj.getTimezoneOffset() : 0), | ||
formatter = locales[lang].formatter, str = ''; | ||
d.utc = utc || false; | ||
for (var i = 1, len = pattern.length, token; i < len; i++) { | ||
token = pattern[i]; | ||
str += formatter[token] ? formatter.post(formatter[token](d, pattern[0])) : token.replace(/\[(.*)]/, '$1'); | ||
} | ||
return str; | ||
}; | ||
/** | ||
* pre-parsing a date string | ||
@@ -179,11 +177,11 @@ * @param {string} dateString - a date string | ||
date.preparse = function (dateString, arg) { | ||
var parser = locales[lang].parser, token, result, offset = 0, | ||
pattern = typeof arg === 'string' ? date.compile(arg) : arg, formatString = pattern[0], | ||
dt = { Y: 1970, M: 1, D: 1, H: 0, A: 0, h: 0, m: 0, s: 0, S: 0, Z: 0, _index: 0, _length: 0, _match: 0 }; | ||
var pattern = typeof arg === 'string' ? date.compile(arg) : arg, | ||
dt = { Y: 1970, M: 1, D: 1, H: 0, A: 0, h: 0, m: 0, s: 0, S: 0, Z: 0, _index: 0, _length: 0, _match: 0 }, | ||
parser = locales[lang].parser, offset = 0; | ||
dateString = parser.pre(dateString); | ||
for (var i = 1, len = pattern.length; i < len; i++) { | ||
for (var i = 1, len = pattern.length, token, result; i < len; i++) { | ||
token = pattern[i]; | ||
if (parser[token]) { | ||
result = parser[token](dateString.slice(offset), formatString); | ||
result = parser[token](dateString.slice(offset), pattern[0]); | ||
if (!result.length) { | ||
@@ -197,2 +195,7 @@ break; | ||
offset++; | ||
} else if (/\[.*]/.test(token)) { | ||
offset += token.length - 2; | ||
} else if (token === '...') { | ||
offset = dateString.length; | ||
break; | ||
} else { | ||
@@ -289,3 +292,3 @@ break; | ||
date.addHours = function (dateObj, hours) { | ||
return date.addMilliseconds(dateObj, hours * 3600000); | ||
return date.addMinutes(dateObj, hours * 60); | ||
}; | ||
@@ -300,3 +303,3 @@ | ||
date.addMinutes = function (dateObj, minutes) { | ||
return date.addMilliseconds(dateObj, minutes * 60000); | ||
return date.addSeconds(dateObj, minutes * 60); | ||
}; | ||
@@ -338,12 +341,12 @@ | ||
toSeconds: function () { | ||
return delta / 1000 | 0; | ||
return delta / 1000; | ||
}, | ||
toMinutes: function () { | ||
return delta / 60000 | 0; | ||
return delta / 60000; | ||
}, | ||
toHours: function () { | ||
return delta / 3600000 | 0; | ||
return delta / 3600000; | ||
}, | ||
toDays: function () { | ||
return delta / 86400000 | 0; | ||
return delta / 86400000; | ||
} | ||
@@ -393,3 +396,12 @@ }; | ||
date.extend = function (extension) { | ||
customize(lang, locales[lang], extension); | ||
var extender = extension.extender || {}; | ||
for (var key in extender) { | ||
if (!date[key]) { | ||
date[key] = extender[key]; | ||
} | ||
} | ||
if (extension.formatter || extension.parser || extension.res) { | ||
customize(lang, locales[lang], extension); | ||
} | ||
}; | ||
@@ -396,0 +408,0 @@ |
/* | ||
date-and-time.js (c) KNOWLEDGECODE | MIT | ||
*/ | ||
(function(r){var d={},m={},k={},h="en",t={MMMM:"January February March April May June July August September October November December".split(" "),MMM:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),dddd:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ddd:"Sun Mon Tue Wed Thu Fri Sat".split(" "),dd:"Su Mo Tu We Th Fr Sa".split(" "),A:["AM","PM"]},u={YYYY:function(a){return("000"+a.getFullYear()).slice(-4)},YY:function(a){return("0"+a.getFullYear()).slice(-2)},Y:function(a){return""+ | ||
(function(r){var d={},n={},m={},l="en",t={MMMM:"January February March April May June July August September October November December".split(" "),MMM:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),dddd:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ddd:"Sun Mon Tue Wed Thu Fri Sat".split(" "),dd:"Su Mo Tu We Th Fr Sa".split(" "),A:["AM","PM"]},u={YYYY:function(a){return("000"+a.getFullYear()).slice(-4)},YY:function(a){return("0"+a.getFullYear()).slice(-2)},Y:function(a){return""+ | ||
a.getFullYear()},MMMM:function(a){return this.res.MMMM[a.getMonth()]},MMM:function(a){return this.res.MMM[a.getMonth()]},MM:function(a){return("0"+(a.getMonth()+1)).slice(-2)},M:function(a){return""+(a.getMonth()+1)},DD:function(a){return("0"+a.getDate()).slice(-2)},D:function(a){return""+a.getDate()},HH:function(a){return("0"+a.getHours()).slice(-2)},H:function(a){return""+a.getHours()},A:function(a){return this.res.A[11<a.getHours()|0]},hh:function(a){return("0"+(a.getHours()%12||12)).slice(-2)}, | ||
h:function(a){return""+(a.getHours()%12||12)},mm:function(a){return("0"+a.getMinutes()).slice(-2)},m:function(a){return""+a.getMinutes()},ss:function(a){return("0"+a.getSeconds()).slice(-2)},s:function(a){return""+a.getSeconds()},SSS:function(a){return("00"+a.getMilliseconds()).slice(-3)},SS:function(a){return("0"+(a.getMilliseconds()/10|0)).slice(-2)},S:function(a){return""+(a.getMilliseconds()/100|0)},dddd:function(a){return this.res.dddd[a.getDay()]},ddd:function(a){return this.res.ddd[a.getDay()]}, | ||
dd:function(a){return this.res.dd[a.getDay()]},Z:function(a){return a.utc?"+0000":/[\+-]\d{4}/.exec(a.toTimeString())[0]},post:function(a){return a}},w={YYYY:function(a){return this.exec(/^\d{4}/,a)},Y:function(a){return this.exec(/^\d{1,4}/,a)},MMMM:function(a){a=this.find(this.res.MMMM,a);a.value++;return a},MMM:function(a){a=this.find(this.res.MMM,a);a.value++;return a},MM:function(a){return this.exec(/^\d\d/,a)},M:function(a){return this.exec(/^\d\d?/,a)},DD:function(a){return this.exec(/^\d\d/, | ||
dd:function(a){return this.res.dd[a.getDay()]},Z:function(a){return a.utc?"+0000":/[\+-]\d{4}/.exec(a.toTimeString())[0]},post:function(a){return a}},v={YYYY:function(a){return this.exec(/^\d{4}/,a)},Y:function(a){return this.exec(/^\d{1,4}/,a)},MMMM:function(a){a=this.find(this.res.MMMM,a);a.value++;return a},MMM:function(a){a=this.find(this.res.MMM,a);a.value++;return a},MM:function(a){return this.exec(/^\d\d/,a)},M:function(a){return this.exec(/^\d\d?/,a)},DD:function(a){return this.exec(/^\d\d/, | ||
a)},D:function(a){return this.exec(/^\d\d?/,a)},HH:function(a){return this.exec(/^\d\d/,a)},H:function(a){return this.exec(/^\d\d?/,a)},A:function(a){return this.find(this.res.A,a)},hh:function(a){return this.exec(/^\d\d/,a)},h:function(a){return this.exec(/^\d\d?/,a)},mm:function(a){return this.exec(/^\d\d/,a)},m:function(a){return this.exec(/^\d\d?/,a)},ss:function(a){return this.exec(/^\d\d/,a)},s:function(a){return this.exec(/^\d\d?/,a)},SSS:function(a){return this.exec(/^\d{1,3}/,a)},SS:function(a){a= | ||
this.exec(/^\d\d?/,a);a.value*=10;return a},S:function(a){a=this.exec(/^\d/,a);a.value*=100;return a},Z:function(a){a=this.exec(/^[\+-]\d{2}[0-5]\d/,a);a.value=-60*(a.value/100|0)-a.value%100;return a},h12:function(a,c){return(12===a?0:a)+12*c},exec:function(a,c){var b=(a.exec(c)||[""])[0];return{value:b|0,length:b.length}},find:function(a,c){for(var b=-1,d=0,e=0,v=a.length,f;e<v;e++)f=a[e],!c.indexOf(f)&&f.length>d&&(b=e,d=f.length);return{value:b,length:d}},pre:function(a){return a}},n=function(a, | ||
c,b){var d=function(a,b,c){var d=function(a){a&&(this.res=a)};d.prototype=a;d.prototype.constructor=d;a=new d(c);for(var e in b||{})b.hasOwnProperty(e)&&(c=b[e],a[e]=c.slice?c.slice():c);return a},e={res:d(c.res,b.res)};e.formatter=d(c.formatter,b.formatter,e.res);e.parser=d(c.parser,b.parser,e.res);m[a]=e};d.format=function(a,c,b){var g=d.addMinutes(a,b?a.getTimezoneOffset():0),e=m[h].formatter;g.utc=b;return c.replace(/\[[^\[\]]*]|\[.*\][^\[]*\]|([A-Za-z])\1*|./g,function(a){return e[a]?e.post(e[a](g, | ||
c)):a.replace(/\[(.*)]/,"$1")})};d.compile=function(a){var c=/([A-Za-z])\1*|./g,b,d=[a];for(a=a.replace(/\[[^\[\]]*]|\[.*\][^\[]*\]/g,function(a){return a.replace(/./g," ").slice(2)});b=c.exec(a);)d[d.length]=b[0];return d};d.preparse=function(a,c){var b=m[h].parser,g=0,e="string"===typeof c?d.compile(c):c,k=e[0],f={Y:1970,M:1,D:1,H:0,A:0,h:0,m:0,s:0,S:0,Z:0,_index:0,_length:0,_match:0};a=b.pre(a);for(var p=1,n=e.length;p<n;p++){var l=e[p];if(b[l]){var q=b[l](a.slice(g),k);if(!q.length)break;g+=q.length; | ||
f[l.charAt(0)]=q.value;f._match++}else if(l===a.charAt(g)||" "===l)g++;else break}f.H=f.H||b.h12(f.h,f.A);f._index=g;f._length=a.length;return f};d.isValid=function(a,c){var b="string"===typeof a?d.preparse(a,c):a,g=[31,28+d.isLeapYear(b.Y)|0,31,30,31,30,31,31,30,31,30,31][b.M-1];return!(1>b._index||1>b._length||b._index-b._length||1>b._match||1>b.Y||9999<b.Y||1>b.M||12<b.M||1>b.D||b.D>g||0>b.H||23<b.H||0>b.m||59<b.m||0>b.s||59<b.s||0>b.S||999<b.S||-720>b.Z||840<b.Z)};d.parse=function(a,c,b){a=d.preparse(a, | ||
c);return d.isValid(a)?(a.M-=100>a.Y?22801:1,b||a.Z?new Date(Date.UTC(a.Y,a.M,a.D,a.H,a.m+a.Z,a.s,a.S)):new Date(a.Y,a.M,a.D,a.H,a.m,a.s,a.S)):new Date(NaN)};d.addYears=function(a,c){return d.addMonths(a,12*c)};d.addMonths=function(a,c){var b=new Date(a.getTime());b.setMonth(b.getMonth()+c);return b};d.addDays=function(a,c){var b=new Date(a.getTime());b.setDate(b.getDate()+c);return b};d.addHours=function(a,c){return d.addMilliseconds(a,36E5*c)};d.addMinutes=function(a,c){return d.addMilliseconds(a, | ||
6E4*c)};d.addSeconds=function(a,c){return d.addMilliseconds(a,1E3*c)};d.addMilliseconds=function(a,c){return new Date(a.getTime()+c)};d.subtract=function(a,c){var b=a.getTime()-c.getTime();return{toMilliseconds:function(){return b},toSeconds:function(){return b/1E3|0},toMinutes:function(){return b/6E4|0},toHours:function(){return b/36E5|0},toDays:function(){return b/864E5|0}}};d.isLeapYear=function(a){return!(a%4)&&!!(a%100)||!(a%400)};d.isSameDay=function(a,c){return a.toDateString()===c.toDateString()}; | ||
d.locale=function(a,c){c?n(a,{res:t,formatter:u,parser:w},c):a&&(h=a);return h};d.extend=function(a){n(h,m[h],a)};d.plugin=function(a,c){k[a]=k[a]||c;!c&&k[a]&&d.extend(k[a])};d.locale(h,{});"object"===typeof module&&"object"===typeof module.exports?module.exports=d:"function"===typeof define&&define.amd?define([],function(){return d}):r.date=d})(this); | ||
this.exec(/^\d\d?/,a);a.value*=10;return a},S:function(a){a=this.exec(/^\d/,a);a.value*=100;return a},Z:function(a){a=this.exec(/^[\+-]\d{2}[0-5]\d/,a);a.value=-60*(a.value/100|0)-a.value%100;return a},h12:function(a,c){return(12===a?0:a)+12*c},exec:function(a,c){var b=(a.exec(c)||[""])[0];return{value:b|0,length:b.length}},find:function(a,c){for(var b=-1,d=0,f=0,h=a.length,g;f<h;f++)g=a[f],!c.indexOf(g)&&g.length>d&&(b=f,d=g.length);return{value:b,length:d}},pre:function(a){return a}},q=function(a, | ||
c,b){var d=function(a,b,c){var d=function(a){a&&(this.res=a)};d.prototype=a;d.prototype.constructor=d;a=new d(c);for(var e in b||{})c=b[e],a[e]=c.slice?c.slice():c;return a},f={res:d(c.res,b.res)};f.formatter=d(c.formatter,b.formatter,f.res);f.parser=d(c.parser,b.parser,f.res);n[a]=f};d.compile=function(a){for(var c=/\[([^\[\]]*|\[[^\[\]]*\])*\]|([A-Za-z])\2+|\.{3}|./g,b,d=[a];b=c.exec(a);)d[d.length]=b[0];return d};d.format=function(a,c,b){c="string"===typeof c?d.compile(c):c;a=d.addMinutes(a,b? | ||
a.getTimezoneOffset():0);var e=n[l].formatter,f="";a.utc=b||!1;b=1;for(var h=c.length,g;b<h;b++)g=c[b],f+=e[g]?e.post(e[g](a,c[0])):g.replace(/\[(.*)]/,"$1");return f};d.preparse=function(a,c){var b="string"===typeof c?d.compile(c):c,e={Y:1970,M:1,D:1,H:0,A:0,h:0,m:0,s:0,S:0,Z:0,_index:0,_length:0,_match:0},f=n[l].parser,h=0;a=f.pre(a);for(var g=1,m=b.length,k,p;g<m;g++)if(k=b[g],f[k]){p=f[k](a.slice(h),b[0]);if(!p.length)break;h+=p.length;e[k.charAt(0)]=p.value;e._match++}else if(k===a.charAt(h)|| | ||
" "===k)h++;else if(/\[.*]/.test(k))h+=k.length-2;else{"..."===k&&(h=a.length);break}e.H=e.H||f.h12(e.h,e.A);e._index=h;e._length=a.length;return e};d.isValid=function(a,c){var b="string"===typeof a?d.preparse(a,c):a,e=[31,28+d.isLeapYear(b.Y)|0,31,30,31,30,31,31,30,31,30,31][b.M-1];return!(1>b._index||1>b._length||b._index-b._length||1>b._match||1>b.Y||9999<b.Y||1>b.M||12<b.M||1>b.D||b.D>e||0>b.H||23<b.H||0>b.m||59<b.m||0>b.s||59<b.s||0>b.S||999<b.S||-720>b.Z||840<b.Z)};d.parse=function(a,c,b){a= | ||
d.preparse(a,c);return d.isValid(a)?(a.M-=100>a.Y?22801:1,b||a.Z?new Date(Date.UTC(a.Y,a.M,a.D,a.H,a.m+a.Z,a.s,a.S)):new Date(a.Y,a.M,a.D,a.H,a.m,a.s,a.S)):new Date(NaN)};d.addYears=function(a,c){return d.addMonths(a,12*c)};d.addMonths=function(a,c){var b=new Date(a.getTime());b.setMonth(b.getMonth()+c);return b};d.addDays=function(a,c){var b=new Date(a.getTime());b.setDate(b.getDate()+c);return b};d.addHours=function(a,c){return d.addMinutes(a,60*c)};d.addMinutes=function(a,c){return d.addSeconds(a, | ||
60*c)};d.addSeconds=function(a,c){return d.addMilliseconds(a,1E3*c)};d.addMilliseconds=function(a,c){return new Date(a.getTime()+c)};d.subtract=function(a,c){var b=a.getTime()-c.getTime();return{toMilliseconds:function(){return b},toSeconds:function(){return b/1E3},toMinutes:function(){return b/6E4},toHours:function(){return b/36E5},toDays:function(){return b/864E5}}};d.isLeapYear=function(a){return!(a%4)&&!!(a%100)||!(a%400)};d.isSameDay=function(a,c){return a.toDateString()===c.toDateString()}; | ||
d.locale=function(a,c){c?q(a,{res:t,formatter:u,parser:v},c):a&&(l=a);return l};d.extend=function(a){var c=a.extender||{},b;for(b in c)d[b]||(d[b]=c[b]);(a.formatter||a.parser||a.res)&&q(l,n[l],a)};d.plugin=function(a,c){m[a]=m[a]||c;!c&&m[a]&&d.extend(m[a])};d.locale(l,{});"object"===typeof module&&"object"===typeof module.exports?module.exports=d:"function"===typeof define&&define.amd?define([],function(){return d}):r.date=d})(this); |
{ | ||
"name": "date-and-time", | ||
"version": "0.12.0", | ||
"version": "0.13.1", | ||
"description": "A Minimalist DateTime utility for Node.js and the browser", | ||
@@ -32,3 +32,3 @@ "main": "date-and-time.js", | ||
"expect.js": "^0.3.1", | ||
"mocha": "^6.2.2", | ||
"mocha": "^7.1.0", | ||
"mocha-headless-chrome": "^2.0.3" | ||
@@ -35,0 +35,0 @@ }, |
121
PLUGINS.md
# Plugins | ||
As this library is oriented toward minimalism, it may seem like a lack of functionality. We think plugin is the most realistic solution for solving such dissatisfaction. By importing the plugins, you could extend the functionality of this library, mainly the formatter and the parser. | ||
As this library is oriented toward minimalism, it may seem like a lack of functionality. We think plugin is the most realistic solution for solving such dissatisfaction. By importing the plugins, you can extend the functionality of this library, mainly the formatter and the parser. | ||
## Usage | ||
@@ -45,8 +44,17 @@ | ||
- day-of-week | ||
- It adds day of week notation to the parser. | ||
- meridiem | ||
- It extends `A` token. | ||
- microsecond | ||
- It adds microsecond notation to the parser. | ||
- ordinal | ||
- It adds ordinal notation of date to the formatter. | ||
- timespan | ||
- It adds `timeSpan()` function to the library. | ||
- two-digit-year | ||
@@ -57,5 +65,30 @@ - It adds two-digit year notation to the parser. | ||
### day-of-week | ||
It adds `dddd`, `ddd` and `dd` tokens to the parser. While these meanings are as follows, in fact they don't make sense because day of week doesn't include information to determine a date: | ||
| token | meaning | examples of acceptable form | added or modified | | ||
|:------|:-------------------------|:----------------------------|:------------------| | ||
| dddd | day of week (long) | Friday, Sunday | ✔ | | ||
| ddd | day of week (short) | Fri, Sun | ✔ | | ||
| dd | day of week (very short) | Fr, Su | ✔ | | ||
```javascript | ||
const date = require('date-and-time'); | ||
// Import "day-of-week" plugin. | ||
require('date-and-time/plugin/day-of-week'); | ||
// Apply "day-of-week" plugin to `date-and-time`. | ||
date.plugin('day-of-week'); | ||
// You can write like this. | ||
date.parse('Thursday, March 05, 2020', 'dddd, MMMM, D YYYY'); | ||
// You can also write like this, but it is not versatile because length of day of week are variant. | ||
date.parse('Thursday, March 05, 2020', ' , MMMM, D YYYY'); | ||
date.parse('Friday, March 06, 2020', ' , MMMM, D YYYY'); | ||
``` | ||
### meridiem | ||
It adds `AA`, `a` and `aa` token to the formatter. These meanings are as follows: | ||
It adds `AA`, `a` and `aa` tokens to the formatter. These meanings are as follows: | ||
@@ -98,2 +131,32 @@ | token | meaning | examples of output | added or modified | | ||
### microsecond | ||
It adds `SSSSSS`, `SSSSS` and `SSSS` tokens to the parser. Thease meanings are as follows: | ||
| token | meaning | examples of output | added or modified | | ||
|:-------|:------------------------------|:-------------------|:------------------| | ||
| SSSSSS | microsecond (high accuracy) | 753123, 022113 | ✔ | | ||
| SSSSS | microsecond (middle accuracy) | 75312, 02211 | ✔ | | ||
| SSSS | microsecond (low accuracy) | 7531, 0221 | ✔ | | ||
| SSS | millisecond (high accuracy) | 753, 022 | | | ||
| SS | millisecond (middle accuracy) | 75, 02 | | | ||
| S | millisecond (low accuracy) | 7, 0 | | | ||
```javascript | ||
const date = require('date-and-time'); | ||
// Import "microsecond" plugin. | ||
require('date-and-time/plugin/microsecond'); | ||
// Apply "microsecond" plugin to `date-and-time`. | ||
date.plugin('microsecond'); | ||
// A date object in JavaScript supports `millisecond` (ms): | ||
date.parse('12:34:56.123', 'HH:mm:ss.SSS'); | ||
// 4 or more digits number sometimes seen is not `millisecond`, probably `microsecond` (μs): | ||
date.parse('12:34:56.123456', 'HH:mm:ss.SSSSSS'); | ||
// 123456µs will be rounded to 123ms. | ||
``` | ||
### ordinal | ||
@@ -105,5 +168,5 @@ | ||
|:------|:-------------------------|:--------------------|:------------------| | ||
| DDD | ordinal notation of date | 1st, 2nd, 3rd, 31th | ✔ | | ||
| DD | date with zero-padding | 01, 02, 03, 31 | | | ||
| D | date | 1, 2, 3, 31 | | | ||
| DD | date with zero-padding | 01, 02, 03, 31 | | | ||
| DDD | ordinal notation of date | 1st, 2nd, 3rd, 31th | ✔ | | ||
@@ -126,2 +189,50 @@ ```javascript | ||
### timespan | ||
It adds `timeSpan()` function to the library. This function is similar to the `subtract()`, but this can display a formatted elapsed time between two date objects: | ||
```javascript | ||
const date = require('date-and-time'); | ||
// Import "timespan" plugin. | ||
require('date-and-time/plugin/timespan'); | ||
// Apply "timespan" plugin to `date-and-time`. | ||
date.plugin('timespan'); | ||
const now = new Date(2020, 2, 5, 1, 2, 3, 4); | ||
const new_years_day = new Date(2020, 0, 1); | ||
date.timeSpan(now, new_years_day).toDays('D HH:mm:ss.SSS'); // => '64 01:02:03.004' | ||
date.timeSpan(now, new_years_day).toHours('H [hours] m [minutes] s [seconds]'); // => '1537 hours 2 minutes 3 seconds' | ||
date.timeSpan(now, new_years_day).toMinutes('mmmmmmmmmm [minutes]'); // => '0000092222 minutes' | ||
``` | ||
The `timeSpan()` returns an object that has some functions as with the `subtract()`: | ||
| function | description | | ||
|:---------------|:------------------------| | ||
| toDays | Outputs as dates | | ||
| toHours | Outputs as hours | | ||
| toMinutes | Outputs as minutes | | ||
| toSeconds | Outputs as seconds | | ||
| toMilliseconds | Outputs as milliseconds | | ||
Available tokens in those functions and their meanings are as follows: | ||
| function | available tokens | | ||
|:---------------|:-----------------| | ||
| toDays | D, H, m, s, S | | ||
| toHours | H, m, s, S | | ||
| toMinutes | m, s, S | | ||
| toSeconds | s, S | | ||
| toMilliseconds | S | | ||
| token | meaning | | ||
|:------|:------------| | ||
| D | date | | ||
| H | 24-hour | | ||
| m | minute | | ||
| s | second | | ||
| S | millisecond | | ||
### two-digit-year | ||
@@ -128,0 +239,0 @@ |
210
README.md
@@ -13,6 +13,6 @@ # date-and-time | ||
- Minimalist. Less than 2k. (minified and gzipped) | ||
- Minimalist. Approximately 2k. (minified and gzipped) | ||
- Extensible. Plugin system support. | ||
- Multi language support. | ||
- Universal / Isomorphic. Wherever JS runtime works. | ||
- Universal / Isomorphic. Works wherever. | ||
- Older browser support. Even works on IE6. :) | ||
@@ -36,5 +36,60 @@ | ||
- 0.13.0 | ||
- The `format()` now supports a compiled formatString. | ||
```javascript | ||
const pattern = date.compile('MMM D YYYY'); | ||
date.format(new Date(2020, 2, 3), pattern); // => Mar 3 2020 | ||
date.format(new Date(2020, 3, 4), pattern); // => Apr 4 2020 | ||
date.format(new Date(2020, 4, 5), pattern); // => May 5 2020 | ||
``` | ||
- The `parse()` now supports `...` (ellipsis) token. The `preparse()` and the `isValid()` are too. | ||
```javascript | ||
// Cannot write like this even if you want to get only a date part. | ||
date.parse('Mar 05 2020 10:42:29 GMT-0800', 'MMM D YYYY'); // => Invalid Date | ||
// Previously, it was necessary to adjust the length of the format string by appending white spaces of the same length as a part to ignore. | ||
date.parse('Mar 05 2020 10:42:29 GMT-0800', 'MMM D YYYY '); | ||
// Can write simply like this using the ellipsis token. | ||
date.parse('Mar 05 2020 10:42:29 GMT-0800', 'MMM D YYYY...'); | ||
``` | ||
- Added `day-of-week` plugin for the parser. However this is a dummy, not effective at all. See [PLUGINS.md](./PLUGINS.md) for details. | ||
```javascript | ||
// If a date string has day of week at the head, cannot parse it unless remove that part from it or fill white spaces that part of the format string. | ||
date.parse('Thu Mar 05 2020 10:42:29 GMT-0800', ' MMM D YYYY...'); | ||
// This plugin provides `dd`, `ddd` and `dddd` tokens for such a case. However they are not effective at all because day of week has not information to identify a date. | ||
date.parse('Thu Mar 05 2020 10:42:29 GMT-0800', 'ddd MMM D YYYY...'); | ||
``` | ||
- (**Breaking Change**) The `subtract()` now returns a **REAL** number. Previously, it returned values with truncated decimals. | ||
```javascript | ||
const now = new Date(2020, 2, 5, 1, 2, 3, 4); | ||
const new_years_day = new Date(2020, 0, 1); | ||
date.subtract(now, new_years_day).toDays(); // => 64.04309032407407 | ||
``` | ||
- Added `timespan` plugin. This plugin provides `timeSpan()` function to display a formatted elapsed time. This will might be integrated with the `subtract()`. See [PLUGINS.md](./PLUGINS.md) for details. | ||
```javascript | ||
const now = new Date(2020, 2, 5, 1, 2, 3, 4); | ||
const new_years_day = new Date(2020, 0, 1); | ||
date.timeSpan(now, new_years_day).toDays('D HH:mm:ss.SSS'); // => '64 01:02:03.004' | ||
date.timeSpan(now, new_years_day).toHours('H [hours] m [minutes] s [seconds]'); // => '1537 hours 2 minutes 3 seconds' | ||
``` | ||
- Added `microsecond` plugin for the parser. Microsecond is not supported by date objects so that it is rounded `millisecond` at the inside. See [PLUGINS.md](./PLUGINS.md) for details. | ||
- 0.12.0 | ||
- The parser now supports `Z` token to parse timezone offset. | ||
- (**Breaking Change**) **Excleded `YY` token from the parser**, added it as `two-digit-year` plugin. | ||
- (**Breaking Change**) **Excleded `YY` token from the parser**, added it as `two-digit-year` plugin. See [PLUGINS.md](./PLUGINS.md) for details. | ||
- (**Breaking Change**) Decided to **change the default behavior of `A` token** to fix the non-intuitive definition. Sepcifically, in the `format()` it now outputs `AM` / `PM` instead of `a.m.` / `p.m.`, and in the `parse()` it recognizes `AM` / `PM` only. Other `A` tokens are supported as `meridiem` plugin. | ||
@@ -50,3 +105,3 @@ | ||
- 0.11.0 | ||
- Added compile() function that precompiling a date-time string for the parser. If you need to process many date-time string with one format, you could get results faster than before by precompiling the format string with this function. | ||
- Added `compile()` function that precompiling a date-time string for the parser. If you need to process many date-time string with one format, you can get results faster than before by precompiling the format string with this function. | ||
@@ -75,24 +130,2 @@ ```javascript | ||
- 0.10.0 | ||
- (**Breaking Change**) `YYYY` token now requires 4 digits in the `parse()`, `preparse()` and `isValid()`. | ||
```javascript | ||
date.parse('31-12-0123', 'DD-MM-YYYY'); // Good | ||
date.parse('31-12-123', 'DD-MM-YYYY'); // Not good | ||
``` | ||
- (**Breaking Change**) `YY` token now requires 2 digits in the same functions. | ||
```javascript | ||
date.parse('31-12-03', 'DD-MM-YY'); // Good, but it assumes the year is 2003. | ||
date.parse('31-12-3', 'DD-MM-YY'); // Not good | ||
``` | ||
- Added `Y` token to support year without zero-padding in the same functions. | ||
```javascript | ||
date.parse('31-12-123', 'DD-MM-Y'); // Good, 123 AD. | ||
date.parse('31-12-3', 'DD-MM-Y'); // Good, 3 AD. | ||
``` | ||
## Usage | ||
@@ -124,3 +157,3 @@ | ||
- @param {**Date**} dateObj - a Date object | ||
- @param {**string**} formatString - a format string | ||
- @param {**string|Array.\<string\>**} arg - a format string or a compiled object | ||
- @param {**boolean**} [utc] - output as UTC | ||
@@ -135,2 +168,5 @@ - @returns {**string**} a formatted string | ||
date.format(now, 'hh:mm A [GMT]Z', true); // => '07:14 AM GMT+0000' | ||
const pattern = date.compile('ddd, MMM DD YYYY'); | ||
date.format(now, pattern); // => 'Fri, Jan 02 2015' | ||
``` | ||
@@ -168,3 +204,3 @@ | ||
You could also use the following tokens by importing plugins. See [PLUGINS.md](./PLUGINS.md) for details. | ||
You can also use the following tokens by importing plugins. See [PLUGINS.md](./PLUGINS.md) for details. | ||
@@ -198,6 +234,4 @@ | token | meaning | examples of output | | ||
You could also define your own tokens. See [EXTEND.md](./EXTEND.md) for details. | ||
You can also define your own tokens. See [EXTEND.md](./EXTEND.md) for details. | ||
--- | ||
### parse(dateString, arg[, utc]) | ||
@@ -223,37 +257,43 @@ | ||
| token | meaning | examples of acceptable form | | ||
|:------|:-------------------------------------|:---------------------------------------| | ||
| YYYY | four-digit year | 0999, 2015 | | ||
| Y | four-digit year without zero-padding | 2, 44, 88, 2015 | | ||
| MMMM | month name (long) | January, December | | ||
| MMM | month name (short) | Jan, Dec | | ||
| MM | month with zero-padding | 01, 12 | | ||
| M | month | 1, 12 | | ||
| DD | date with zero-padding | 02, 31 | | ||
| D | date | 2, 31 | | ||
| HH | 24-hour with zero-padding | 23, 08 | | ||
| H | 24-hour | 23, 8 | | ||
| hh | 12-hour with zero-padding | 11, 08 | | ||
| h | 12-hour | 11, 8 | | ||
| A | meridiem (uppercase) | AM, PM | | ||
| mm | minute with zero-padding | 14, 07 | | ||
| m | minute | 14, 7 | | ||
| ss | second with zero-padding | 05, 10 | | ||
| s | second | 5, 10 | | ||
| SSS | millisecond (high accuracy) | 753, 022 | | ||
| SS | millisecond (middle accuracy) | 75, 02 | | ||
| S | millisecond (low accuracy) | 7, 0 | | ||
| Z | timezone offset | +0100, -0800 | | ||
| token | meaning | examples of acceptable form | | ||
|:-------|:-------------------------------------|:---------------------------------------| | ||
| YYYY | four-digit year | 0999, 2015 | | ||
| Y | four-digit year without zero-padding | 2, 44, 88, 2015 | | ||
| MMMM | month name (long) | January, December | | ||
| MMM | month name (short) | Jan, Dec | | ||
| MM | month with zero-padding | 01, 12 | | ||
| M | month | 1, 12 | | ||
| DD | date with zero-padding | 02, 31 | | ||
| D | date | 2, 31 | | ||
| HH | 24-hour with zero-padding | 23, 08 | | ||
| H | 24-hour | 23, 8 | | ||
| hh | 12-hour with zero-padding | 11, 08 | | ||
| h | 12-hour | 11, 8 | | ||
| A | meridiem (uppercase) | AM, PM | | ||
| mm | minute with zero-padding | 14, 07 | | ||
| m | minute | 14, 7 | | ||
| ss | second with zero-padding | 05, 10 | | ||
| s | second | 5, 10 | | ||
| SSS | millisecond (high accuracy) | 753, 022 | | ||
| SS | millisecond (middle accuracy) | 75, 02 | | ||
| S | millisecond (low accuracy) | 7, 0 | | ||
| Z | timezone offset | +0100, -0800 | | ||
You could also use the following tokens by importing plugins. See [PLUGINS.md](./PLUGINS.md) for details. | ||
You can also use the following tokens by importing plugins. See [PLUGINS.md](./PLUGINS.md) for details. | ||
| token | meaning | examples of acceptable form | | ||
|:------|:-------------------------------------|:---------------------------------------| | ||
| YY | two-digit year | 90, 00, 08, 19 | | ||
| Y | two-digit year without zero-padding | 90, 0, 8, 19 | | ||
| A | meridiem | AM, PM, A.M., P.M., am, pm, a.m., p.m. | | ||
| token | meaning | examples of acceptable form | | ||
|:-------|:-------------------------------------|:---------------------------------------| | ||
| YY | two-digit year | 90, 00, 08, 19 | | ||
| Y | two-digit year without zero-padding | 90, 0, 8, 19 | | ||
| A | meridiem | AM, PM, A.M., P.M., am, pm, a.m., p.m. | | ||
| dddd | day of week (long) | Friday, Sunday | | ||
| ddd | day of week (short) | Fri, Sun | | ||
| dd | day of week (very short) | Fr, Su | | ||
| SSSSSS | microsecond (high accuracy) | 123456, 000001 | | ||
| SSSSS | microsecond (middle accuracy) | 12345, 00001 | | ||
| SSSS | microsecond (low accuracy) | 1234, 0001 | | ||
#### NOTE 1. Invalid Date | ||
If the function fails to parse, it will return `Invalid Date`. Notice that the `Invalid Date` is a Date object, not `NaN` or `null`. You could tell whether the Date object is invalid as follows: | ||
If the function fails to parse, it will return `Invalid Date`. Notice that the `Invalid Date` is a Date object, not `NaN` or `null`. You can tell whether the Date object is invalid as follows: | ||
@@ -323,8 +363,14 @@ ```javascript | ||
date.parse('2015/01/02 11:14:05', 'YYYY/MM/DD'); // => Invalid Date | ||
// Append the same length white spaces behind the formatString. | ||
// Adjust the length of the format string by appending white spaces of the same length as a part to ignore to the end of it. | ||
date.parse('2015/01/02 11:14:05', 'YYYY/MM/DD '); // => Jan 2 2015 00:00:00 GMT-0800 | ||
``` | ||
--- | ||
#### NOTE 8. Ellipsis | ||
The parser supports `...` (ellipse) token. The above example can also be written like this: | ||
```javascript | ||
date.parse('2015/01/02 11:14:05', 'YYYY/MM/DD...'); // => Jan 2 2015 00:00:00 GMT-0800 | ||
``` | ||
### compile(formatString) | ||
@@ -342,8 +388,8 @@ | ||
date.parse('Dec 25 2019 3:51:11 AM', pattern); | ||
date.format(new Date(), pattern); // => Mar 16 2020 6:24:56 PM | ||
``` | ||
If you are going to call the `parse()` or the `isValid()` many times with one string format, recommended to precompile and reuse it for performance. | ||
If you are going to call the `format()`, the `parse()` or the `isValid()` many times with one string format, recommended to precompile and reuse it for performance. | ||
--- | ||
### preparse(dateString, arg) | ||
@@ -378,6 +424,4 @@ | ||
This date structure provides a parsing result. You would be able to tell from it how the date string was parsed(, or why the parsing was failed). | ||
This date structure provides a parsing result. You will be able to tell from it how the date string was parsed(, or why the parsing was failed). | ||
--- | ||
### isValid(arg1[, arg2]) | ||
@@ -402,4 +446,2 @@ | ||
--- | ||
### addYears(dateObj, years) | ||
@@ -417,4 +459,2 @@ | ||
--- | ||
### addMonths(dateObj, months) | ||
@@ -432,4 +472,2 @@ | ||
--- | ||
### addDays(dateObj, days) | ||
@@ -447,4 +485,2 @@ | ||
--- | ||
### addHours(dateObj, hours) | ||
@@ -462,4 +498,2 @@ | ||
--- | ||
### addMinutes(dateObj, minutes) | ||
@@ -477,4 +511,2 @@ | ||
--- | ||
### addSeconds(dateObj, seconds) | ||
@@ -492,4 +524,2 @@ | ||
--- | ||
### addMilliseconds(dateObj, milliseconds) | ||
@@ -507,4 +537,2 @@ | ||
--- | ||
### subtract(date1, date2) | ||
@@ -528,4 +556,2 @@ | ||
--- | ||
### isLeapYear(y) | ||
@@ -542,4 +568,2 @@ | ||
--- | ||
### isSameDay(date1, date2) | ||
@@ -560,4 +584,2 @@ | ||
--- | ||
### locale([code[, locale]]) | ||
@@ -584,4 +606,2 @@ | ||
--- | ||
### extend(extension) | ||
@@ -595,4 +615,2 @@ | ||
--- | ||
### plugin(name[, extension]) | ||
@@ -607,4 +625,2 @@ | ||
--- | ||
## Browser Support | ||
@@ -611,0 +627,0 @@ |
129340
46
1939
607