chronos-date 1.0.2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basic-DqKyujoj.mjs +382 -0
- package/dist/basic-DsQqC5nZ.cjs +466 -0
- package/dist/constants.cjs +43 -1
- package/dist/constants.d.cts +17 -1
- package/dist/constants.d.mts +17 -1
- package/dist/constants.mjs +21 -1
- package/dist/convert-DbgntRVW.cjs +49 -0
- package/dist/convert-mMaI4YP0.mjs +38 -0
- package/dist/greet-D07t2_e6.mjs +51 -0
- package/dist/greet-hjVsd2dt.cjs +56 -0
- package/dist/guards.cjs +140 -1
- package/dist/guards.d.cts +18 -2
- package/dist/guards.d.mts +18 -2
- package/dist/guards.mjs +131 -1
- package/dist/helpers-CQzi908i.cjs +278 -0
- package/dist/helpers-DEf4sevD.mjs +201 -0
- package/dist/index.cjs +1477 -1
- package/dist/index.d.cts +18 -2
- package/dist/index.d.mts +18 -2
- package/dist/index.mjs +1474 -1
- package/dist/non-primitives-D9zxCwX8.cjs +68 -0
- package/dist/non-primitives-DBtomDty.mjs +38 -0
- package/dist/plugins/banglaPlugin.cjs +137 -1
- package/dist/plugins/banglaPlugin.d.cts +19 -3
- package/dist/plugins/banglaPlugin.d.mts +19 -3
- package/dist/plugins/banglaPlugin.mjs +136 -1
- package/dist/plugins/businessPlugin.cjs +134 -1
- package/dist/plugins/businessPlugin.d.cts +17 -1
- package/dist/plugins/businessPlugin.d.mts +17 -1
- package/dist/plugins/businessPlugin.mjs +133 -1
- package/dist/plugins/dateRangePlugin.cjs +62 -1
- package/dist/plugins/dateRangePlugin.d.cts +19 -3
- package/dist/plugins/dateRangePlugin.d.mts +19 -3
- package/dist/plugins/dateRangePlugin.mjs +61 -1
- package/dist/plugins/dayPartPlugin.cjs +42 -1
- package/dist/plugins/dayPartPlugin.d.cts +17 -1
- package/dist/plugins/dayPartPlugin.d.mts +17 -1
- package/dist/plugins/dayPartPlugin.mjs +41 -1
- package/dist/plugins/durationPlugin.cjs +107 -1
- package/dist/plugins/durationPlugin.d.cts +17 -1
- package/dist/plugins/durationPlugin.d.mts +17 -1
- package/dist/plugins/durationPlugin.mjs +106 -1
- package/dist/plugins/fromNowPlugin.cjs +96 -1
- package/dist/plugins/fromNowPlugin.d.cts +17 -1
- package/dist/plugins/fromNowPlugin.d.mts +17 -1
- package/dist/plugins/fromNowPlugin.mjs +95 -1
- package/dist/plugins/greetingPlugin.cjs +35 -1
- package/dist/plugins/greetingPlugin.d.cts +17 -1
- package/dist/plugins/greetingPlugin.d.mts +17 -1
- package/dist/plugins/greetingPlugin.mjs +34 -1
- package/dist/plugins/palindromePlugin.cjs +38 -1
- package/dist/plugins/palindromePlugin.d.cts +17 -1
- package/dist/plugins/palindromePlugin.d.mts +17 -1
- package/dist/plugins/palindromePlugin.mjs +37 -1
- package/dist/plugins/relativeTimePlugin.cjs +90 -1
- package/dist/plugins/relativeTimePlugin.d.cts +17 -1
- package/dist/plugins/relativeTimePlugin.d.mts +17 -1
- package/dist/plugins/relativeTimePlugin.mjs +89 -1
- package/dist/plugins/roundPlugin.cjs +85 -1
- package/dist/plugins/roundPlugin.d.cts +17 -1
- package/dist/plugins/roundPlugin.d.mts +17 -1
- package/dist/plugins/roundPlugin.mjs +84 -1
- package/dist/plugins/seasonPlugin.cjs +47 -1
- package/dist/plugins/seasonPlugin.d.cts +17 -1
- package/dist/plugins/seasonPlugin.d.mts +17 -1
- package/dist/plugins/seasonPlugin.mjs +46 -1
- package/dist/plugins/timeZonePlugin.cjs +155 -1
- package/dist/plugins/timeZonePlugin.d.cts +17 -1
- package/dist/plugins/timeZonePlugin.d.mts +17 -1
- package/dist/plugins/timeZonePlugin.mjs +154 -1
- package/dist/plugins/zodiacPlugin.cjs +67 -1
- package/dist/plugins/zodiacPlugin.d.cts +17 -1
- package/dist/plugins/zodiacPlugin.d.mts +17 -1
- package/dist/plugins/zodiacPlugin.mjs +66 -1
- package/dist/primitives-CtuSNmV7.cjs +65 -0
- package/dist/primitives-dXzXlzJw.mjs +35 -0
- package/dist/seasons-B7kK88zq.cjs +434 -0
- package/dist/{seasons-CioTH5Dm.d.mts → seasons-B_kjFWIX.d.mts} +16 -0
- package/dist/{seasons-CsVeJ27s.d.cts → seasons-CpUn45n6.d.cts} +16 -0
- package/dist/seasons-Cq3ah3pV.mjs +368 -0
- package/dist/timezone-BNnHFgki.cjs +5625 -0
- package/dist/timezone-Db2CeL32.mjs +5589 -0
- package/dist/{types-B2fgrJ86.d.mts → types-Cb4gxrgJ.d.mts} +29 -15
- package/dist/{types-DPTQ_yLx.d.cts → types-CdmsXbU_.d.cts} +29 -15
- package/dist/types.cjs +16 -0
- package/dist/types.d.cts +18 -2
- package/dist/types.d.mts +18 -2
- package/dist/types.mjs +17 -1
- package/dist/utilities-BGX8dviZ.mjs +257 -0
- package/dist/utilities-BKtVo78T.mjs +59 -0
- package/dist/utilities-CpF3uys3.cjs +88 -0
- package/dist/utilities-D47SN9EZ.cjs +334 -0
- package/dist/utils.cjs +92 -1
- package/dist/utils.d.cts +20 -4
- package/dist/utils.d.mts +20 -4
- package/dist/utils.mjs +60 -1
- package/package.json +10 -4
- package/dist/basic-CKxaRSHQ.cjs +0 -1
- package/dist/basic-e46DaNAi.mjs +0 -1
- package/dist/convert-Bmp63ats.mjs +0 -1
- package/dist/convert-DrLrcgqz.cjs +0 -1
- package/dist/greet-BBsrvmkn.mjs +0 -1
- package/dist/greet-C-6mruI9.cjs +0 -1
- package/dist/helpers-DGzYnP81.cjs +0 -1
- package/dist/helpers-N1X_Rj_V.mjs +0 -1
- package/dist/non-primitives-B2EE6D6s.mjs +0 -1
- package/dist/non-primitives-Bu3a4WL4.cjs +0 -1
- package/dist/primitives-Cxss_JVF.mjs +0 -1
- package/dist/primitives-Db2FUp4e.cjs +0 -1
- package/dist/seasons-ChAIVphi.mjs +0 -1
- package/dist/seasons-oABOhHcX.cjs +0 -1
- package/dist/timezone-B10UItNO.mjs +0 -1
- package/dist/timezone-CWxbK_7I.cjs +0 -1
- package/dist/utilities-B8dOAQVD.cjs +0 -1
- package/dist/utilities-BJE06bms.mjs +0 -1
- package/dist/utilities-D2-p26DX.cjs +0 -1
- package/dist/utilities-DV_ohS37.mjs +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1 +1,1474 @@
|
|
|
1
|
-
import{c as e,o as t,s as n,u as r}from"./basic-e46DaNAi.mjs";import{i,r as a}from"./primitives-Cxss_JVF.mjs";import{t as o}from"./non-primitives-B2EE6D6s.mjs";import{isLeapYear as s}from"./guards.mjs";import{c,n as l,p as u,r as d,u as f}from"./helpers-N1X_Rj_V.mjs";import{l as p,r as m}from"./utilities-DV_ohS37.mjs";const h=(e,t,n,r,i,o,s)=>a(e)&&a(t)?new v(e,t,n??1,r??0,i??0,o??0,s??0):new v(e);function g(e){return e in v&&e!==`prototype`&&e!==`name`&&e!==`length`&&o(v[e])}const _=new Proxy(h,{get(e,t,n){return t in e?Reflect.get(e,t,n):g(t)?v[t]:Reflect.get(e,t,n)},has(e,t){return t in e||g(t)}});var v=class o{#e;#t;#n;static#r=new Set;static[n]={internalDate(e){return e.#e},offset(e){return e.#t},withOrigin(e,t,n,r,i,a){return e.#o(t,n,r,i,a)},toNewDate(e,t){return e.#a(t)},cast(e){return o.#u(e)}};origin;native;utcOffset;timeZoneName;timeZoneId;$tzTracker;constructor(e,t,n,r,i,o,s){a(e)&&a(t)?(this.#e=new Date(e,t-1,n??1,r??0,i??0,o??0,s??0),this.native=this.#e):(this.#e=this.#a(e),this.native=this.#e),this.#n=`root`,this.origin=this.#n,this.#t=`UTC${this.getUTCOffset()}`,this.utcOffset=this.#t,this.timeZoneName=this.$getNativeTimeZoneName(),this.timeZoneId=this.$getNativeTimeZoneId()}*[Symbol.iterator](){yield[`year`,this.year],yield[`month`,this.month],yield[`isoMonth`,this.isoMonth],yield[`date`,this.date],yield[`weekDay`,this.weekDay],yield[`isoWeekDay`,this.isoWeekDay],yield[`hour`,this.hour],yield[`minute`,this.minute],yield[`second`,this.second],yield[`millisecond`,this.millisecond],yield[`timestamp`,this.getTimeStamp()],yield[`unix`,this.unix]}[Symbol.toPrimitive](e){return e===`number`?this.getTimeStamp():this.toLocalISOString()}[Symbol.replace](e,t){return e.replace(this.#l(),t)}[Symbol.search](e){return e.indexOf(this.#l())}[Symbol.split](e){return e.split(this.#l())}[Symbol.match](e){let[t,n]=this.toLocalISOString().split(`.`)[0].split(`T`),r=t.replace(/-/g,`[-/]?`),i=n?.replace(/:/g,`[:.]?`),a=n?`${r}(?:[T ]?${i})?`:r;return e.match(new RegExp(a))}get[Symbol.toStringTag](){return this.toLocalISOString()}get[Symbol.isConcatSpreadable](){return!0}$getNativeTimeZoneName(e){let t=e||p();return u(t,`long`,this.#e)??t}$getNativeTimeZoneId(){return p()}get#i(){return this.#e.getTime()}#a(e){let t=e instanceof o?e.toDate():l(e);if(isNaN(t.getTime()))throw Error(`Provided date is invalid!`);return t}#o(e,t,n,r,i){let a=new o(this.#e);return a.#n=e,a.origin=e,t&&(a.#t=t,a.utcOffset=t),n&&(a.timeZoneName=n),r&&(a.timeZoneId=r),i&&(a.$tzTracker=i),a.native=a.toDate(),a}#s(e,t){return e.#o(t,this.#t,this.timeZoneName,this.timeZoneId,this.$tzTracker)}#c(e,t=!1){let n=this.#e,r=this.toDate(),i=e=>t?r[`getUTC${e}`]():n[`get${e}`]();return d(e,i(`FullYear`),i(`Month`),i(`Day`),i(`Date`),i(`Hours`),i(`Minutes`),i(`Seconds`),i(`Milliseconds`),t?`Z`:this.getTimeZoneOffset())}#l(e=!0){let t=/\.\d+(Z|[+-]\d{2}:\d{2})?$/;return e?this.toLocalISOString().replace(t,``):this.toISOString().replace(t,``)}get year(){return this.#e.getFullYear()}get month(){return this.#e.getMonth()}get date(){return this.#e.getDate()}get weekDay(){return this.#e.getDay()}get hour(){return this.#e.getHours()}get minute(){return this.#e.getMinutes()}get second(){return this.#e.getSeconds()}get millisecond(){return this.#e.getMilliseconds()}get isoWeekDay(){let e=this.weekDay;return e===0?7:e}get isoMonth(){return this.month+1}get unix(){return Math.floor(this.getTimeStamp()/1e3)}get timestamp(){return this.getTimeStamp()}get lastDateOfMonth(){return this.daysInMonth()}inspect(){return`[Chronos ${this.toLocalISOString()}]`}toJSON(){return this.toLocalISOString()}valueOf(){return this.getTimeStamp()}clone(){return new o(this.#e).#o(this.#n,this.#t,this.timeZoneName,this.timeZoneId,this.$tzTracker)}toDate(){let e=(m(this.#t)-this.getUTCOffsetMinutes())*6e4;return new Date(this.#i-e)}toString(){return this.#c(`dd mmm DD YYYY HH:mm:ss `).concat(this.#t.replace(`UTC`,`GMT`).replace(`:`,``)).concat(` (${this.timeZoneName})`)}toLocalISOString(){return this.#c(`YYYY-MM-DDTHH:mm:ss.mssZZ`)}toISOString(){return this.toDate().toISOString()}toLocaleString(e,t){return this.#e.toLocaleString(e,t)}getTimeStamp(){return this.toDate().getTime()}format(e,t=!1){return this.#c(e||`dd, mmm DD, YYYY HH:mm:ss`,t)}formatStrict(e,t=!1){return this.#c(e||`dd, mmm DD, YYYY HH:mm:ss`,t)}formatUTC(e=`dd, mmm DD, YYYY HH:mm:ss:mss`){return this.#c(e,!0)}addSeconds(e){return this.#s(this.add(e,`second`),`addSeconds`)}addMinutes(e){return this.#s(this.add(e,`minute`),`addMinutes`)}addHours(e){return this.#s(this.add(e,`hour`),`addHours`)}addDays(e){return this.#s(this.add(e,`day`),`addDays`)}addWeeks(e){return this.#s(this.add(e,`week`),`addWeeks`)}addMonths(e){return this.#s(this.add(e,`month`),`addMonths`)}addYears(e){return this.#s(this.add(e,`year`),`addYears`)}isLeapYear(e){return s(e??this.year)}isEqual(e){return this.#i===o.#u(e).#i}isEqualOrBefore(e){return this.#i<=o.#u(e).#i}isEqualOrAfter(e){return this.#i>=o.#u(e).#i}isSame(e,t,n=0){return this.startOf(t,n).#i===o.#u(e).startOf(t,n).#i}isBefore(e,t,n=0){return this.startOf(t,n).#i<o.#u(e).startOf(t,n).#i}isAfter(e,t,n=0){return this.startOf(t,n).#i>o.#u(e).startOf(t,n).#i}isSameOrBefore(e,t,n=0){return this.isSame(e,t,n)||this.isBefore(e,t,n)}isSameOrAfter(e,t,n=0){return this.isSame(e,t,n)||this.isAfter(e,t,n)}isBetween(e,t,n=`()`){let r=o.#u(e).getTimeStamp(),i=o.#u(t).getTimeStamp(),a=this.getTimeStamp();switch(n){case`[]`:return a>=r&&a<=i;case`[)`:return a>=r&&a<i;case`(]`:return a>r&&a<=i;case`()`:return a>r&&a<i;default:return!1}}isDST(){let e=this.year,t=new Date(e,0,1).getTimezoneOffset(),n=new Date(e,6,1).getTimezoneOffset();return this.#e.getTimezoneOffset()<Math.max(t,n)}isFirstDayOfMonth(){return this.isSame(this.firstDayOfMonth(),`day`)}isLastDayOfMonth(){return this.isSame(this.lastDayOfMonth(),`day`)}firstDayOfMonth(){let e=new Date(this.year,this.month,1);return this.#s(new o(e),`firstDayOfMonth`)}lastDayOfMonth(){let e=new Date(this.year,this.month+1,0);return this.#s(new o(e),`lastDayOfMonth`)}startOf(e,t=0){let n=new Date(this.#e);switch(e){case`year`:n.setMonth(0,1),n.setHours(0,0,0,0);break;case`month`:n.setDate(1),n.setHours(0,0,0,0);break;case`week`:{let e=(n.getDay()-t+7)%7;n.setDate(n.getDate()-e),n.setHours(0,0,0,0);break}case`day`:n.setHours(0,0,0,0);break;case`hour`:n.setMinutes(0,0,0);break;case`minute`:n.setSeconds(0,0);break;case`second`:n.setMilliseconds(0);break;case`millisecond`:break}return this.#s(new o(n),`startOf`)}endOf(e,t=0){let n=this.startOf(e,t).add(1,e).add(-1,`millisecond`);return this.#s(n,`endOf`)}add(e,t){let n=new Date(this.#e);switch(t){case`millisecond`:n.setMilliseconds(n.getMilliseconds()+e);break;case`second`:n.setSeconds(n.getSeconds()+e);break;case`minute`:n.setMinutes(n.getMinutes()+e);break;case`hour`:n.setHours(n.getHours()+e);break;case`day`:n.setDate(n.getDate()+e);break;case`week`:n.setDate(n.getDate()+e*7);break;case`month`:n.setMonth(n.getMonth()+e);break;case`year`:n.setFullYear(n.getFullYear()+e);break}return this.#s(new o(n),`add`)}subtract(e,t){return this.#s(this.add(-e,t),`subtract`)}get(e){switch(e){case`year`:return this.year;case`month`:return this.isoMonth;case`day`:return this.date;case`week`:return this.getWeek();case`hour`:return this.hour;case`minute`:return this.minute;case`second`:return this.second;case`millisecond`:return this.millisecond}}set(e,t){let n=new Date(this.#e);switch(e){case`year`:n.setFullYear(t);break;case`month`:n.setMonth(t-1);break;case`day`:n.setDate(t);break;case`week`:return this.setWeek(t);case`hour`:n.setHours(t);break;case`minute`:n.setMinutes(t);break;case`second`:n.setSeconds(t);break;case`millisecond`:n.setMilliseconds(t);break}return this.#s(new o(n),`set`)}diff(e,t){let n=o.#u(e),r=this.#i-n.#i;switch(t){case`millisecond`:return r;case`second`:return r/1e3;case`minute`:return r/6e4;case`hour`:return r/36e5;case`day`:return r/864e5;case`week`:return r/6048e5;case`month`:{let e=this.year-n.year,t=this.month-n.month;return e*12+t+(this.date-n.date)/this.daysInMonth()}case`year`:return this.diff(n,`month`)/12}}calendar(e){let t=e?o.#u(e):new o,n=this.startOf(`day`),r=t.startOf(`day`),i=n.diff(r,`day`),a=this.toDate().toLocaleString(`en`,{hour:`numeric`,minute:`2-digit`});return i===0?`Today at ${a}`:i===1?`Tomorrow at ${a}`:i===-1?`Yesterday at ${a}`:this.toDate().toLocaleString(`en`,{month:`long`,day:`2-digit`,year:`numeric`,weekday:`long`,hour:`numeric`,minute:`2-digit`})}fromNowShort(){let e=new o,t=this.diff(e,`second`),n=Math.abs(t),r=t>=0?`in `:``,i=t<0?` ago`:``;return n<60?`${r}${Math.floor(n)}s${i}`:n<3600?`${r}${Math.floor(n/60)}m${i}`:n<86400?`${r}${Math.floor(n/3600)}h${i}`:n<2592e3?`${r}${Math.floor(n/86400)}d${i}`:n<31536e3?`${r}${Math.floor(n/2592e3)}mo${i}`:`${r}${Math.floor(n/31536e3)}y${i}`}setWeek(e){let t=new Date(this.#e),n=t.getFullYear(),r=new Date(n,0,4),i=r.getDay()||7,a=new Date(r);return a.setDate(r.getDate()-(i-1)),a.setDate(a.getDate()+(e-1)*7),t.setFullYear(a.getFullYear()),t.setMonth(a.getMonth()),t.setDate(a.getDate()),this.#s(new o(t),`setWeek`)}getWeek(){let e=this.startOf(`week`,1).add(3,`day`),t=new o(e.year,1,4).startOf(`week`,1).add(3,`day`);return e.diff(t,`week`)+1}getWeekOfYear(e=0){let t=this.startOf(`year`).startOf(`week`,e);return this.startOf(`week`,e).diff(t,`week`)+1}getWeekYear(e=0){return this.startOf(`week`,e).add(3,`day`).year}getDayOfYear(){return this.startOf(`day`).diff(this.startOf(`year`),`day`)+1}daysInMonth(){return new Date(this.year,this.month+1,0).getDate()}toObject(){return Object.fromEntries([...this])}toArray(){return Object.values(this.toObject())}toQuarter(){let e=this.#e.getMonth();return Math.floor(e/3)+1}getUTCOffset(){let e=-this.#e.getTimezoneOffset(),t=e>=0?`+`:`-`,n=e=>String(Math.floor(Math.abs(e))).padStart(2,`0`);return`${t}${n(e/60)}:${n(e%60)}`}getTimeZoneOffset(){return this.#t.replace(`UTC`,``)}getUTCOffsetMinutes(){return-this.#e.getTimezoneOffset()}getTimeZoneOffsetMinutes(){return m(this.#t)}toUTC(){let e=this.getTimeZoneOffsetMinutes();return new o(new Date(this.#i-e*60*1e3)).#o(`toUTC`,`UTC+00:00`,`Greenwich Mean Time`,`UTC`)}toLocal(){let e=this.getTimeZoneOffsetMinutes()-this.getUTCOffsetMinutes();return new o(new Date(this.#i-e*60*1e3)).#o(`toLocal`)}day(e){return t[e??this.weekDay]}monthName(t){return e[t??this.month]}static parse(e,t){let n={YYYY:`(?<YYYY>\\d{4})`,YY:`(?<YY>\\d{2})`,MM:`(?<MM>\\d{2})`,M:`(?<M>\\d{1,2})`,DD:`(?<DD>\\d{2})`,D:`(?<D>\\d{1,2})`,HH:`(?<HH>\\d{2})`,H:`(?<H>\\d{1,2})`,mm:`(?<mm>\\d{2})`,m:`(?<m>\\d{1,2})`,ss:`(?<ss>\\d{2})`,s:`(?<s>\\d{1,2})`,mss:`(?<mss>\\d{3})`,ms:`(?<ms>\\d{1,3})`},r={YYYY:`year`,YY:`year`,MM:`month`,M:`month`,DD:`date`,D:`date`,HH:`hour`,H:`hour`,mm:`minute`,m:`minute`,ss:`second`,s:`second`,mss:`millisecond`,ms:`millisecond`},i=new RegExp(Object.keys(n).sort((e,t)=>t.length-e.length).join(`|`),`g`),a=t?.trim()?.replace(i,e=>n[e]??e)?.replace(/\s+/g,`\\s*`),s=RegExp(`^${a}\\s*$`).exec(e.trim());if(!s?.groups)throw Error(`Invalid date format!`);let c={};for(let[e,t]of Object.entries(s.groups)){let n=r[e];if(n){let r=Number(t);e===`YY`&&(r+=r<100?2e3:0),c[n]=r}}return new o(c?.year??1970,c?.month??1,c?.date??1,c?.hour??0,c?.minute??0,c?.second??0,c?.millisecond??0).#o(`parse`)}static with(e){let t=new o,{year:n,month:r,date:i,hour:a,minute:s,second:c,millisecond:l}=e??{},u=()=>t.startOf(`month`).set(`year`,n??t.year).set(`month`,r??t.isoMonth).lastDateOfMonth;return new o(n??t.year,r??t.isoMonth,i||(t.isLastDayOfMonth()&&t.date>=u()?u():t.date),a??t.hour,s??t.minute,c??t.second,l??t.millisecond).#o(`with`)}static today(e){let{format:t=`dd, mmm DD, YYYY HH:mm:ss`,useUTC:n=!1}=e||{};return new o().#c(t,n)}static yesterday(){let e=new Date;return new o(e.setDate(e.getDate()-1)).#o(`yesterday`)}static tomorrow(){let e=new Date;return new o(e.setDate(e.getDate()+1)).#o(`tomorrow`)}static now(){return Date.now()}static utc(e){let t=new o(e),n=t.getTimeZoneOffsetMinutes();return new o(new Date(t.#i-n*60*1e3)).#o(`utc`,`UTC+00:00`,`Greenwich Mean Time`,`UTC`)}static formatTimePart(e,t){return new o(`${new o().#c(`YYYY-MM-DD`)}T${f(e)}`).#c(t||`hh:mm:ss a`)}static getDatesForDay(e,n){let i=new o,a=i.addWeeks(4),{format:s=`local`,roundDate:c=!1}=n??{};if(n){if(`from`in n||`to`in n)n?.from&&(i=o.#u(n?.from)),n?.to&&(a=o.#u(n?.to));else if(`span`in n||`unit`in n){let{span:e=4,unit:t=`week`}=n??{};a=i.add(e,t)}}c&&(i=i.startOf(`day`),a=a.startOf(`day`));let l=[],u=(i.isBefore(a,`day`)?1:-1)*r,d=Math.abs(a.diff(i,`day`)),f=i.#i,p=0;for(;new Date(f+p*u).getDay()!==t.indexOf(e);)p++;for(let e=p;e<=d;e+=7){let t=new o(f+e*u).#o(`clone`,i.#t,i.timeZoneName,i.timeZoneId,i.$tzTracker);l.push(s===`local`?t.toLocalISOString():t.toISOString())}return l}static min(...e){let t=o.#u(e[0]);for(let n of e){let e=o.#u(n);e.getTimeStamp()<t.getTimeStamp()&&(t=e)}return t.#s(t,t.#n===`root`?`min`:t.#n)}static max(...e){let t=o.#u(e[0]);for(let n of e){let e=o.#u(n);e.getTimeStamp()>t.getTimeStamp()&&(t=e)}return t.#s(t,t.#n===`root`?`max`:t.#n)}static isLeapYear(e){let t;return t=a(e)?e>0&&e<=9999?e:new Date(e).getFullYear():o.#u(e).year,s(t)}static isValidDate(e){return e instanceof Date}static isDateString(e){return i(e)&&!isNaN(Date.parse(e))}static isValidChronos(e){return e instanceof o}static isReconstructable(e){return c(e)}static reconstruct(e){if(!c(e))throw TypeError(`Invalid input for reconstruction!`);let{native:t,origin:n,utcOffset:r,timeZoneName:i,timeZoneId:a,$tzTracker:s}=e,l=m(r),u=new o(t),d=u.getTimeZoneOffsetMinutes()-l;return(u.utcOffset===r?u:u.add(-d,`minute`)).#o(n,r,i,a,s)}static use(e){o.#r.has(e)||(o.#r.add(e),e(o))}static register(e){o.use(e)}static#u(e){return e instanceof o?e:new o(e)}};export{v as Chronos,n as INTERNALS,_ as chronos};
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 - present Nazmul Hassan
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { c as MONTHS, o as DAYS, s as INTERNALS, u as MS_PER_DAY } from "./basic-DqKyujoj.mjs";
|
|
18
|
+
import { r as isNumber } from "./primitives-dXzXlzJw.mjs";
|
|
19
|
+
import { t as isFunction } from "./non-primitives-DBtomDty.mjs";
|
|
20
|
+
import { isDateString, isLeapYear } from "./guards.mjs";
|
|
21
|
+
import { c as _hasChronosProperties, n as _dateArgsToDate, p as _resolveNativeTzName, r as _formatDate, u as _normalizeOffset } from "./helpers-DEf4sevD.mjs";
|
|
22
|
+
import { l as getNativeTimeZoneId, r as extractMinutesFromUTC } from "./utilities-BGX8dviZ.mjs";
|
|
23
|
+
|
|
24
|
+
//#region src/utils/chronos-fn.ts
|
|
25
|
+
/**
|
|
26
|
+
* * Converts a date into a Chronos object and access to all `Chronos` methods and properties.
|
|
27
|
+
*
|
|
28
|
+
* **Note**: *If a date is provided **without a time component**, the instance will default to `00:00:00.000` UTC
|
|
29
|
+
* and convert it to the **equivalent local time** using the current environment's UTC offset.*
|
|
30
|
+
*
|
|
31
|
+
* @description
|
|
32
|
+
* This function serves as a wrapper around the `Chronos` class constructor and allows you to create a new `Chronos` instance from various types of date representations.
|
|
33
|
+
* The following types of input are supported:
|
|
34
|
+
*
|
|
35
|
+
* - **`string`**: A string representing a date, which can be parsed by the JavaScript `Date` constructor.
|
|
36
|
+
* Example: `"2023-12-31"`.
|
|
37
|
+
* - **`number`**: A timestamp representing the number of milliseconds since the Unix epoch.
|
|
38
|
+
* Example: `1672531199000`.
|
|
39
|
+
* - **`Date`**: A JavaScript `Date` object.
|
|
40
|
+
* - **`Chronos`**: A `Chronos` instance created by the same constructor.
|
|
41
|
+
* - **`year, month, date, hours, minutes, seconds, milliseconds`**: Individual components of a date-time to construct a `Chronos` instance.
|
|
42
|
+
* - **`year`**: A number representing the year. If the year is between 0 and 99, it will be assumed to be the year 1900 + the provided year.
|
|
43
|
+
* - **`month`**: A number between 1 and 12 representing the month (1 for January, 12 for December). It is adjusted internally to a 0-based index (0 for January, 11 for December).
|
|
44
|
+
* - **`date`**: A number between 1 and 31 representing the day of the month.
|
|
45
|
+
* - **`hours`**: A number between 0 and 23 representing the hour of the day.
|
|
46
|
+
* - **`minutes`**: A number between 0 and 59 representing the minutes past the hour.
|
|
47
|
+
* - **`seconds`**: A number between 0 and 59 representing the seconds past the minute.
|
|
48
|
+
* - **`milliseconds`**: A number between 0 and 999 representing the milliseconds past the second.
|
|
49
|
+
*
|
|
50
|
+
* This function also allows you to access static methods from the `Chronos` class, as it copies all static methods from `Chronos` to the `chronos` function itself.
|
|
51
|
+
* Therefore, static methods can be called either through the `Chronos` class directly or through the `chronos` function.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const chronosInstanceFn = chronos("2023-12-31");
|
|
55
|
+
* const chronosInstanceClass = new Chronos("2023-12-31");
|
|
56
|
+
* const sameInstanceFn = chronos.parse("2023-12-31", "YYYY-MM-DD");
|
|
57
|
+
* const sameInstanceClass = Chronos.parse("2023-12-31", "YYYY-MM-DD");
|
|
58
|
+
*
|
|
59
|
+
* @param valueOrYear The value in number, string, Date or Chronos format or the full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.
|
|
60
|
+
* @param month The month as a number between 1 and 12 (January to December).
|
|
61
|
+
* @param date The date as a number between 1 and 31.
|
|
62
|
+
* @param hours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.
|
|
63
|
+
* @param minutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.
|
|
64
|
+
* @param seconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.
|
|
65
|
+
* @param ms A number from 0 to 999 that specifies the milliseconds.
|
|
66
|
+
*
|
|
67
|
+
* @returns new `Chronos` instance representing the provided date with all `Chronos` methods and properties.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* - Static methods can be accessed from both the `Chronos` class and the `chronos` function.
|
|
71
|
+
* - Static methods from the `Chronos` class are copied over to the `chronos` wrapper function, so you can call them like:
|
|
72
|
+
* ```ts
|
|
73
|
+
* chronos.parse("2023-12-31", "YYYY-MM-DD");
|
|
74
|
+
* // Or
|
|
75
|
+
* Chronos.parse("2023-12-31", "YYYY-MM-DD");
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
const $chronos = (valueOrYear, month, date, hours, minutes, seconds, ms) => {
|
|
79
|
+
if (isNumber(valueOrYear) && isNumber(month)) return new Chronos(valueOrYear, month, date ?? 1, hours ?? 0, minutes ?? 0, seconds ?? 0, ms ?? 0);
|
|
80
|
+
else return new Chronos(valueOrYear);
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* @internal Type guard to check if a property is a static method of the `Chronos` class.
|
|
84
|
+
*
|
|
85
|
+
* @param prop - The property name to check.
|
|
86
|
+
* @returns `true` if the property is a static method of `Chronos`, `false` otherwise.
|
|
87
|
+
*/
|
|
88
|
+
function _isChronosStaticKey(prop) {
|
|
89
|
+
return prop in Chronos && prop !== "prototype" && prop !== "name" && prop !== "length" && isFunction(Chronos[prop]);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* * Use `chronos` with all static methods from the `Chronos` class.
|
|
93
|
+
*
|
|
94
|
+
* @description
|
|
95
|
+
* It serves as both a constructor for creating `Chronos` instances and a namespace for accessing all static methods from the `Chronos` class.
|
|
96
|
+
*
|
|
97
|
+
* **Note**: *If a date is provided **without a time component**, the instance will default to `00:00:00.000` UTC and convert it to the **equivalent local time** using the current environment's UTC offset.*
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* // Example usage as constructor:
|
|
101
|
+
* const instance = chronos("2023-12-31");
|
|
102
|
+
* const instanceWithTime = chronos(2023, 12, 31, 15, 30, 0);
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* // Example usage of static methods:
|
|
106
|
+
* // Both work identically - thanks to automatic Proxy delegation
|
|
107
|
+
* chronos.parse("2023-12-31", "YYYY-MM-DD");
|
|
108
|
+
* Chronos.parse("2023-12-31", "YYYY-MM-DD");
|
|
109
|
+
*
|
|
110
|
+
* chronos.today();
|
|
111
|
+
* chronos.isLeapYear(2024);
|
|
112
|
+
* chronos.min(date1, date2, date3);
|
|
113
|
+
*
|
|
114
|
+
* @remarks *No need to call `chronos` for accessing the static methods. Simply call the static methods.*
|
|
115
|
+
*
|
|
116
|
+
* **Available Static Methods:**
|
|
117
|
+
*
|
|
118
|
+
* ```ts
|
|
119
|
+
* chronos.now(): number;
|
|
120
|
+
* chronos.tomorrow(): Chronos;
|
|
121
|
+
* chronos.yesterday(): Chronos;
|
|
122
|
+
* chronos.today(options?: FormatOptions): string;
|
|
123
|
+
* chronos.with(options: ChronosWithOptions): Chronos;
|
|
124
|
+
* chronos.parse(dateStr: string, format: string): Chronos;
|
|
125
|
+
* chronos.utc(dateLike: ChronosInput): Chronos;
|
|
126
|
+
* chronos.min(...dates: ChronosInput[]): Chronos;
|
|
127
|
+
* chronos.max(...dates: ChronosInput[]): Chronos;
|
|
128
|
+
* chronos.isLeapYear(date: ChronosInput): boolean;
|
|
129
|
+
* chronos.isValidDate(value: unknown): boolean;
|
|
130
|
+
* chronos.isDateString(value: unknown): boolean;
|
|
131
|
+
* chronos.isValidChronos(value: unknown): boolean;
|
|
132
|
+
* chronos.isReconstructable(value: unknown): value is ChronosProperties;
|
|
133
|
+
* chronos.reconstruct(value: ChronosProperties): Chronos;
|
|
134
|
+
* chronos.formatTimePart(time: string, format?: TimeParts): string;
|
|
135
|
+
* chronos.getDatesForDay(day: WeekDay, options?: WeekdayOptions): string[];
|
|
136
|
+
* chronos.use(plugin: ChronosPlugin): void;
|
|
137
|
+
* chronos.register(plugin: ChronosPlugin): void;
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
const chronos = new Proxy($chronos, {
|
|
141
|
+
get(target, prop, receiver) {
|
|
142
|
+
if (prop in target) return Reflect.get(target, prop, receiver);
|
|
143
|
+
if (_isChronosStaticKey(prop)) return Chronos[prop];
|
|
144
|
+
return Reflect.get(target, prop, receiver);
|
|
145
|
+
},
|
|
146
|
+
has(target, prop) {
|
|
147
|
+
return prop in target || _isChronosStaticKey(prop);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/index.ts
|
|
153
|
+
/**
|
|
154
|
+
* @class Creates a new immutable `Chronos` instance.
|
|
155
|
+
* - **Note**: *If a date is provided **without a time component**, the instance will default to `00:00:00.000` UTC
|
|
156
|
+
* and convert it to the **equivalent local time** using the current environment's UTC offset.*
|
|
157
|
+
*
|
|
158
|
+
* @param value - A date value (`number`, `string`, `Date`, or `Chronos` object).
|
|
159
|
+
*
|
|
160
|
+
* @remarks
|
|
161
|
+
* - If a string is provided, it should be in a format that can be parsed by the {@link Date} constructor.
|
|
162
|
+
* - If a number is provided, it should be a timestamp (milliseconds since the Unix epoch).
|
|
163
|
+
* - If a `Date` or `Chronos` object is provided, it will be handled internally to parse the date value.
|
|
164
|
+
*
|
|
165
|
+
* **It also accepts number values as following:**
|
|
166
|
+
* - **`year, month, date, hours, minutes, seconds, milliseconds`**: Individual components of a date-time to construct a `Chronos` instance.
|
|
167
|
+
* - **`year`**: A number representing the year. If the year is between 0 and 99, it will be assumed to be the year 1900 + the provided year.
|
|
168
|
+
* - **`month`**: A number between 1 and 12 representing the month (1 for January, 12 for December).
|
|
169
|
+
* - **`date`**: A number between 1 and 31 representing the day of the month.
|
|
170
|
+
* - **`hours`**: A number between 0 and 23 representing the hour of the day.
|
|
171
|
+
* - **`minutes`**: A number between 0 and 59 representing the minutes past the hour.
|
|
172
|
+
* - **`seconds`**: A number between 0 and 59 representing the seconds past the minute.
|
|
173
|
+
* - **`milliseconds`**: A number between 0 and 999 representing the milliseconds past the second.
|
|
174
|
+
*
|
|
175
|
+
* @returns Instance of `Chronos` with all methods and properties.
|
|
176
|
+
*/
|
|
177
|
+
var Chronos = class Chronos {
|
|
178
|
+
#date;
|
|
179
|
+
#offset;
|
|
180
|
+
#ORIGIN;
|
|
181
|
+
static #plugins = /* @__PURE__ */ new Set();
|
|
182
|
+
/** Use `readonly and/or private` methods outside `Chronos`. Purpose: Plugin creation. */
|
|
183
|
+
static [INTERNALS] = {
|
|
184
|
+
internalDate(instance) {
|
|
185
|
+
return instance.#date;
|
|
186
|
+
},
|
|
187
|
+
offset(instance) {
|
|
188
|
+
return instance.#offset;
|
|
189
|
+
},
|
|
190
|
+
withOrigin(instance, method, offset, tzName, tzId, tzTracker) {
|
|
191
|
+
return instance.#withOrigin(method, offset, tzName, tzId, tzTracker);
|
|
192
|
+
},
|
|
193
|
+
toNewDate(instance, value) {
|
|
194
|
+
return instance.#toNewDate(value);
|
|
195
|
+
},
|
|
196
|
+
cast(date) {
|
|
197
|
+
return Chronos.#cast(date);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
/** Origin of the `Chronos` instance (Method that created `new Chronos`), useful for tracking instance. */
|
|
201
|
+
origin;
|
|
202
|
+
/**
|
|
203
|
+
* * `Chronos` date/time as Native JS `Date` object.
|
|
204
|
+
*
|
|
205
|
+
* - Also accessible via {@link toDate} instance method.
|
|
206
|
+
*/
|
|
207
|
+
native;
|
|
208
|
+
/**
|
|
209
|
+
* * Current (time zone) UTC offset in `UTC±HH:mm` format.
|
|
210
|
+
*
|
|
211
|
+
* - Also accessible via {@link getTimeZoneOffset} instance method without `UTC` prefix (returns in `±HH:mm` format).
|
|
212
|
+
*/
|
|
213
|
+
utcOffset;
|
|
214
|
+
/**
|
|
215
|
+
* Represents the current timezone name (e.g., `"Bangladesh Standard Time"`), or falls back to the corresponding timezone identifier (e.g., `"Asia/Dhaka"`) if no name can be resolved.
|
|
216
|
+
*
|
|
217
|
+
* @remarks
|
|
218
|
+
* - Invoking the {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone} method sets the timezone name that corresponds to the specified UTC offset, or the UTC offset itself if no name exists. For more details on this behavior, see {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/names#gettimezonename getTimeZoneName}.
|
|
219
|
+
* - To retrieve the local system's native timezone name (or its identifier if the name is unavailable), use the {@link $getNativeTimeZoneName} instance method.
|
|
220
|
+
*/
|
|
221
|
+
timeZoneName;
|
|
222
|
+
/**
|
|
223
|
+
* Represents the current timezone context, which can be a single identifier, an array of equivalent identifiers, or a UTC offset.
|
|
224
|
+
*
|
|
225
|
+
* - **{@link $TimeZoneIdentifier}** — e.g., `"Asia/Dhaka"`. Returned when the {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone} method has not been invoked. It is default behavior.
|
|
226
|
+
* - **Array of {@link $TimeZoneIdentifier}** — e.g., `[ 'Asia/Calcutta', 'Asia/Colombo' ]`, used when multiple timezones share the same UTC offset such as `"UTC+05:30"`.
|
|
227
|
+
* - **{@link UTCOffset}** — e.g., `"UTC+06:45"` or `"UTC+02:15"`, returned when no named timezone corresponds to a given offset.
|
|
228
|
+
*
|
|
229
|
+
* @remarks
|
|
230
|
+
* - By default, when {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone} is not applied, a single {@link $TimeZoneIdentifier} string is provided.
|
|
231
|
+
* - When applied, it may instead return a single identifier string, an array of equivalent identifiers or a UTC offset string.
|
|
232
|
+
* - To retrieve the local system's native timezone identifier, use the {@link $getNativeTimeZoneId} instance method.
|
|
233
|
+
*/
|
|
234
|
+
timeZoneId;
|
|
235
|
+
/** Tracker to identify the instance created by {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone} method */
|
|
236
|
+
$tzTracker;
|
|
237
|
+
/**
|
|
238
|
+
* * Creates a new immutable `Chronos` instance.
|
|
239
|
+
*
|
|
240
|
+
* **Note**: *If a date is provided **without a time component**, the instance will default to `00:00:00.000` UTC and convert it to the **equivalent local time** using the current environment's UTC offset.*
|
|
241
|
+
*
|
|
242
|
+
* @param valueOrYear The value in `number`, `string`, `Date` or `Chronos` format or the full year designation is required for cross-century date accuracy. If year is between 0 and 99, year is assumed to be 1900 + year.
|
|
243
|
+
* @param month The month as a `number` between 1 and 12 (1: January to 12: December).
|
|
244
|
+
* @param date The date as a `number` between 1 and 31.
|
|
245
|
+
* @param hours Must be supplied if minutes is supplied. A `number` from 0 to 23 (midnight to 11pm) that specifies the hour.
|
|
246
|
+
* @param minutes Must be supplied if seconds is supplied. A `number` from 0 to 59 that specifies the minutes.
|
|
247
|
+
* @param seconds Must be supplied if milliseconds is supplied. A `number` from 0 to 59 that specifies the seconds.
|
|
248
|
+
* @param ms A `number` from 0 to 999 that specifies the milliseconds.
|
|
249
|
+
*
|
|
250
|
+
* @returns Instance of `Chronos` with all methods and properties.
|
|
251
|
+
*/
|
|
252
|
+
constructor(valueOrYear, month, date, hours, minutes, seconds, ms) {
|
|
253
|
+
if (isNumber(valueOrYear) && isNumber(month)) {
|
|
254
|
+
this.#date = new Date(valueOrYear, month - 1, date ?? 1, hours ?? 0, minutes ?? 0, seconds ?? 0, ms ?? 0);
|
|
255
|
+
this.native = this.#date;
|
|
256
|
+
} else {
|
|
257
|
+
this.#date = this.#toNewDate(valueOrYear);
|
|
258
|
+
this.native = this.#date;
|
|
259
|
+
}
|
|
260
|
+
this.#ORIGIN = "root";
|
|
261
|
+
this.origin = this.#ORIGIN;
|
|
262
|
+
this.#offset = `UTC${this.getUTCOffset()}`;
|
|
263
|
+
this.utcOffset = this.#offset;
|
|
264
|
+
this.timeZoneName = this.$getNativeTimeZoneName();
|
|
265
|
+
this.timeZoneId = this.$getNativeTimeZoneId();
|
|
266
|
+
}
|
|
267
|
+
*[Symbol.iterator]() {
|
|
268
|
+
yield ["year", this.year];
|
|
269
|
+
yield ["month", this.month];
|
|
270
|
+
yield ["isoMonth", this.isoMonth];
|
|
271
|
+
yield ["date", this.date];
|
|
272
|
+
yield ["weekDay", this.weekDay];
|
|
273
|
+
yield ["isoWeekDay", this.isoWeekDay];
|
|
274
|
+
yield ["hour", this.hour];
|
|
275
|
+
yield ["minute", this.minute];
|
|
276
|
+
yield ["second", this.second];
|
|
277
|
+
yield ["millisecond", this.millisecond];
|
|
278
|
+
yield ["timestamp", this.getTimeStamp()];
|
|
279
|
+
yield ["unix", this.unix];
|
|
280
|
+
}
|
|
281
|
+
[Symbol.toPrimitive](hint) {
|
|
282
|
+
if (hint === "number") return this.getTimeStamp();
|
|
283
|
+
return this.toLocalISOString();
|
|
284
|
+
}
|
|
285
|
+
[Symbol.replace](string, replacement) {
|
|
286
|
+
return string.replace(this.#removeUTCFromISO(), replacement);
|
|
287
|
+
}
|
|
288
|
+
[Symbol.search](string) {
|
|
289
|
+
return string.indexOf(this.#removeUTCFromISO());
|
|
290
|
+
}
|
|
291
|
+
[Symbol.split](string) {
|
|
292
|
+
return string.split(this.#removeUTCFromISO());
|
|
293
|
+
}
|
|
294
|
+
[Symbol.match](string) {
|
|
295
|
+
const [datePart, timePart] = this.toLocalISOString().split(".")[0].split("T");
|
|
296
|
+
const fuzzyDate = datePart.replace(/-/g, "[-/]?");
|
|
297
|
+
const fuzzyTime = timePart?.replace(/:/g, "[:.]?");
|
|
298
|
+
const pattern = timePart ? `${fuzzyDate}(?:[T ]?${fuzzyTime})?` : fuzzyDate;
|
|
299
|
+
return string.match(new RegExp(pattern));
|
|
300
|
+
}
|
|
301
|
+
get [Symbol.toStringTag]() {
|
|
302
|
+
return this.toLocalISOString();
|
|
303
|
+
}
|
|
304
|
+
get [Symbol.isConcatSpreadable]() {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* @instance Retrieves the local system's current time zone name (e.g., `"Bangladesh Standard Time"`), or falls back to its corresponding IANA time zone identifier (e.g., `"Asia/Dhaka"`) if the name cannot be determined.
|
|
309
|
+
*
|
|
310
|
+
* @remarks
|
|
311
|
+
* - This method always reflects the local machine's time zone if `tzId` is parameter is omitted.
|
|
312
|
+
* - {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone}, {@link utc}, or {@link toUTC} methods have no effects on this method.
|
|
313
|
+
* - To access the time zone name of a modified or converted instance, use the {@link timeZoneName} public property instead.
|
|
314
|
+
*
|
|
315
|
+
* @param tzId Optional time zone identifier to get time zone name for that specific identifier if available.
|
|
316
|
+
*
|
|
317
|
+
* @returns The resolved time zone name or its IANA identifier as a fallback.
|
|
318
|
+
*/
|
|
319
|
+
$getNativeTimeZoneName(tzId) {
|
|
320
|
+
const $tzId = tzId || getNativeTimeZoneId();
|
|
321
|
+
return _resolveNativeTzName($tzId, "long", this.#date) ?? $tzId;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* @instance Retrieves the IANA time zone identifier (e.g., `"Asia/Dhaka"`, `"Africa/Harare"`) for the local system's current time zone.
|
|
325
|
+
*
|
|
326
|
+
* @remarks
|
|
327
|
+
* - This method always returns the identifier of the local machine's time zone.
|
|
328
|
+
* - {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone}, {@link utc}, or {@link toUTC} methods have no effects on this method.
|
|
329
|
+
* - To obtain the identifier(s) of a modified or converted instance, use the {@link timeZoneId} public property instead.
|
|
330
|
+
*
|
|
331
|
+
* @returns The local system's IANA time zone identifier.
|
|
332
|
+
*/
|
|
333
|
+
$getNativeTimeZoneId() {
|
|
334
|
+
return getNativeTimeZoneId();
|
|
335
|
+
}
|
|
336
|
+
/** Get timestamp (milliseconds since midnight, January 1, 1970 UTC) of the current instance, not the true `Date`. */
|
|
337
|
+
get #timestamp() {
|
|
338
|
+
return this.#date.getTime();
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* @private Method to create native `Date` instance from date-like data types.
|
|
342
|
+
* @param value The value to convert into `Date`.
|
|
343
|
+
* @returns Instance of native `Date` object.
|
|
344
|
+
*/
|
|
345
|
+
#toNewDate(value) {
|
|
346
|
+
const date = value instanceof Chronos ? value.toDate() : _dateArgsToDate(value);
|
|
347
|
+
if (isNaN(date.getTime())) throw new Error("Provided date is invalid!");
|
|
348
|
+
return date;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* @private Method to tag origin and other properties to the `Chronos` instance.
|
|
352
|
+
*
|
|
353
|
+
* @param origin Origin of the instance, the method name from where it was created.
|
|
354
|
+
* @param offset Optional UTC offset in `UTC±HH:mm` format.
|
|
355
|
+
* @param tzName Optional time zone name to set.
|
|
356
|
+
* @param tzId Optional time zone identifier(s) to set.
|
|
357
|
+
* @param tzTracker Optional tracker to identify the instance created by {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/conversion#timezone timeZone} method.
|
|
358
|
+
* @returns The `Chronos` instance with the specified origin and other properties.
|
|
359
|
+
*/
|
|
360
|
+
#withOrigin(origin, offset, tzName, tzId, tzTracker) {
|
|
361
|
+
const instance = new Chronos(this.#date);
|
|
362
|
+
instance.#ORIGIN = origin;
|
|
363
|
+
instance.origin = origin;
|
|
364
|
+
if (offset) {
|
|
365
|
+
instance.#offset = offset;
|
|
366
|
+
instance.utcOffset = offset;
|
|
367
|
+
}
|
|
368
|
+
if (tzName) instance.timeZoneName = tzName;
|
|
369
|
+
if (tzId) instance.timeZoneId = tzId;
|
|
370
|
+
if (tzTracker) instance.$tzTracker = tzTracker;
|
|
371
|
+
instance.native = instance.toDate();
|
|
372
|
+
return instance;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* @private Method to pass all the current states to the provided `Chronos` instance.
|
|
376
|
+
* @param instance States to pass to the `Chronos` instance.
|
|
377
|
+
* @param origin Origin of the instates (which method created the instance).
|
|
378
|
+
* @returns The provided instance with all the current states.
|
|
379
|
+
*/
|
|
380
|
+
#cloneStates(instance, origin) {
|
|
381
|
+
return instance.#withOrigin(origin, this.#offset, this.timeZoneName, this.timeZoneId, this.$tzTracker);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* @private Formats the current `Chronos` date using the specified template.
|
|
385
|
+
*
|
|
386
|
+
* @param format - The desired date format.
|
|
387
|
+
* @param useUTC - Whether to use UTC or local time.
|
|
388
|
+
* @returns Formatted date string.
|
|
389
|
+
*/
|
|
390
|
+
#format(format, useUTC = false) {
|
|
391
|
+
const $date = this.#date;
|
|
392
|
+
const $utcDate = this.toDate();
|
|
393
|
+
/** Get unit value for {@link $date} or {@link $utcDate} for specific unit */
|
|
394
|
+
const _getUnitValue = (suffix) => {
|
|
395
|
+
return useUTC ? $utcDate[`getUTC${suffix}`]() : $date[`get${suffix}`]();
|
|
396
|
+
};
|
|
397
|
+
return _formatDate(format, _getUnitValue("FullYear"), _getUnitValue("Month"), _getUnitValue("Day"), _getUnitValue("Date"), _getUnitValue("Hours"), _getUnitValue("Minutes"), _getUnitValue("Seconds"), _getUnitValue("Milliseconds"), useUTC ? "Z" : this.getTimeZoneOffset());
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* @private Returns ISO string for the current date with removed timezone/utc part.
|
|
401
|
+
* @param local Whether to use {@link toLocalISOString()} method or not. Defaults to `true`.
|
|
402
|
+
* @returns Modified ISO string for the current date with removed timezone/utc part.
|
|
403
|
+
*/
|
|
404
|
+
#removeUTCFromISO(local = true) {
|
|
405
|
+
const search = /\.\d+(Z|[+-]\d{2}:\d{2})?$/;
|
|
406
|
+
return local ? this.toLocalISOString().replace(search, "") : this.toISOString().replace(search, "");
|
|
407
|
+
}
|
|
408
|
+
/** Gets the full year of the date. */
|
|
409
|
+
get year() {
|
|
410
|
+
return this.#date.getFullYear();
|
|
411
|
+
}
|
|
412
|
+
/** Gets the month (0-11) of the date. */
|
|
413
|
+
get month() {
|
|
414
|
+
return this.#date.getMonth();
|
|
415
|
+
}
|
|
416
|
+
/** Gets the day of the month (1-31). */
|
|
417
|
+
get date() {
|
|
418
|
+
return this.#date.getDate();
|
|
419
|
+
}
|
|
420
|
+
/** Gets the day of the week (0-6, where 0 is Sunday). */
|
|
421
|
+
get weekDay() {
|
|
422
|
+
return this.#date.getDay();
|
|
423
|
+
}
|
|
424
|
+
/** Gets the hour (0-23) of the date. */
|
|
425
|
+
get hour() {
|
|
426
|
+
return this.#date.getHours();
|
|
427
|
+
}
|
|
428
|
+
/** Gets the minute (0-59) of the date. */
|
|
429
|
+
get minute() {
|
|
430
|
+
return this.#date.getMinutes();
|
|
431
|
+
}
|
|
432
|
+
/** Gets the second (0-59) of the date. */
|
|
433
|
+
get second() {
|
|
434
|
+
return this.#date.getSeconds();
|
|
435
|
+
}
|
|
436
|
+
/** Gets the millisecond (0-999) of the date. */
|
|
437
|
+
get millisecond() {
|
|
438
|
+
return this.#date.getMilliseconds();
|
|
439
|
+
}
|
|
440
|
+
/** Gets ISO weekday: 1 = Monday, 7 = Sunday */
|
|
441
|
+
get isoWeekDay() {
|
|
442
|
+
const day = this.weekDay;
|
|
443
|
+
return day === 0 ? 7 : day;
|
|
444
|
+
}
|
|
445
|
+
/** Gets ISO month (1–12 instead of 0–11) */
|
|
446
|
+
get isoMonth() {
|
|
447
|
+
return this.month + 1;
|
|
448
|
+
}
|
|
449
|
+
/** Returns the Unix timestamp (seconds since the Unix epoch: January 1, 1970, UTC). */
|
|
450
|
+
get unix() {
|
|
451
|
+
return Math.floor(this.getTimeStamp() / 1e3);
|
|
452
|
+
}
|
|
453
|
+
/** Gets the time value in milliseconds since midnight, January 1, 1970 UTC. */
|
|
454
|
+
get timestamp() {
|
|
455
|
+
return this.getTimeStamp();
|
|
456
|
+
}
|
|
457
|
+
/** * Gets the last date (number) of the current month `(28, 29, 30 or 31)`. */
|
|
458
|
+
get lastDateOfMonth() {
|
|
459
|
+
return this.daysInMonth();
|
|
460
|
+
}
|
|
461
|
+
/** @instance Returns a debug-friendly string for `console.log` or `util.inspect`. */
|
|
462
|
+
inspect() {
|
|
463
|
+
return `[Chronos ${this.toLocalISOString()}]`;
|
|
464
|
+
}
|
|
465
|
+
/** @instance Enables `JSON.stringify` to show readable output. Calls {@link toLocalISOString} method. */
|
|
466
|
+
toJSON() {
|
|
467
|
+
return this.toLocalISOString();
|
|
468
|
+
}
|
|
469
|
+
/** @instance Enables arithmetic and comparison operations (e.g., `+new Chronos()`). Calls {@link getTimeStamp} method. */
|
|
470
|
+
valueOf() {
|
|
471
|
+
return this.getTimeStamp();
|
|
472
|
+
}
|
|
473
|
+
/** @instance Clones and returns exactly same `Chronos` instance. */
|
|
474
|
+
clone() {
|
|
475
|
+
return new Chronos(this.#date).#withOrigin(this.#ORIGIN, this.#offset, this.timeZoneName, this.timeZoneId, this.$tzTracker);
|
|
476
|
+
}
|
|
477
|
+
/** @instance Gets the native `Date` instance of the current `Chronos`. */
|
|
478
|
+
toDate() {
|
|
479
|
+
const adjustmentMs = (extractMinutesFromUTC(this.#offset) - this.getUTCOffsetMinutes()) * 6e4;
|
|
480
|
+
return new Date(this.#timestamp - adjustmentMs);
|
|
481
|
+
}
|
|
482
|
+
/** @instance Returns a string representation of a date. */
|
|
483
|
+
toString() {
|
|
484
|
+
return this.#format("dd mmm DD YYYY HH:mm:ss ").concat(this.#offset.replace("UTC", "GMT").replace(":", "")).concat(` (${this.timeZoneName})`);
|
|
485
|
+
}
|
|
486
|
+
/** @instance Returns ISO time string in appropriate time zone with offset. */
|
|
487
|
+
toLocalISOString() {
|
|
488
|
+
return this.#format("YYYY-MM-DDTHH:mm:ss.mssZZ");
|
|
489
|
+
}
|
|
490
|
+
/** @instance Returns a date as a string value in ISO format (UTC). */
|
|
491
|
+
toISOString() {
|
|
492
|
+
return this.toDate().toISOString();
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* @instance Wrapper over native {@link Date.toLocaleString} with improved type system.
|
|
496
|
+
* @description Converts a date and time to a string by using the current or specified locale.
|
|
497
|
+
*
|
|
498
|
+
* @param locales A locale string, array of locale strings, {@link Intl.Locale} object, or array of {@link Intl.Locale} objects that contain one or more language or locale tags (see: {@link LocalesArguments}). If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
|
|
499
|
+
* @param options An object that contains one or more properties that specify comparison options (see: {@link DateTimeFormatOptions}).
|
|
500
|
+
*/
|
|
501
|
+
toLocaleString(locales, options) {
|
|
502
|
+
return this.#date.toLocaleString(locales, options);
|
|
503
|
+
}
|
|
504
|
+
/** @instance Returns the time value in milliseconds since midnight, January 1, 1970 UTC. */
|
|
505
|
+
getTimeStamp() {
|
|
506
|
+
return this.toDate().getTime();
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* @instance Formats the current date into a custom string format (local time by default).
|
|
510
|
+
*
|
|
511
|
+
* @param format - The desired format string (Default: `dd, mmm DD, YYYY HH:mm:ss` → e.g., `Sun, Apr 06, 2025 16:11:55`).
|
|
512
|
+
*
|
|
513
|
+
* - To output raw text (i.e., not interpreted as a date token), wrap it in square brackets.
|
|
514
|
+
* - For example, `[Today is] ddd` results in `Today is Sunday`, and `YYYY[ year]` results in `2025 year`.
|
|
515
|
+
*
|
|
516
|
+
* - Supported format tokens include: `YYYY`, `YY`, `mmmm`, `mmm`, `MM`, `M`, `DD`, `D`, `dd`, `ddd`, `Do`, `HH`, `H`, `hh`, `h`, `mm`, `m`, `ss`, `s`, `ms`, `mss`, `a`, `A`, `ZZ` and `Z`.
|
|
517
|
+
* - *Any token not wrapped in brackets will be parsed and replaced with its corresponding date component.*
|
|
518
|
+
* - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/format#format-tokens format tokens} for details.
|
|
519
|
+
*
|
|
520
|
+
* @param useUTC - Optional boolean to format the date using UTC time.
|
|
521
|
+
* When `true`, it behaves like `formatUTC()` and outputs time based on UTC offset. Defaults to `false`.
|
|
522
|
+
*
|
|
523
|
+
* @returns Formatted date string using the specified format.
|
|
524
|
+
* Uses local time by default unless `useUTC` is set to `true`.
|
|
525
|
+
*/
|
|
526
|
+
format(format, useUTC = false) {
|
|
527
|
+
return this.#format(format || "dd, mmm DD, YYYY HH:mm:ss", useUTC);
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* @instance Formats the date into a predefined strict string format using local time or UTC.
|
|
531
|
+
*
|
|
532
|
+
* @remarks Offers `over 21,300` predefined formats with full IntelliSense support.
|
|
533
|
+
*
|
|
534
|
+
* @param format - The desired format string. Defaults to `'dd, mmm DD, YYYY HH:mm:ss'`
|
|
535
|
+
* (e.g., `'Sun, Apr 06, 2025 16:11:55'`).
|
|
536
|
+
* - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/format#format-tokens format tokens} for details.
|
|
537
|
+
*
|
|
538
|
+
* @param useUTC - If `true`, formats the date in UTC (equivalent to `formatUTC()`).
|
|
539
|
+
* Defaults to `false` (local time).
|
|
540
|
+
* @returns A formatted date string in the specified format.
|
|
541
|
+
*/
|
|
542
|
+
formatStrict(format, useUTC = false) {
|
|
543
|
+
return this.#format(format || "dd, mmm DD, YYYY HH:mm:ss", useUTC);
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* @instance Formats the date into a custom string format (UTC time).
|
|
547
|
+
*
|
|
548
|
+
* @param format - The desired format (Default format is `dd, mmm DD, YYYY HH:mm:ss:mss` = `Sun, Apr 06, 2025 16:11:55:379`).
|
|
549
|
+
*
|
|
550
|
+
* - To output raw text (i.e., not interpreted as a date token), wrap it in square brackets.
|
|
551
|
+
* - For example, `[Today is] ddd` results in `Today is Sunday`, and `YYYY[ year]` results in `2025 year`.
|
|
552
|
+
*
|
|
553
|
+
* - Supported format tokens include: `YYYY`, `YY`, `mmmm`, `mmm`, `MM`, `M`, `DD`, `D`, `dd`, `ddd`, `Do`, `HH`, `H`, `hh`, `h`, `mm`, `m`, `ss`, `s`, `ms`, `mss`, `a`, `A`, `ZZ` and `Z`.
|
|
554
|
+
* - *Any token not wrapped in brackets will be parsed and replaced with its corresponding date component.*
|
|
555
|
+
* - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/format#format-tokens format tokens} for details.
|
|
556
|
+
*
|
|
557
|
+
* @returns Formatted date string in desired format (UTC time).
|
|
558
|
+
*/
|
|
559
|
+
formatUTC(format = "dd, mmm DD, YYYY HH:mm:ss:mss") {
|
|
560
|
+
return this.#format(format, true);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* @instance Adds seconds and returns a new immutable instance.
|
|
564
|
+
* @param seconds - Number of seconds to add.
|
|
565
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
566
|
+
*/
|
|
567
|
+
addSeconds(seconds) {
|
|
568
|
+
return this.#cloneStates(this.add(seconds, "second"), "addSeconds");
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* @instance Adds minutes and returns a new immutable instance.
|
|
572
|
+
* @param minutes - Number of minutes to add.
|
|
573
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
574
|
+
*/
|
|
575
|
+
addMinutes(minutes) {
|
|
576
|
+
return this.#cloneStates(this.add(minutes, "minute"), "addMinutes");
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* @instance Adds hours and returns a new immutable instance.
|
|
580
|
+
* @param hours - Number of hours to add.
|
|
581
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
582
|
+
*/
|
|
583
|
+
addHours(hours) {
|
|
584
|
+
return this.#cloneStates(this.add(hours, "hour"), "addHours");
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* @instance Adds days and returns a new immutable instance.
|
|
588
|
+
* @param days - Number of days to add.
|
|
589
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
590
|
+
*/
|
|
591
|
+
addDays(days) {
|
|
592
|
+
return this.#cloneStates(this.add(days, "day"), "addDays");
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* @instance Adds weeks and returns a new immutable instance.
|
|
596
|
+
* @param weeks - Number of weeks to add.
|
|
597
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
598
|
+
*/
|
|
599
|
+
addWeeks(weeks) {
|
|
600
|
+
return this.#cloneStates(this.add(weeks, "week"), "addWeeks");
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* @instance Adds months and returns a new immutable instance.
|
|
604
|
+
* @param months - Number of months to add.
|
|
605
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
606
|
+
*/
|
|
607
|
+
addMonths(months) {
|
|
608
|
+
return this.#cloneStates(this.add(months, "month"), "addMonths");
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* @instance Adds years and returns a new immutable instance.
|
|
612
|
+
* @param years - Number of years to add.
|
|
613
|
+
* @returns A new `Chronos` instance with the updated date.
|
|
614
|
+
*/
|
|
615
|
+
addYears(years) {
|
|
616
|
+
return this.#cloneStates(this.add(years, "year"), "addYears");
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* @instance Checks if the current year is a leap year.
|
|
620
|
+
* - A year is a leap year if it is divisible by 4, but not divisible by 100, unless it is also divisible by 400.
|
|
621
|
+
* - For example, 2000 and 2400 are leap years, but 1900 and 2100 are not.
|
|
622
|
+
* @param year - Optional year to check. Default is the year from current `Chronos` instance.
|
|
623
|
+
* @returns `true` if the year is a leap year, `false` otherwise.
|
|
624
|
+
*/
|
|
625
|
+
isLeapYear(year) {
|
|
626
|
+
return isLeapYear(year ?? this.year);
|
|
627
|
+
}
|
|
628
|
+
/** @instance Checks if another date is exactly equal to this one. */
|
|
629
|
+
isEqual(other) {
|
|
630
|
+
return this.#timestamp === Chronos.#cast(other).#timestamp;
|
|
631
|
+
}
|
|
632
|
+
/** @instance Checks if another date is exactly equal to or before this one. */
|
|
633
|
+
isEqualOrBefore(other) {
|
|
634
|
+
return this.#timestamp <= Chronos.#cast(other).#timestamp;
|
|
635
|
+
}
|
|
636
|
+
/** @instance Checks if another date is exactly equal to or after this one. */
|
|
637
|
+
isEqualOrAfter(other) {
|
|
638
|
+
return this.#timestamp >= Chronos.#cast(other).#timestamp;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* @instance Checks if another date is the same as this one in a specific unit.
|
|
642
|
+
* @param other The other date to compare.
|
|
643
|
+
* @param unit The unit to compare.
|
|
644
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
645
|
+
*/
|
|
646
|
+
isSame(other, unit, weekStartsOn = 0) {
|
|
647
|
+
return this.startOf(unit, weekStartsOn).#timestamp === Chronos.#cast(other).startOf(unit, weekStartsOn).#timestamp;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* @instance Checks if this date is before another date in a specific unit.
|
|
651
|
+
* @param other The other date to compare.
|
|
652
|
+
* @param unit The unit to compare.
|
|
653
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
654
|
+
*/
|
|
655
|
+
isBefore(other, unit, weekStartsOn = 0) {
|
|
656
|
+
return this.startOf(unit, weekStartsOn).#timestamp < Chronos.#cast(other).startOf(unit, weekStartsOn).#timestamp;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* @instance Checks if this date is after another date in a specific unit.
|
|
660
|
+
* @param other The other date to compare.
|
|
661
|
+
* @param unit The unit to compare.
|
|
662
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
663
|
+
*/
|
|
664
|
+
isAfter(other, unit, weekStartsOn = 0) {
|
|
665
|
+
return this.startOf(unit, weekStartsOn).#timestamp > Chronos.#cast(other).startOf(unit, weekStartsOn).#timestamp;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* @instance Checks if this date is the same or before another date in a specific unit.
|
|
669
|
+
* @param other The other date to compare.
|
|
670
|
+
* @param unit The unit to compare.
|
|
671
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
672
|
+
*/
|
|
673
|
+
isSameOrBefore(other, unit, weekStartsOn = 0) {
|
|
674
|
+
return this.isSame(other, unit, weekStartsOn) || this.isBefore(other, unit, weekStartsOn);
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* @instance Checks if this date is the same or after another date in a specific unit.
|
|
678
|
+
* @param other The other date to compare.
|
|
679
|
+
* @param unit The unit to compare.
|
|
680
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
681
|
+
*/
|
|
682
|
+
isSameOrAfter(other, unit, weekStartsOn = 0) {
|
|
683
|
+
return this.isSame(other, unit, weekStartsOn) || this.isAfter(other, unit, weekStartsOn);
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* @instance Checks if the current date is between the given start and end dates.
|
|
687
|
+
*
|
|
688
|
+
* @param start - The start of the range.
|
|
689
|
+
* @param end - The end of the range.
|
|
690
|
+
* @param inclusive - Specifies whether the comparison is inclusive or exclusive:
|
|
691
|
+
* - `'[]'`: inclusive of both start and end (≥ start and ≤ end)
|
|
692
|
+
* - `'[)'`: inclusive of start, exclusive of end (≥ start and < end)
|
|
693
|
+
* - `'(]'`: exclusive of start, inclusive of end (> start and ≤ end)
|
|
694
|
+
* - `'()'`: exclusive of both start and end (> start and < end)
|
|
695
|
+
*
|
|
696
|
+
* @returns `true` if the current date is within the specified range based on the `inclusive` mode.
|
|
697
|
+
*/
|
|
698
|
+
isBetween(start, end, inclusive = "()") {
|
|
699
|
+
const s = Chronos.#cast(start).getTimeStamp();
|
|
700
|
+
const e = Chronos.#cast(end).getTimeStamp();
|
|
701
|
+
const t = this.getTimeStamp();
|
|
702
|
+
switch (inclusive) {
|
|
703
|
+
case "[]": return t >= s && t <= e;
|
|
704
|
+
case "[)": return t >= s && t < e;
|
|
705
|
+
case "(]": return t > s && t <= e;
|
|
706
|
+
case "()": return t > s && t < e;
|
|
707
|
+
default: return false;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* @instance Checks if the date is within daylight saving time (DST).
|
|
712
|
+
* @returns Whether the date is in DST (`true` or `false`).
|
|
713
|
+
*/
|
|
714
|
+
isDST() {
|
|
715
|
+
const year = this.year;
|
|
716
|
+
const jan = new Date(year, 0, 1).getTimezoneOffset();
|
|
717
|
+
const jul = new Date(year, 6, 1).getTimezoneOffset();
|
|
718
|
+
return this.#date.getTimezoneOffset() < Math.max(jan, jul);
|
|
719
|
+
}
|
|
720
|
+
/** @instance Checks if current day is the first day of the current month. */
|
|
721
|
+
isFirstDayOfMonth() {
|
|
722
|
+
return this.isSame(this.firstDayOfMonth(), "day");
|
|
723
|
+
}
|
|
724
|
+
/** @instance Checks if current day is the last day of the current month. */
|
|
725
|
+
isLastDayOfMonth() {
|
|
726
|
+
return this.isSame(this.lastDayOfMonth(), "day");
|
|
727
|
+
}
|
|
728
|
+
/** @instance Returns a new `Chronos` instance set to the first day of the current month. */
|
|
729
|
+
firstDayOfMonth() {
|
|
730
|
+
const firstDate = new Date(this.year, this.month, 1);
|
|
731
|
+
return this.#cloneStates(new Chronos(firstDate), "firstDayOfMonth");
|
|
732
|
+
}
|
|
733
|
+
/** @instance Returns a new `Chronos` instance set to the last day of the current month. */
|
|
734
|
+
lastDayOfMonth() {
|
|
735
|
+
const lastDate = new Date(this.year, this.month + 1, 0);
|
|
736
|
+
return this.#cloneStates(new Chronos(lastDate), "lastDayOfMonth");
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* @instance Returns a new `Chronos` instance at the start of a given unit.
|
|
740
|
+
* @param unit The unit to reset (e.g., year, month, day).
|
|
741
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
742
|
+
*/
|
|
743
|
+
startOf(unit, weekStartsOn = 0) {
|
|
744
|
+
const d = new Date(this.#date);
|
|
745
|
+
switch (unit) {
|
|
746
|
+
case "year":
|
|
747
|
+
d.setMonth(0, 1);
|
|
748
|
+
d.setHours(0, 0, 0, 0);
|
|
749
|
+
break;
|
|
750
|
+
case "month":
|
|
751
|
+
d.setDate(1);
|
|
752
|
+
d.setHours(0, 0, 0, 0);
|
|
753
|
+
break;
|
|
754
|
+
case "week": {
|
|
755
|
+
const diff = (d.getDay() - weekStartsOn + 7) % 7;
|
|
756
|
+
d.setDate(d.getDate() - diff);
|
|
757
|
+
d.setHours(0, 0, 0, 0);
|
|
758
|
+
break;
|
|
759
|
+
}
|
|
760
|
+
case "day":
|
|
761
|
+
d.setHours(0, 0, 0, 0);
|
|
762
|
+
break;
|
|
763
|
+
case "hour":
|
|
764
|
+
d.setMinutes(0, 0, 0);
|
|
765
|
+
break;
|
|
766
|
+
case "minute":
|
|
767
|
+
d.setSeconds(0, 0);
|
|
768
|
+
break;
|
|
769
|
+
case "second":
|
|
770
|
+
d.setMilliseconds(0);
|
|
771
|
+
break;
|
|
772
|
+
case "millisecond": break;
|
|
773
|
+
}
|
|
774
|
+
return this.#cloneStates(new Chronos(d), "startOf");
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* @instance Returns a new `Chronos` instance at the end of a given unit.
|
|
778
|
+
* @param unit The unit to adjust (e.g., year, month, day).
|
|
779
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
780
|
+
*/
|
|
781
|
+
endOf(unit, weekStartsOn = 0) {
|
|
782
|
+
const instance = this.startOf(unit, weekStartsOn).add(1, unit).add(-1, "millisecond");
|
|
783
|
+
return this.#cloneStates(instance, "endOf");
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* @instance Returns a new `Chronos` instance with the specified unit added.
|
|
787
|
+
* @param number The number of time unit to add (can be negative).
|
|
788
|
+
* @param unit The time unit to add.
|
|
789
|
+
*/
|
|
790
|
+
add(number, unit) {
|
|
791
|
+
const d = new Date(this.#date);
|
|
792
|
+
switch (unit) {
|
|
793
|
+
case "millisecond":
|
|
794
|
+
d.setMilliseconds(d.getMilliseconds() + number);
|
|
795
|
+
break;
|
|
796
|
+
case "second":
|
|
797
|
+
d.setSeconds(d.getSeconds() + number);
|
|
798
|
+
break;
|
|
799
|
+
case "minute":
|
|
800
|
+
d.setMinutes(d.getMinutes() + number);
|
|
801
|
+
break;
|
|
802
|
+
case "hour":
|
|
803
|
+
d.setHours(d.getHours() + number);
|
|
804
|
+
break;
|
|
805
|
+
case "day":
|
|
806
|
+
d.setDate(d.getDate() + number);
|
|
807
|
+
break;
|
|
808
|
+
case "week":
|
|
809
|
+
d.setDate(d.getDate() + number * 7);
|
|
810
|
+
break;
|
|
811
|
+
case "month":
|
|
812
|
+
d.setMonth(d.getMonth() + number);
|
|
813
|
+
break;
|
|
814
|
+
case "year":
|
|
815
|
+
d.setFullYear(d.getFullYear() + number);
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
return this.#cloneStates(new Chronos(d), "add");
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* @instance Returns a new `Chronos` instance with the specified unit subtracted.
|
|
822
|
+
* @param number The number of time unit to subtract (can be negative).
|
|
823
|
+
* @param unit The time unit to add.
|
|
824
|
+
*/
|
|
825
|
+
subtract(number, unit) {
|
|
826
|
+
return this.#cloneStates(this.add(-number, unit), "subtract");
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* @instance Gets the value of a specific time unit from the date.
|
|
830
|
+
* @param unit The unit to retrieve. Type of return value is determined by `unit`.
|
|
831
|
+
*/
|
|
832
|
+
get(unit) {
|
|
833
|
+
switch (unit) {
|
|
834
|
+
case "year": return this.year;
|
|
835
|
+
case "month": return this.isoMonth;
|
|
836
|
+
case "day": return this.date;
|
|
837
|
+
case "week": return this.getWeek();
|
|
838
|
+
case "hour": return this.hour;
|
|
839
|
+
case "minute": return this.minute;
|
|
840
|
+
case "second": return this.second;
|
|
841
|
+
case "millisecond": return this.millisecond;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* @instance Returns a new `Chronos` instance with the specified unit set to the given value.
|
|
846
|
+
* @param unit The unit to modify. Type of `value` is determined by `unit`.
|
|
847
|
+
* @param value The value to set for the unit. Type of `value` is determined by `unit`.
|
|
848
|
+
*/
|
|
849
|
+
set(unit, value) {
|
|
850
|
+
const d = new Date(this.#date);
|
|
851
|
+
switch (unit) {
|
|
852
|
+
case "year":
|
|
853
|
+
d.setFullYear(value);
|
|
854
|
+
break;
|
|
855
|
+
case "month":
|
|
856
|
+
d.setMonth(value - 1);
|
|
857
|
+
break;
|
|
858
|
+
case "day":
|
|
859
|
+
d.setDate(value);
|
|
860
|
+
break;
|
|
861
|
+
case "week": return this.setWeek(value);
|
|
862
|
+
case "hour":
|
|
863
|
+
d.setHours(value);
|
|
864
|
+
break;
|
|
865
|
+
case "minute":
|
|
866
|
+
d.setMinutes(value);
|
|
867
|
+
break;
|
|
868
|
+
case "second":
|
|
869
|
+
d.setSeconds(value);
|
|
870
|
+
break;
|
|
871
|
+
case "millisecond":
|
|
872
|
+
d.setMilliseconds(value);
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
return this.#cloneStates(new Chronos(d), "set");
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* @instance Returns the difference between current and another date in the given unit.
|
|
879
|
+
* @param other The other date to compare.
|
|
880
|
+
* @param unit The unit in which to return the difference.
|
|
881
|
+
* @returns Difference in number (either `integer` or `float`).
|
|
882
|
+
*/
|
|
883
|
+
diff(other, unit) {
|
|
884
|
+
const time = Chronos.#cast(other);
|
|
885
|
+
const msDiff = this.#timestamp - time.#timestamp;
|
|
886
|
+
switch (unit) {
|
|
887
|
+
case "millisecond": return msDiff;
|
|
888
|
+
case "second": return msDiff / 1e3;
|
|
889
|
+
case "minute": return msDiff / 6e4;
|
|
890
|
+
case "hour": return msDiff / 36e5;
|
|
891
|
+
case "day": return msDiff / 864e5;
|
|
892
|
+
case "week": return msDiff / 6048e5;
|
|
893
|
+
case "month": {
|
|
894
|
+
const yearDiff = this.year - time.year;
|
|
895
|
+
const monthDiff = this.month - time.month;
|
|
896
|
+
return yearDiff * 12 + monthDiff + (this.date - time.date) / this.daysInMonth();
|
|
897
|
+
}
|
|
898
|
+
case "year": return this.diff(time, "month") / 12;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* @instance Returns a human-readable relative calendar time like "Today at 3:00 PM"
|
|
903
|
+
* @param baseDate Optional base date to compare with.
|
|
904
|
+
*/
|
|
905
|
+
calendar(baseDate) {
|
|
906
|
+
const base = baseDate ? Chronos.#cast(baseDate) : new Chronos();
|
|
907
|
+
const input = this.startOf("day");
|
|
908
|
+
const comparison = base.startOf("day");
|
|
909
|
+
const diff = input.diff(comparison, "day");
|
|
910
|
+
const timeStr = this.toDate().toLocaleString("en", {
|
|
911
|
+
hour: "numeric",
|
|
912
|
+
minute: "2-digit"
|
|
913
|
+
});
|
|
914
|
+
if (diff === 0) return `Today at ${timeStr}`;
|
|
915
|
+
if (diff === 1) return `Tomorrow at ${timeStr}`;
|
|
916
|
+
if (diff === -1) return `Yesterday at ${timeStr}`;
|
|
917
|
+
return this.toDate().toLocaleString("en", {
|
|
918
|
+
month: "long",
|
|
919
|
+
day: "2-digit",
|
|
920
|
+
year: "numeric",
|
|
921
|
+
weekday: "long",
|
|
922
|
+
hour: "numeric",
|
|
923
|
+
minute: "2-digit"
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
/** @instance Returns a short human-readable string like "2h ago", "in 5m". From `year` to `second`. */
|
|
927
|
+
fromNowShort() {
|
|
928
|
+
const now = new Chronos();
|
|
929
|
+
const diffInSeconds = this.diff(now, "second");
|
|
930
|
+
const abs = Math.abs(diffInSeconds);
|
|
931
|
+
const prefix = diffInSeconds >= 0 ? "in " : "";
|
|
932
|
+
const suffix = diffInSeconds < 0 ? " ago" : "";
|
|
933
|
+
if (abs < 60) return `${prefix}${Math.floor(abs)}s${suffix}`;
|
|
934
|
+
else if (abs < 3600) return `${prefix}${Math.floor(abs / 60)}m${suffix}`;
|
|
935
|
+
else if (abs < 86400) return `${prefix}${Math.floor(abs / 3600)}h${suffix}`;
|
|
936
|
+
else if (abs < 2592e3) return `${prefix}${Math.floor(abs / 86400)}d${suffix}`;
|
|
937
|
+
else if (abs < 31536e3) return `${prefix}${Math.floor(abs / 2592e3)}mo${suffix}`;
|
|
938
|
+
else return `${prefix}${Math.floor(abs / 31536e3)}y${suffix}`;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* @instance Sets the date to the Monday of the specified ISO week number within the current year.
|
|
942
|
+
* This method assumes ISO week logic, where week 1 is the week containing January 4th.
|
|
943
|
+
*
|
|
944
|
+
* @param week The ISO week number (1–53) to set the date to.
|
|
945
|
+
* @returns A new `Chronos` instance set to the start (Monday) of the specified week.
|
|
946
|
+
*/
|
|
947
|
+
setWeek(week) {
|
|
948
|
+
const d = new Date(this.#date);
|
|
949
|
+
const year = d.getFullYear();
|
|
950
|
+
const jan4 = new Date(year, 0, 4);
|
|
951
|
+
const dayOfWeek = jan4.getDay() || 7;
|
|
952
|
+
const weekStart = new Date(jan4);
|
|
953
|
+
weekStart.setDate(jan4.getDate() - (dayOfWeek - 1));
|
|
954
|
+
weekStart.setDate(weekStart.getDate() + (week - 1) * 7);
|
|
955
|
+
d.setFullYear(weekStart.getFullYear());
|
|
956
|
+
d.setMonth(weekStart.getMonth());
|
|
957
|
+
d.setDate(weekStart.getDate());
|
|
958
|
+
return this.#cloneStates(new Chronos(d), "setWeek");
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* @instance Calculates the ISO 8601 week number of the year.
|
|
962
|
+
*
|
|
963
|
+
* @Remarks ISO weeks start on Monday, and the first week of the year is the one containing January 4th.
|
|
964
|
+
*
|
|
965
|
+
* @returns Week number (1–53).
|
|
966
|
+
*/
|
|
967
|
+
getWeek() {
|
|
968
|
+
const target = this.startOf("week", 1).add(3, "day");
|
|
969
|
+
const firstThursday = new Chronos(target.year, 1, 4).startOf("week", 1).add(3, "day");
|
|
970
|
+
return target.diff(firstThursday, "week") + 1;
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* @instance Calculates the week number of the year based on custom week start.
|
|
974
|
+
* @param weekStartsOn Optional: Day the week starts on (0 = Sunday, 1 = Monday). Applicable if week day is required. Default is `0`.
|
|
975
|
+
* @returns Week number (1-53).
|
|
976
|
+
*/
|
|
977
|
+
getWeekOfYear(weekStartsOn = 0) {
|
|
978
|
+
const startOfFirstWeek = this.startOf("year").startOf("week", weekStartsOn);
|
|
979
|
+
return this.startOf("week", weekStartsOn).diff(startOfFirstWeek, "week") + 1;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* @instance Returns the ISO week-numbering year for the current date.
|
|
983
|
+
*
|
|
984
|
+
* The ISO week-numbering year may differ from the calendar year.
|
|
985
|
+
* For example, January 1st may fall in the last ISO week of the previous year.
|
|
986
|
+
*
|
|
987
|
+
* @param weekStartsOn Optional: Defines the start day of the week (0 = Sunday, 1 = Monday).
|
|
988
|
+
* Defaults to `0` (Sunday). Use 1 for strict ISO 8601.
|
|
989
|
+
* @returns The ISO week-numbering year.
|
|
990
|
+
*/
|
|
991
|
+
getWeekYear(weekStartsOn = 0) {
|
|
992
|
+
return this.startOf("week", weekStartsOn).add(3, "day").year;
|
|
993
|
+
}
|
|
994
|
+
/** @instance Returns day of year (1 - 366) */
|
|
995
|
+
getDayOfYear() {
|
|
996
|
+
return this.startOf("day").diff(this.startOf("year"), "day") + 1;
|
|
997
|
+
}
|
|
998
|
+
/** @instance Returns number of days in current month */
|
|
999
|
+
daysInMonth() {
|
|
1000
|
+
return new Date(this.year, this.month + 1, 0).getDate();
|
|
1001
|
+
}
|
|
1002
|
+
/** @instance Converts to object with all date unit parts */
|
|
1003
|
+
toObject() {
|
|
1004
|
+
return Object.fromEntries([...this]);
|
|
1005
|
+
}
|
|
1006
|
+
/** @instance Converts to array with all date unit parts */
|
|
1007
|
+
toArray() {
|
|
1008
|
+
return Object.values(this.toObject());
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* @instance Returns the **calendar quarter** (1 to 4) of the current date.
|
|
1012
|
+
*
|
|
1013
|
+
* @remarks
|
|
1014
|
+
* A calendar year is divided into four quarters:
|
|
1015
|
+
*
|
|
1016
|
+
* - `Q1`: January to March
|
|
1017
|
+
* - `Q2`: April to June
|
|
1018
|
+
* - `Q3`: July to September
|
|
1019
|
+
* - `Q4`: October to December
|
|
1020
|
+
*
|
|
1021
|
+
* This method strictly uses the **calendar year**. For fiscal quarters, use {@link toFiscalQuarter} instead.
|
|
1022
|
+
*
|
|
1023
|
+
* @example
|
|
1024
|
+
* new Chronos('2025-02-14').toQuarter(); // 1
|
|
1025
|
+
* new Chronos('2025-08-09').toQuarter(); // 3
|
|
1026
|
+
*
|
|
1027
|
+
* @returns The calendar quarter number (1–4).
|
|
1028
|
+
*/
|
|
1029
|
+
toQuarter() {
|
|
1030
|
+
const month = this.#date.getMonth();
|
|
1031
|
+
return Math.floor(month / 3) + 1;
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* @instance Returns the system's current UTC offset formatted as `±HH:mm` (`+06:00` or `-07:00`).
|
|
1035
|
+
*
|
|
1036
|
+
* - *Unlike JavaScript's {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset `Date.prototype.getTimezoneOffset()`}, which returns the offset in minutes **behind** UTC (positive for locations west of UTC and negative for east), this method returns the more intuitive sign format used in timezone representations (e.g., `+06:00` means 6 hours **ahead** of UTC).*
|
|
1037
|
+
*
|
|
1038
|
+
* @returns The (local) system's UTC offset in `±HH:mm` format.
|
|
1039
|
+
*/
|
|
1040
|
+
getUTCOffset() {
|
|
1041
|
+
const offset = -this.#date.getTimezoneOffset();
|
|
1042
|
+
const sign = offset >= 0 ? "+" : "-";
|
|
1043
|
+
const pad = (n) => String(Math.floor(Math.abs(n))).padStart(2, "0");
|
|
1044
|
+
return `${sign}${pad(offset / 60)}:${pad(offset % 60)}`;
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* @instance Returns the timezone offset of this `Chronos` instance in `±HH:mm` format maintaining current timezone.
|
|
1048
|
+
*
|
|
1049
|
+
* - *Unlike JavaScript's {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset `Date.prototype.getTimezoneOffset()`}, which returns the offset in minutes **behind** UTC (positive for locations west of UTC and negative for east), this method returns the more intuitive sign format used in timezone representations (e.g., `+06:00` means 6 hours **ahead** of UTC).*
|
|
1050
|
+
*
|
|
1051
|
+
* @returns The timezone offset string in `±HH:mm` format maintaining the current timezone regardless of system having different one.
|
|
1052
|
+
*/
|
|
1053
|
+
getTimeZoneOffset() {
|
|
1054
|
+
return this.#offset.replace("UTC", "");
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* @instance Gets the difference in minutes between Universal Coordinated Time (UTC) and the time on the local computer.
|
|
1058
|
+
*
|
|
1059
|
+
* - *Unlike JavaScript's {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset `Date.prototype.getTimezoneOffset()`}, this method returns a positive value if the local time is ahead of UTC, and negative if behind UTC.*
|
|
1060
|
+
*
|
|
1061
|
+
* For example, for `UTC+06:00`, this returns `360`; for `UTC-05:30`, this returns `-330`.
|
|
1062
|
+
*
|
|
1063
|
+
* @returns The system's UTC offset in minutes, matching the sign convention used in `±HH:mm`.
|
|
1064
|
+
*/
|
|
1065
|
+
getUTCOffsetMinutes() {
|
|
1066
|
+
return -this.#date.getTimezoneOffset();
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* @instance Returns the current `Chronos` instance's UTC offset in minutes.
|
|
1070
|
+
*
|
|
1071
|
+
* This reflects the parsed or stored offset used internally by `Chronos` and follows the same
|
|
1072
|
+
* sign convention: positive for timezones ahead of UTC, negative for behind.
|
|
1073
|
+
*
|
|
1074
|
+
* @returns The UTC offset in minutes maintaining the current timezone regardless of system having different one.
|
|
1075
|
+
*/
|
|
1076
|
+
getTimeZoneOffsetMinutes() {
|
|
1077
|
+
return extractMinutesFromUTC(this.#offset);
|
|
1078
|
+
}
|
|
1079
|
+
/** @instance Returns new `Chronos` instance in UTC time */
|
|
1080
|
+
toUTC() {
|
|
1081
|
+
const offset = this.getTimeZoneOffsetMinutes();
|
|
1082
|
+
return new Chronos(/* @__PURE__ */ new Date(this.#timestamp - offset * 60 * 1e3)).#withOrigin("toUTC", "UTC+00:00", "Greenwich Mean Time", "UTC");
|
|
1083
|
+
}
|
|
1084
|
+
/** @instance Returns new `Chronos` instance in local time */
|
|
1085
|
+
toLocal() {
|
|
1086
|
+
const offset = this.getTimeZoneOffsetMinutes() - this.getUTCOffsetMinutes();
|
|
1087
|
+
return new Chronos(/* @__PURE__ */ new Date(this.#timestamp - offset * 60 * 1e3)).#withOrigin("toLocal");
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* @instance Returns the name of the current day or optional day index.
|
|
1091
|
+
* @param index Optional day index (`0–6`, where `0` is `Sunday`) to override current day.
|
|
1092
|
+
* @returns Name of the weekday, e.g., `'Monday'`, `'Tuesday'` etc.
|
|
1093
|
+
*/
|
|
1094
|
+
day(index) {
|
|
1095
|
+
return DAYS[index ?? this.weekDay];
|
|
1096
|
+
}
|
|
1097
|
+
/**
|
|
1098
|
+
* @instance Returns the name of the current month or optional month index.
|
|
1099
|
+
* @param index Optional month index (`0–11`, where `0` is `January`) to override current month.
|
|
1100
|
+
* @returns Name of the month, e.g., `'January'`, `'February'` etc.
|
|
1101
|
+
*/
|
|
1102
|
+
monthName(index) {
|
|
1103
|
+
return MONTHS[index ?? this.month];
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* @static Parses a date string with a given format (limited support only).
|
|
1107
|
+
*
|
|
1108
|
+
* **Supported format tokens**:
|
|
1109
|
+
* - `YYYY`: Full year (e.g., 2023)
|
|
1110
|
+
* - `YY`: Two-digit year (e.g., 23 for 2023, 99 for 1999)
|
|
1111
|
+
* - `MM`: Month (01-12)
|
|
1112
|
+
* - `M`: Month (1-12)
|
|
1113
|
+
* - `DD`: Day of the month (01-31)
|
|
1114
|
+
* - `D`: Day of the month (1-31)
|
|
1115
|
+
* - `HH`: Hour (00-23)
|
|
1116
|
+
* - `H`: Hour (0-23)
|
|
1117
|
+
* - `mm`: Minute (00-59)
|
|
1118
|
+
* - `m`: Minute (0-59)
|
|
1119
|
+
* - `ss`: Second (00-59)
|
|
1120
|
+
* - `s`: Second (0-59)
|
|
1121
|
+
* - `mss`: Millisecond (000-999)
|
|
1122
|
+
* - `ms`: Millisecond (0-999)
|
|
1123
|
+
*
|
|
1124
|
+
* @example
|
|
1125
|
+
* Chronos.parse('23-12-31 15:30:45', 'YY-MM-DD HH:mm:ss');
|
|
1126
|
+
* // returns `Chronos` instance with the parsed date 2023-12-31T15:30:45
|
|
1127
|
+
*
|
|
1128
|
+
* @param dateStr - The date string to be parsed
|
|
1129
|
+
* @param format - The format of the date string. Supported tokens `YYYY`, `YY` `MM`, `M`, `DD`, `D`, `HH`, `H`, `mm`, `m`, `ss`, `s`, `mss`, `ms` are used to specify the structure.
|
|
1130
|
+
* @returns A new `Chronos` instance representing the parsed date.
|
|
1131
|
+
* @throws `Error` If the date string does not match the format.
|
|
1132
|
+
*/
|
|
1133
|
+
static parse(dateStr, format) {
|
|
1134
|
+
const tokenPatterns = {
|
|
1135
|
+
YYYY: "(?<YYYY>\\d{4})",
|
|
1136
|
+
YY: "(?<YY>\\d{2})",
|
|
1137
|
+
MM: "(?<MM>\\d{2})",
|
|
1138
|
+
M: "(?<M>\\d{1,2})",
|
|
1139
|
+
DD: "(?<DD>\\d{2})",
|
|
1140
|
+
D: "(?<D>\\d{1,2})",
|
|
1141
|
+
HH: "(?<HH>\\d{2})",
|
|
1142
|
+
H: "(?<H>\\d{1,2})",
|
|
1143
|
+
mm: "(?<mm>\\d{2})",
|
|
1144
|
+
m: "(?<m>\\d{1,2})",
|
|
1145
|
+
ss: "(?<ss>\\d{2})",
|
|
1146
|
+
s: "(?<s>\\d{1,2})",
|
|
1147
|
+
mss: "(?<mss>\\d{3})",
|
|
1148
|
+
ms: "(?<ms>\\d{1,3})"
|
|
1149
|
+
};
|
|
1150
|
+
const tokenToComponent = {
|
|
1151
|
+
YYYY: "year",
|
|
1152
|
+
YY: "year",
|
|
1153
|
+
MM: "month",
|
|
1154
|
+
M: "month",
|
|
1155
|
+
DD: "date",
|
|
1156
|
+
D: "date",
|
|
1157
|
+
HH: "hour",
|
|
1158
|
+
H: "hour",
|
|
1159
|
+
mm: "minute",
|
|
1160
|
+
m: "minute",
|
|
1161
|
+
ss: "second",
|
|
1162
|
+
s: "second",
|
|
1163
|
+
mss: "millisecond",
|
|
1164
|
+
ms: "millisecond"
|
|
1165
|
+
};
|
|
1166
|
+
const tokenRegExp = new RegExp(Object.keys(tokenPatterns).sort((a, b) => b.length - a.length).join("|"), "g");
|
|
1167
|
+
const regexStr = format?.trim()?.replace(tokenRegExp, (token) => tokenPatterns[token] ?? token)?.replace(/\s+/g, "\\s*");
|
|
1168
|
+
const match = new RegExp(`^${regexStr}\\s*$`).exec(dateStr.trim());
|
|
1169
|
+
if (!match?.groups) throw new Error("Invalid date format!");
|
|
1170
|
+
const parts = {};
|
|
1171
|
+
for (const [token, value] of Object.entries(match.groups)) {
|
|
1172
|
+
const key = tokenToComponent[token];
|
|
1173
|
+
if (key) {
|
|
1174
|
+
let num = Number(value);
|
|
1175
|
+
if (token === "YY") num += num < 100 ? 2e3 : 0;
|
|
1176
|
+
parts[key] = num;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
return new Chronos(parts?.year ?? 1970, parts?.month ?? 1, parts?.date ?? 1, parts?.hour ?? 0, parts?.minute ?? 0, parts?.second ?? 0, parts?.millisecond ?? 0).#withOrigin("parse");
|
|
1180
|
+
}
|
|
1181
|
+
/**
|
|
1182
|
+
* @static Creates a new `Chronos` instance with the provided time component(s).
|
|
1183
|
+
*
|
|
1184
|
+
* @param options - One or more time components to override.
|
|
1185
|
+
* @returns A new `Chronos` instance with the provided time components applied.
|
|
1186
|
+
*
|
|
1187
|
+
* @remarks
|
|
1188
|
+
* - Unspecified components are filled with the current time's (`Chronos`) respective values.
|
|
1189
|
+
* - For option `month`, value should be number from `1` (January) to `12` (December).
|
|
1190
|
+
* - If the `date` component is omitted and the current day is the last day of its month,
|
|
1191
|
+
* the resulting instance will also use the last day of the target month.
|
|
1192
|
+
* - _This rule does **not** apply if the `date` component is explicitly provided,
|
|
1193
|
+
* even if that value exceeds the last day of the target month._
|
|
1194
|
+
*
|
|
1195
|
+
* @example
|
|
1196
|
+
* // Override only the year and month
|
|
1197
|
+
* const c = Chronos.with({ year: 2025, month: 12 });
|
|
1198
|
+
*/
|
|
1199
|
+
static with(options) {
|
|
1200
|
+
const now = new Chronos();
|
|
1201
|
+
const { year, month, date, hour, minute, second, millisecond } = options ?? {};
|
|
1202
|
+
const nextLDoM = () => {
|
|
1203
|
+
return now.startOf("month").set("year", year ?? now.year).set("month", month ?? now.isoMonth).lastDateOfMonth;
|
|
1204
|
+
};
|
|
1205
|
+
return new Chronos(year ?? now.year, month ?? now.isoMonth, date ? date : now.isLastDayOfMonth() && now.date >= nextLDoM() ? nextLDoM() : now.date, hour ?? now.hour, minute ?? now.minute, second ?? now.second, millisecond ?? now.millisecond).#withOrigin("with");
|
|
1206
|
+
}
|
|
1207
|
+
/**
|
|
1208
|
+
* @static Returns the current date and time in a specified format in local time.
|
|
1209
|
+
* * Default format is dd, `mmm DD, YYYY HH:mm:ss` = `Sun, Apr 06, 2025 16:11:55`
|
|
1210
|
+
* @param options - Configure format string and whether to format using utc offset.
|
|
1211
|
+
* @returns Formatted date string in desired format.
|
|
1212
|
+
*/
|
|
1213
|
+
static today(options) {
|
|
1214
|
+
const { format = "dd, mmm DD, YYYY HH:mm:ss", useUTC = false } = options || {};
|
|
1215
|
+
return new Chronos().#format(format, useUTC);
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* @static Returns a new `Chronos` instance representing yesterday's date.
|
|
1219
|
+
*
|
|
1220
|
+
* @returns A `Chronos` instance for the previous calendar day.
|
|
1221
|
+
*/
|
|
1222
|
+
static yesterday() {
|
|
1223
|
+
const today = /* @__PURE__ */ new Date();
|
|
1224
|
+
return new Chronos(today.setDate(today.getDate() - 1)).#withOrigin("yesterday");
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* @static Returns a new `Chronos` instance representing tomorrow's date.
|
|
1228
|
+
*
|
|
1229
|
+
* @returns A `Chronos` instance for the next calendar day.
|
|
1230
|
+
*/
|
|
1231
|
+
static tomorrow() {
|
|
1232
|
+
const today = /* @__PURE__ */ new Date();
|
|
1233
|
+
return new Chronos(today.setDate(today.getDate() + 1)).#withOrigin("tomorrow");
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* @static Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).
|
|
1237
|
+
* @returns The number of milliseconds elapsed since the Unix epoch.
|
|
1238
|
+
* @remarks It internally uses {@link Date.now()}.
|
|
1239
|
+
*/
|
|
1240
|
+
static now() {
|
|
1241
|
+
return Date.now();
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* @static Creates a UTC-based `Chronos` instance.
|
|
1245
|
+
* If no date is provided, it uses the current date and time.
|
|
1246
|
+
*
|
|
1247
|
+
* **This is the base time, meaning conversion in other timezone will consider UTC time as the base time.**
|
|
1248
|
+
*
|
|
1249
|
+
* @param dateLike Optional input date to base the UTC time on.
|
|
1250
|
+
* If omitted, the current system date/time is used.
|
|
1251
|
+
* @returns A new `Chronos` instance representing the UTC equivalent of the input.
|
|
1252
|
+
*/
|
|
1253
|
+
static utc(dateLike) {
|
|
1254
|
+
const chronos = new Chronos(dateLike);
|
|
1255
|
+
const offset = chronos.getTimeZoneOffsetMinutes();
|
|
1256
|
+
return new Chronos(/* @__PURE__ */ new Date(chronos.#timestamp - offset * 60 * 1e3)).#withOrigin("utc", "UTC+00:00", "Greenwich Mean Time", "UTC");
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* @static Formats a time-only string into a formatted time string.
|
|
1260
|
+
*
|
|
1261
|
+
* @param time - Time string to be formatted. Supported formats include:
|
|
1262
|
+
* - `HH:mm` → e.g., `'14:50'`
|
|
1263
|
+
* - `HH:mm:ss` → e.g., `'14:50:00'`
|
|
1264
|
+
* - `HH:mm:ss.mss` → e.g., `'14:50:00.800'`
|
|
1265
|
+
* - `HH:mm+TimeZoneOffset(HH)` → e.g., `'14:50+06'`
|
|
1266
|
+
* - `HH:mm+TimeZoneOffset(HH:mm)` → e.g., `'14:50+06:00'`
|
|
1267
|
+
* - `HH:mm:ss+TimeZoneOffset(HH)` → e.g., `'14:50:00+06'`
|
|
1268
|
+
* - `HH:mm:ss+TimeZoneOffset(HH:mm)` → e.g., `'14:50:00+05:30'`
|
|
1269
|
+
* - `HH:mm:ss.mss+TimeZoneOffset(HH)` → e.g., `'14:50:00.800+06'`
|
|
1270
|
+
* - `HH:mm:ss.mss+TimeZoneOffset(HH:mm)` → e.g., `'14:50:00.800+06:30'`
|
|
1271
|
+
*
|
|
1272
|
+
* - *Input will default to today's date and assume local timezone if no offset is provided.*
|
|
1273
|
+
*
|
|
1274
|
+
* @param format - Format tokens accepted by {@link formatStrict()} method ({@link TimeOnlyFormat}) for time part only.
|
|
1275
|
+
* Default: `hh:mm:ss a` → 02:33:36 pm.
|
|
1276
|
+
* @returns Formatted time string in local (System) time.
|
|
1277
|
+
*/
|
|
1278
|
+
static formatTimePart(time, format) {
|
|
1279
|
+
return new Chronos(`${new Chronos().#format("YYYY-MM-DD")}T${_normalizeOffset(time)}`).#format(format || "hh:mm:ss a");
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* @static Returns ISO date strings for each occurrence of a weekday.
|
|
1283
|
+
*
|
|
1284
|
+
* @param day - The weekday to match (e.g., `'Wednesday'`, `'Sunday'`).
|
|
1285
|
+
* @param options - Relative range (e.g., 7 days, 4 weeks) or date range (from/to) and output format.
|
|
1286
|
+
* @returns Array of ISO date strings in the specified format.
|
|
1287
|
+
*
|
|
1288
|
+
* - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/statics#getdatesforday docs} for details.
|
|
1289
|
+
*/
|
|
1290
|
+
static getDatesForDay(day, options) {
|
|
1291
|
+
let startDate = new Chronos(), endDate = startDate.addWeeks(4);
|
|
1292
|
+
const { format = "local", roundDate = false } = options ?? {};
|
|
1293
|
+
if (options) {
|
|
1294
|
+
if ("from" in options || "to" in options) {
|
|
1295
|
+
if (options?.from) startDate = Chronos.#cast(options?.from);
|
|
1296
|
+
if (options?.to) endDate = Chronos.#cast(options?.to);
|
|
1297
|
+
} else if ("span" in options || "unit" in options) {
|
|
1298
|
+
const { span = 4, unit = "week" } = options ?? {};
|
|
1299
|
+
endDate = startDate.add(span, unit);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
if (roundDate) {
|
|
1303
|
+
startDate = startDate.startOf("day");
|
|
1304
|
+
endDate = endDate.startOf("day");
|
|
1305
|
+
}
|
|
1306
|
+
const result = [];
|
|
1307
|
+
const step = (startDate.isBefore(endDate, "day") ? 1 : -1) * MS_PER_DAY;
|
|
1308
|
+
const totalDays = Math.abs(endDate.diff(startDate, "day"));
|
|
1309
|
+
const currentTime = startDate.#timestamp;
|
|
1310
|
+
let firstOffset = 0;
|
|
1311
|
+
while (new Date(currentTime + firstOffset * step).getDay() !== DAYS.indexOf(day)) firstOffset++;
|
|
1312
|
+
for (let i = firstOffset; i <= totalDays; i += 7) {
|
|
1313
|
+
const chr = new Chronos(currentTime + i * step).#withOrigin("clone", startDate.#offset, startDate.timeZoneName, startDate.timeZoneId, startDate.$tzTracker);
|
|
1314
|
+
result.push(format === "local" ? chr.toLocalISOString() : chr.toISOString());
|
|
1315
|
+
}
|
|
1316
|
+
return result;
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* @static Returns the earliest `Chronos` instance based on the underlying universal {@link timestamp}.
|
|
1320
|
+
*
|
|
1321
|
+
* @remarks
|
|
1322
|
+
* - All inputs are normalized to `Chronos` instances before comparison.
|
|
1323
|
+
* - Comparison is always performed using each instance's **UTC timestamp**, ensuring a consistent and timezone-agnostic result.
|
|
1324
|
+
* - When exactly two values are provided, the first value becomes the initial candidate; if the second value represents an earlier moment in time, it replaces the candidate.
|
|
1325
|
+
* - The returned value is **not** one of the input objects. A new immutable `Chronos` instance is always created. Its internal timezone, offset, name, and tracking information are cloned from the winning input instance.
|
|
1326
|
+
*
|
|
1327
|
+
* @param dates A list of Chronos-compatible inputs (`string`, `number`, `Date` or `Chronos`).
|
|
1328
|
+
* @returns A new `Chronos` instance representing the earliest moment.
|
|
1329
|
+
*/
|
|
1330
|
+
static min(...dates) {
|
|
1331
|
+
let winner = Chronos.#cast(dates[0]);
|
|
1332
|
+
for (const d of dates) {
|
|
1333
|
+
const c = Chronos.#cast(d);
|
|
1334
|
+
if (c.getTimeStamp() < winner.getTimeStamp()) winner = c;
|
|
1335
|
+
}
|
|
1336
|
+
return winner.#cloneStates(winner, winner.#ORIGIN !== "root" ? winner.#ORIGIN : "min");
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* @static Returns the latest `Chronos` instance based on the underlying universal {@link timestamp}.
|
|
1340
|
+
*
|
|
1341
|
+
* @remarks
|
|
1342
|
+
* - All inputs are normalized to `Chronos` instances before comparison.
|
|
1343
|
+
* - Comparison is always performed using each instance's **UTC timestamp**, ensuring a consistent and timezone-agnostic result.
|
|
1344
|
+
* - When exactly two values are provided, the first value becomes the initial candidate; if the second value represents a later moment in time, it replaces the candidate.
|
|
1345
|
+
* - The returned value is **not** one of the input objects. A new immutable `Chronos` instance is always created. Its internal timezone, offset, name, and tracking information are cloned from the winning input instance.
|
|
1346
|
+
*
|
|
1347
|
+
* @param dates A list of Chronos-compatible inputs (`string`, `number`, `Date` or `Chronos`).
|
|
1348
|
+
* @returns A new `Chronos` instance representing the latest moment.
|
|
1349
|
+
*/
|
|
1350
|
+
static max(...dates) {
|
|
1351
|
+
let winner = Chronos.#cast(dates[0]);
|
|
1352
|
+
for (const d of dates) {
|
|
1353
|
+
const c = Chronos.#cast(d);
|
|
1354
|
+
if (c.getTimeStamp() > winner.getTimeStamp()) winner = c;
|
|
1355
|
+
}
|
|
1356
|
+
return winner.#cloneStates(winner, winner.#ORIGIN !== "root" ? winner.#ORIGIN : "max");
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* @static Checks if the year in the date string or year (from 0 - 9999) is a leap year.
|
|
1360
|
+
* - A year is a leap year if it is divisible by 4, but not divisible by 100, unless it is also divisible by 400.
|
|
1361
|
+
* - For example, 2000 and 2400 are leap years, but 1900 and 2100 are not.
|
|
1362
|
+
*
|
|
1363
|
+
* @remarks
|
|
1364
|
+
* - This method accepts different types of date inputs and extracts the year to check if it's a leap year.
|
|
1365
|
+
* - If the provided date is a `number`, it will be treated as a year (must be a valid year from 0 to 9999).
|
|
1366
|
+
* - If the year is out of this range (negative or larger than 9999), it will be treated as a Unix timestamp.
|
|
1367
|
+
* - If the provided date is a string or a `Date` object, it will be parsed and the year will be extracted.
|
|
1368
|
+
* - If a `Chronos` instance is passed, the year will be directly accessed from the instance.
|
|
1369
|
+
*
|
|
1370
|
+
* @param date - A `number` (year or Unix timestamp), `string`, `Date`, or `Chronos` instance representing a date.
|
|
1371
|
+
* @returns `true` if the year is a leap year, `false` otherwise.
|
|
1372
|
+
*/
|
|
1373
|
+
static isLeapYear(date) {
|
|
1374
|
+
let year;
|
|
1375
|
+
if (isNumber(date)) if (date > 0 && date <= 9999) year = date;
|
|
1376
|
+
else year = new Date(date).getFullYear();
|
|
1377
|
+
else year = Chronos.#cast(date).year;
|
|
1378
|
+
return isLeapYear(year);
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* @static Checks if the given value is a valid `Date` object.
|
|
1382
|
+
* - A value is considered valid if it is an instance of the built-in `Date` class.
|
|
1383
|
+
* - This does not check whether the date itself is valid (e.g., `new Date('invalid')`).
|
|
1384
|
+
* @param value - The value to test.
|
|
1385
|
+
* @returns `true` if the value is a valid `Date` object, otherwise `false`.
|
|
1386
|
+
*/
|
|
1387
|
+
static isValidDate(value) {
|
|
1388
|
+
return value instanceof Date;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* @static Checks if the given value is a valid date string.
|
|
1392
|
+
* - A value is considered a valid date string if it is a string and can be parsed by `Date.parse()`.
|
|
1393
|
+
* - This uses the native JavaScript date parser internally.
|
|
1394
|
+
* @param value - The value to test.
|
|
1395
|
+
* @returns `true` if the value is a valid date string, otherwise `false`.
|
|
1396
|
+
*/
|
|
1397
|
+
static isDateString(value) {
|
|
1398
|
+
return isDateString(value);
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* @static Checks if the given value is an instance of `Chronos`.
|
|
1402
|
+
* - Useful for verifying `Chronos` objects in type guards or validations.
|
|
1403
|
+
* @param value - The value to test.
|
|
1404
|
+
* @returns `true` if the value is an instance of `Chronos`, otherwise `false`.
|
|
1405
|
+
*/
|
|
1406
|
+
static isValidChronos(value) {
|
|
1407
|
+
return value instanceof Chronos;
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* @static Checks if the given value has the necessary properties to be reconstructed into a `Chronos` instance.
|
|
1411
|
+
* - Can be used for validating objects that may represent serialized `Chronos` data.
|
|
1412
|
+
* @param value - The value to check.
|
|
1413
|
+
* @returns `true` if the value has the required properties for reconstruction, otherwise `false`.
|
|
1414
|
+
*/
|
|
1415
|
+
static isReconstructable(value) {
|
|
1416
|
+
return _hasChronosProperties(value);
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* @static Reconstructs a `Chronos` instance from an object containing the necessary properties.
|
|
1420
|
+
* - The input object must have the properties defined in {@link ChronosProperties} interface.
|
|
1421
|
+
* - If the input is not reconstructable, an error is thrown.
|
|
1422
|
+
*
|
|
1423
|
+
* @param value - An object containing the properties required to reconstruct a `Chronos` instance.
|
|
1424
|
+
* @returns A new `Chronos` instance created from the provided properties.
|
|
1425
|
+
* @throws `TypeError` if the input value does not have the necessary properties for reconstruction.
|
|
1426
|
+
*/
|
|
1427
|
+
static reconstruct(value) {
|
|
1428
|
+
if (!_hasChronosProperties(value)) throw new TypeError("Invalid input for reconstruction!");
|
|
1429
|
+
const { native, origin, utcOffset, timeZoneName, timeZoneId, $tzTracker } = value;
|
|
1430
|
+
const offsetMins = extractMinutesFromUTC(utcOffset);
|
|
1431
|
+
const chr = new Chronos(native);
|
|
1432
|
+
const diffMins = chr.getTimeZoneOffsetMinutes() - offsetMins;
|
|
1433
|
+
return (chr.utcOffset === utcOffset ? chr : chr.add(-diffMins, "minute")).#withOrigin(origin, utcOffset, timeZoneName, timeZoneId, $tzTracker);
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* @static Injects a plugin into the `Chronos` system.
|
|
1437
|
+
* @param plugin The plugin to inject.
|
|
1438
|
+
*
|
|
1439
|
+
* @remarks
|
|
1440
|
+
* - Using this (`use`) method in `React` projects may trigger *linter error* like `"React Hooks must be called in a React function component or a custom React Hook function."`
|
|
1441
|
+
* - To prevent this incorrect *linter error* in `React` projects, prefer using {@link register} method (alias `use` method).
|
|
1442
|
+
*
|
|
1443
|
+
* - **NOTE:** *Once a plugin is injected, all the registered methods for that plugin will be available for the whole project.*
|
|
1444
|
+
* - See {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/plugins#-official-plugins full list of plugins and the methods they register}.
|
|
1445
|
+
*/
|
|
1446
|
+
static use(plugin) {
|
|
1447
|
+
if (!Chronos.#plugins.has(plugin)) {
|
|
1448
|
+
Chronos.#plugins.add(plugin);
|
|
1449
|
+
plugin(Chronos);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
/**
|
|
1453
|
+
* @static Registers a plugin into the `Chronos` system.
|
|
1454
|
+
* @param plugin The plugin to register.
|
|
1455
|
+
*
|
|
1456
|
+
* @remarks
|
|
1457
|
+
* - This is just an alias for {@link use} method.
|
|
1458
|
+
* - Using {@link use} method in `React` projects may trigger *linter error* like `"React Hooks must be called in a React function component or a custom React Hook function."`
|
|
1459
|
+
* - To prevent this incorrect *linter error* in `React` projects, prefer using this (`register`) method over {@link use} method.
|
|
1460
|
+
*
|
|
1461
|
+
* - **NOTE:** *Once a plugin is injected, all the registered methods for that plugin will be available for the whole project.*
|
|
1462
|
+
* - See {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/plugins#-official-plugins full list of plugins and the methods they register}.
|
|
1463
|
+
*/
|
|
1464
|
+
static register(plugin) {
|
|
1465
|
+
Chronos.use(plugin);
|
|
1466
|
+
}
|
|
1467
|
+
/** @static Ensures the input is a `Chronos` instance, creating one if necessary. */
|
|
1468
|
+
static #cast(date) {
|
|
1469
|
+
return date instanceof Chronos ? date : new Chronos(date);
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
//#endregion
|
|
1474
|
+
export { Chronos, INTERNALS, chronos };
|