@fluixi/utils 1.0.0-alpha.82 → 1.0.0-alpha.84
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/index.cjs +2858 -1
- package/dist/index.mjs +2838 -1
- package/dist/lib/array/advanced.cjs +2227 -1
- package/dist/lib/array/advanced.mjs +2204 -1
- package/dist/lib/array/array.cjs +57 -1
- package/dist/lib/array/array.mjs +36 -1
- package/dist/lib/array/index.cjs +2344 -1
- package/dist/lib/array/index.mjs +2322 -1
- package/dist/lib/array/utils.cjs +103 -1
- package/dist/lib/array/utils.mjs +82 -1
- package/dist/lib/color/color.cjs +2190 -1
- package/dist/lib/color/color.mjs +2167 -1
- package/dist/lib/color/constants.cjs +380 -1
- package/dist/lib/color/constants.mjs +359 -1
- package/dist/lib/color/conversions.cjs +629 -1
- package/dist/lib/color/conversions.mjs +608 -1
- package/dist/lib/color/helpers.cjs +2534 -1
- package/dist/lib/color/helpers.mjs +2511 -1
- package/dist/lib/color/index.cjs +2641 -1
- package/dist/lib/color/index.mjs +2619 -1
- package/dist/lib/color/types.cjs +18 -1
- package/dist/lib/color/utils.cjs +962 -1
- package/dist/lib/color/utils.mjs +939 -1
- package/dist/lib/compare/comparators.cjs +171 -1
- package/dist/lib/compare/comparators.mjs +150 -1
- package/dist/lib/compare/index.cjs +172 -1
- package/dist/lib/compare/index.mjs +152 -1
- package/dist/lib/crypto/hash.cjs +83 -1
- package/dist/lib/crypto/hash.mjs +62 -1
- package/dist/lib/crypto/index.cjs +85 -1
- package/dist/lib/crypto/index.mjs +62 -1
- package/dist/lib/dom/events.cjs +40 -1
- package/dist/lib/dom/events.mjs +19 -1
- package/dist/lib/dom/index.cjs +78 -1
- package/dist/lib/dom/index.mjs +56 -1
- package/dist/lib/dom/utils.cjs +57 -1
- package/dist/lib/dom/utils.mjs +36 -1
- package/dist/lib/functions/functions.cjs +366 -1
- package/dist/lib/functions/functions.mjs +345 -1
- package/dist/lib/functions/index.cjs +369 -1
- package/dist/lib/functions/index.mjs +347 -1
- package/dist/lib/functions/types.cjs +18 -1
- package/dist/lib/helpers.cjs +78 -1
- package/dist/lib/helpers.mjs +59 -1
- package/dist/lib/index.cjs +2857 -1
- package/dist/lib/index.mjs +2836 -1
- package/dist/lib/maths/constants.cjs +70 -1
- package/dist/lib/maths/constants.mjs +50 -1
- package/dist/lib/maths/fn/advanced.cjs +231 -1
- package/dist/lib/maths/fn/advanced.mjs +208 -1
- package/dist/lib/maths/fn/basic.cjs +212 -1
- package/dist/lib/maths/fn/basic.mjs +191 -1
- package/dist/lib/maths/fn/complex.cjs +268 -1
- package/dist/lib/maths/fn/complex.mjs +247 -1
- package/dist/lib/maths/fn/index.cjs +877 -1
- package/dist/lib/maths/fn/index.mjs +855 -1
- package/dist/lib/maths/fn/trigo.cjs +179 -1
- package/dist/lib/maths/fn/trigo.mjs +156 -1
- package/dist/lib/maths/fn/vector.cjs +728 -1
- package/dist/lib/maths/fn/vector.mjs +707 -1
- package/dist/lib/maths/formatter.cjs +61 -1
- package/dist/lib/maths/formatter.mjs +40 -1
- package/dist/lib/maths/guards.cjs +164 -1
- package/dist/lib/maths/guards.mjs +144 -1
- package/dist/lib/maths/index.cjs +1152 -1
- package/dist/lib/maths/index.mjs +1130 -1
- package/dist/lib/maths/parser.cjs +75 -1
- package/dist/lib/maths/parser.mjs +54 -1
- package/dist/lib/maths/random.cjs +49 -1
- package/dist/lib/maths/random.mjs +28 -1
- package/dist/lib/maths/types/advanced.cjs +18 -1
- package/dist/lib/maths/types/basic.cjs +18 -1
- package/dist/lib/maths/types/index.cjs +19 -1
- package/dist/lib/maths/types/index.mjs +1 -0
- package/dist/lib/maths/types/negative.cjs +18 -1
- package/dist/lib/maths/types/operations.cjs +18 -1
- package/dist/lib/object/clone.cjs +88 -1
- package/dist/lib/object/clone.mjs +65 -1
- package/dist/lib/object/diff.cjs +573 -1
- package/dist/lib/object/diff.mjs +550 -1
- package/dist/lib/object/getter-setter.cjs +2351 -1
- package/dist/lib/object/getter-setter.mjs +2330 -1
- package/dist/lib/object/index.cjs +3956 -6
- package/dist/lib/object/index.mjs +3936 -6
- package/dist/lib/object/merge.cjs +1029 -1
- package/dist/lib/object/merge.mjs +1006 -1
- package/dist/lib/object/object.cjs +280 -1
- package/dist/lib/object/object.mjs +257 -1
- package/dist/lib/object/omit.cjs +2022 -1
- package/dist/lib/object/omit.mjs +1999 -1
- package/dist/lib/object/reconcile.cjs +126 -1
- package/dist/lib/object/reconcile.mjs +105 -1
- package/dist/lib/object/selector.cjs +303 -1
- package/dist/lib/object/selector.mjs +282 -1
- package/dist/lib/object/sort.cjs +209 -1
- package/dist/lib/object/sort.mjs +186 -1
- package/dist/lib/object/transform.cjs +2211 -1
- package/dist/lib/object/transform.mjs +2190 -1
- package/dist/lib/object/types.cjs +18 -1
- package/dist/lib/object/utils.cjs +326 -6
- package/dist/lib/object/utils.mjs +305 -6
- package/dist/lib/primitive/boolean/boolean.cjs +407 -1
- package/dist/lib/primitive/boolean/boolean.mjs +386 -1
- package/dist/lib/primitive/boolean/index.cjs +382 -1
- package/dist/lib/primitive/boolean/index.mjs +359 -1
- package/dist/lib/primitive/boolean/types.cjs +18 -1
- package/dist/lib/primitive/date/date.cjs +1126 -1
- package/dist/lib/primitive/date/date.mjs +1105 -1
- package/dist/lib/primitive/date/index.cjs +1128 -1
- package/dist/lib/primitive/date/index.mjs +1105 -1
- package/dist/lib/primitive/date/types.cjs +18 -1
- package/dist/lib/primitive/index.cjs +2338 -5
- package/dist/lib/primitive/index.mjs +2316 -5
- package/dist/lib/primitive/string/index.cjs +875 -5
- package/dist/lib/primitive/string/index.mjs +852 -5
- package/dist/lib/primitive/string/parser-2.cjs +543 -8
- package/dist/lib/primitive/string/parser-2.mjs +522 -8
- package/dist/lib/primitive/string/parser.cjs +236 -3
- package/dist/lib/primitive/string/parser.mjs +215 -3
- package/dist/lib/primitive/string/string.cjs +926 -5
- package/dist/lib/primitive/string/string.mjs +903 -5
- package/dist/lib/primitive/string/types.cjs +18 -1
- package/dist/lib/primitive/types.cjs +18 -1
- package/dist/lib/url/index.cjs +327 -1
- package/dist/lib/url/index.mjs +304 -1
- package/dist/lib/url/parser.cjs +325 -1
- package/dist/lib/url/parser.mjs +304 -1
- package/dist/lib/url/types.cjs +18 -1
- package/package.json +5 -5
|
@@ -1 +1,1128 @@
|
|
|
1
|
-
"use strict";var E=Object.defineProperty;var X=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var rt=(t,e)=>{for(var n in e)E(t,n,{get:e[n],enumerable:!0})},nt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of tt(e))!et.call(t,a)&&a!==n&&E(t,a,{get:()=>e[a],enumerable:!(r=X(e,a))||r.enumerable});return t};var at=t=>nt(E({},"__esModule",{value:!0}),t);var ae={};rt(ae,{add:()=>M,addBusinessDays:()=>Ht,addDays:()=>F,addMonths:()=>ht,addYears:()=>wt,configureDateUtils:()=>ot,convertTimezone:()=>U,createDate:()=>B,daysBetween:()=>Ut,difference:()=>j,endOf:()=>S,endOfDay:()=>Mt,endOfMonth:()=>yt,endOfWeek:()=>Tt,endOfYear:()=>$t,formatDate:()=>T,getAge:()=>_t,getDayName:()=>Pt,getDaysInMonth:()=>Wt,getMonthName:()=>zt,getQuarter:()=>Rt,getTimezoneInfo:()=>Bt,getWeekNumber:()=>At,humanizeDifference:()=>Ft,isAfter:()=>xt,isBefore:()=>kt,isBetween:()=>Yt,isBusinessDay:()=>K,isDate:()=>f,isFuture:()=>Z,isLeapYear:()=>Lt,isPast:()=>V,isSame:()=>N,isToday:()=>Ot,isWeekday:()=>Nt,isWeekend:()=>H,monthsBetween:()=>vt,now:()=>p,parseDate:()=>u,resetDateConfig:()=>st,startOf:()=>h,startOfDay:()=>y,startOfMonth:()=>St,startOfWeek:()=>Et,startOfYear:()=>It,subtract:()=>$,subtractDays:()=>J,subtractMonths:()=>bt,subtractYears:()=>pt,today:()=>I,tomorrow:()=>lt,validateDate:()=>qt,yearsBetween:()=>Ct,yesterday:()=>dt});module.exports=at(ae);var Y=1e3,k=60,x=60,O=24,b=7;var P=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],z=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],W=["January","February","March","April","May","June","July","August","September","October","November","December"],L=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],q={defaultTimezone:"UTC",defaultLocale:"en-US",weekStartsOn:0,businessDays:{businessDays:[1,2,3,4,5],holidays:[],holidayCheck:()=>!1,workStartHour:9,workEndHour:17}},D={...q};function ot(t){D={...D,...t,businessDays:{...D.businessDays,...t.businessDays||{}}}}function st(){D={...q}}function u(t,e={}){let{format:n="ISO",customFormat:r="",timezone:a=D.defaultTimezone,strict:o=!0,locale:s=D.defaultLocale}=e;if(t instanceof Date&&f(t))return t;let i=null;if(typeof t=="number"){if(i=new Date(t),!f(i))throw new Error(`Invalid timestamp: ${t}`);return _(i,a)}if(typeof t!="string")throw new Error(`Invalid input type: ${typeof t}`);let c=t.trim();if(!c)throw new Error("Empty date string");try{switch(n){case"ISO":case"ISO_DATE":case"ISO_TIME":i=it(c,n);break;case"US":i=ut(c);break;case"EU":i=ct(c);break;case"CUSTOM":i=mt(c,r);break;case"RFC_2822":i=ft(c);break;case"TIMESTAMP":i=Dt(c);break;default:i=gt(c,s,o)}if(!i||!f(i)){if(o)throw new Error(`Parsing resulted in invalid date from input: "${c}"`);if(i=new Date(c),!f(i))throw new Error(`Invalid date format: ${c}`)}if(a&&a!=="UTC"&&(i=U(i,a)),!i)throw new Error(`Invalid date format: ${c}`);return i}catch(l){if(o)throw new Error(`Failed to parse date "${c}" with format ${n}: ${l instanceof Error?l.message:String(l)}`);let m=new Date(c);if(f(m)){let d=_(m,a);if(!d)throw new Error(`Invalid date format: ${c}`);return d}throw new Error(`Invalid date format: ${c}`)}}function it(t,e){try{if(e==="ISO_DATE"){let r=t.split("-").map(i=>parseInt(i,10));if(r.length<3||r.some(isNaN))throw new Error("Invalid ISO date format");let[a,o,s]=r;return new Date(Date.UTC(a,o-1,s))}if(e==="ISO_TIME"){let a=new Date().toISOString().split("T")[0];return new Date(`${a}T${t}Z`)}let n=new Date(t);if(!f(n))throw new Error("Invalid ISO date");return n}catch{throw new Error(`Invalid ISO ${e} format: ${t}`)}}function ut(t){try{let e=t.split("/");if(e.length!==3)throw new Error("Invalid US date format - expected MM/DD/YYYY");let n=parseInt(e[0],10)-1,r=parseInt(e[1],10),a=parseInt(e[2],10);if(isNaN(n)||isNaN(r)||isNaN(a))throw new Error("Invalid US date format - non-numeric parts");if(a<100){let s=new Date().getFullYear(),i=Math.floor(s/100)*100;a+=a<50?i:i-100}if(n<0||n>11)throw new Error(`Month must be between 1 and 12, got ${n+1}`);let o=new Date(a,n,r);if(!f(o))throw new Error("Invalid date");if(o.getFullYear()!==a||o.getMonth()!==n||o.getDate()!==r)throw new Error("Invalid date");return o}catch(e){throw new Error(`Invalid US date format: ${t} - ${e instanceof Error?e.message:String(e)}`)}}function ct(t){try{let e=t.split("/");if(e.length!==3)throw new Error("Invalid EU date format - expected DD/MM/YYYY");let n=parseInt(e[0],10),r=parseInt(e[1],10)-1,a=parseInt(e[2],10);if(isNaN(n)||isNaN(r)||isNaN(a))throw new Error("Invalid EU date format - non-numeric parts");if(a<100){let s=new Date().getFullYear(),i=Math.floor(s/100)*100;a+=a<50?i:i-100}if(r<0||r>11)throw new Error(`Month must be between 1 and 12, got ${r+1}`);let o=new Date(a,r,n);if(!f(o))throw new Error("Invalid date");if(o.getFullYear()!==a||o.getMonth()!==r||o.getDate()!==n)throw new Error("Invalid date");return o}catch(e){throw new Error(`Invalid EU date format: ${t} - ${e instanceof Error?e.message:String(e)}`)}}function mt(t,e){try{if(!e)throw new Error("Custom format string is required");let n=e.replace(/YYYY/g,"(\\d{4})").replace(/YY/g,"(\\d{2})").replace(/MM/g,"(\\d{2})").replace(/M/g,"(\\d{1,2})").replace(/DD/g,"(\\d{2})").replace(/D/g,"(\\d{1,2})").replace(/HH/g,"(\\d{2})").replace(/H/g,"(\\d{1,2})").replace(/hh/g,"(\\d{2})").replace(/h/g,"(\\d{1,2})").replace(/mm/g,"(\\d{2})").replace(/m/g,"(\\d{1,2})").replace(/ss/g,"(\\d{2})").replace(/s/g,"(\\d{1,2})"),r=new RegExp(`^${n}$`),a=t.match(r);if(!a)throw new Error(`Input does not match custom format: ${e}`);let o=0,s=0,i=1,c=0,l=0,m=0,d=1,G=e.match(/YYYY|YY|MM|M|DD|D|HH|H|hh|h|mm|m|ss|s/g)||[];for(let v of G){let g=parseInt(a[d],10);if(isNaN(g))throw new Error(`Invalid numeric value for token ${v}`);switch(v){case"YYYY":o=g;break;case"YY":if(o=g,o<100){let Q=new Date().getFullYear(),C=Math.floor(Q/100)*100;o+=o<50?C:C-100}break;case"MM":case"M":s=g-1;break;case"DD":case"D":i=g;break;case"HH":case"H":c=g;break;case"hh":case"h":c=g;break;case"mm":case"m":l=g;break;case"ss":case"s":m=g;break}d++}if(o<1e3||o>9999)throw new Error(`Year must be between 1000 and 9999: ${o}`);if(s<0||s>11)throw new Error(`Month must be between 1 and 12: ${s+1}`);let w=new Date(o,s,i,c,l,m);if(!f(w))throw new Error("Invalid date");if(w.getFullYear()!==o||w.getMonth()!==s||w.getDate()!==i)throw new Error("Invalid date");return w}catch(n){throw new Error(`Failed to parse with custom format "${e}": ${n instanceof Error?n.message:String(n)}`)}}function ft(t){try{let e=new Date(t);if(!f(e))throw new Error("Invalid RFC 2822 date");return e}catch{throw new Error(`Invalid RFC 2822 date format: ${t}`)}}function Dt(t){try{if(!/^\d{8}(\d{6})?$/.test(t))throw new Error("Invalid timestamp format - expected YYYYMMDD or YYYYMMDDHHMMSS");let e=parseInt(t.substring(0,4),10),n=parseInt(t.substring(4,6),10)-1,r=parseInt(t.substring(6,8),10),a=0,o=0,s=0;if(t.length===14&&(a=parseInt(t.substring(8,10),10),o=parseInt(t.substring(10,12),10),s=parseInt(t.substring(12,14),10)),n<0||n>11)throw new Error(`Month must be between 1 and 12: ${n+1}`);let i=new Date(e,n,r,a,o,s);if(!f(i))throw new Error("Invalid timestamp");return i}catch(e){throw new Error(`Invalid timestamp format: ${t} - ${e instanceof Error?e.message:String(e)}`)}}function gt(t,e,n){try{let r=new Date(t);if(f(r))return r;let a=new Intl.DateTimeFormat(e,{year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric"}),o=new Date(t);if(f(o))return o;if(n)throw new Error(`Could not parse date with locale ${e}`);return new Date(NaN)}catch(r){if(n)throw new Error(`Failed to parse locale date: ${r instanceof Error?r.message:String(r)}`);return new Date(NaN)}}function _(t,e){return t}function f(t){if(!t||typeof t!="object")return!1;let e=t;if(typeof e.getTime!="function"||typeof e.getFullYear!="function")return!1;let n=e.getTime();return!isNaN(n)&&typeof n=="number"&&isFinite(n)}function T(t,e={}){let n=u(t),{format:r="ISO",customFormat:a="",timezone:o=D.defaultTimezone,locale:s=D.defaultLocale,includeTime:i=!0,includeSeconds:c=!1,includeMilliseconds:l=!1}=e,m=n;switch(o&&o!=="UTC"&&(m=U(n,o)),r){case"ISO":return m.toISOString();case"ISO_DATE":return m.toISOString().split("T")[0];case"ISO_TIME":{let d=m.toISOString().split("T")[1];return l?d:d.split(".")[0]}case"US":return Jt(m);case"EU":return Vt(m);case"FULL":return Zt(m,s);case"LONG":return jt(m,s);case"MEDIUM":return A(m,s);case"SHORT":return Kt(m,s);case"TIME":return R(m,s,c);case"TIME_24":return Gt(m,c);case"DATETIME":return`${A(m,s)}, ${R(m,s,c)}`;case"TIMESTAMP":return Qt(m);case"RFC_2822":return Xt(m);case"CUSTOM":return te(m,a);default:return m.toISOString()}}function p(){return new Date}function I(){return y(new Date)}function lt(){return F(I(),1)}function dt(){return J(I(),1)}function B(t,e,n,r=0,a=0,o=0,s=0){return ee(t,e,n,r,a,o,s),new Date(t,e,n,r,a,o,s)}function M(t,e,n="day"){let r=u(t),a=new Date(r);switch(n){case"millisecond":a.setMilliseconds(a.getMilliseconds()+e);break;case"second":a.setSeconds(a.getSeconds()+e);break;case"minute":a.setMinutes(a.getMinutes()+e);break;case"hour":a.setHours(a.getHours()+e);break;case"day":a.setDate(a.getDate()+e);break;case"week":a.setDate(a.getDate()+e*b);break;case"month":a.setMonth(a.getMonth()+e);break;case"quarter":a.setMonth(a.getMonth()+e*3);break;case"year":a.setFullYear(a.getFullYear()+e);break;default:throw new Error(`Unsupported date unit: ${n}`)}return a}function $(t,e,n="day"){return M(t,-e,n)}function F(t,e){return M(t,e,"day")}function J(t,e){return $(t,e,"day")}function ht(t,e){return M(t,e,"month")}function bt(t,e){return $(t,e,"month")}function wt(t,e){return M(t,e,"year")}function pt(t,e){return $(t,e,"year")}function h(t,e){let n=u(t),r=new Date(n);switch(e){case"year":r.setMonth(0,1),r.setHours(0,0,0,0);break;case"month":r.setDate(1),r.setHours(0,0,0,0);break;case"day":r.setHours(0,0,0,0);break;case"hour":r.setMinutes(0,0,0);break;case"minute":r.setSeconds(0,0);break;case"second":r.setMilliseconds(0);break;case"week":{let o=(r.getDay()-D.weekStartsOn+b)%b;r.setDate(r.getDate()-o),r.setHours(0,0,0,0);break}case"quarter":{let a=Math.floor(r.getMonth()/3);r.setMonth(a*3,1),r.setHours(0,0,0,0);break}default:throw new Error(`Unsupported unit for startOf: ${e}`)}return r}function S(t,e){let n=h(t,e),r=new Date(n);switch(e){case"year":r.setFullYear(r.getFullYear()+1);break;case"quarter":r.setMonth(r.getMonth()+3);break;case"month":r.setMonth(r.getMonth()+1);break;case"week":r.setDate(r.getDate()+b);break;case"day":r.setDate(r.getDate()+1);break;case"hour":r.setHours(r.getHours()+1);break;case"minute":r.setMinutes(r.getMinutes()+1);break;case"second":r.setSeconds(r.getSeconds()+1);break;default:throw new Error(`Unsupported unit for endOf: ${e}`)}return r.setMilliseconds(r.getMilliseconds()-1),r}function y(t){return h(t,"day")}function Mt(t){return S(t,"day")}function St(t){return h(t,"month")}function yt(t){return S(t,"month")}function It(t){return h(t,"year")}function $t(t){return S(t,"year")}function Et(t){return h(t,"week")}function Tt(t){return S(t,"week")}function Yt(t,e,n,r=!0){let a=u(t),o=u(e),s=u(n);return r?a>=o&&a<=s:a>o&&a<s}function kt(t,e){return u(t)<u(e)}function xt(t,e){return u(t)>u(e)}function N(t,e,n){let r=u(t),a=u(e);if(!n)return r.getTime()===a.getTime();let o=h(r,n),s=h(a,n);return o.getTime()===s.getTime()}function Ot(t){return N(t,I(),"day")}function V(t){return u(t)<p()}function Z(t){return u(t)>p()}function j(t,e){let n=u(t),r=u(e),a=Math.abs(r.getTime()-n.getTime()),o=Math.floor(a/Y),s=Math.floor(o/k),i=Math.floor(s/x),c=Math.floor(i/O);return{years:Math.floor(c/365),months:Math.floor(c/30),weeks:Math.floor(c/b),days:c,hours:i,minutes:s,seconds:o,milliseconds:a,totalDays:c,totalHours:i,totalMinutes:s,totalSeconds:o,totalMilliseconds:a}}function Ft(t,e=p(),n=!1){let r=j(t,e),o=u(t)<u(e)?"ago":"in";return r.years>0?n?`${r.years} year${r.years===1?"":"s"} ${o}`:`${r.years}y ${o}`:r.months>0?n?`${r.months} month${r.months===1?"":"s"} ${o}`:`${r.months}mo ${o}`:r.weeks>0?n?`${r.weeks} week${r.weeks===1?"":"s"} ${o}`:`${r.weeks}w ${o}`:r.days>0?n?`${r.days} day${r.days===1?"":"s"} ${o}`:`${r.days}d ${o}`:r.hours>0?n?`${r.hours} hour${r.hours===1?"":"s"} ${o}`:`${r.hours}h ${o}`:r.minutes>0?n?`${r.minutes} minute${r.minutes===1?"":"s"} ${o}`:`${r.minutes}m ${o}`:n?`${r.seconds} second${r.seconds===1?"":"s"} ${o}`:`${r.seconds}s ${o}`}function H(t){let n=u(t).getDay();return n===0||n===6}function Nt(t){return!H(t)}function K(t){let e=u(t);return H(e)||!D.businessDays.businessDays.includes(e.getDay())?!1:!(D.businessDays.holidays?.some(r=>N(r,e,"day"))||D.businessDays.holidayCheck?.(e))}function Ht(t,e){let n=u(t),r=0,a=e>0?1:-1;for(;r<Math.abs(e);)n=F(n,a),K(n)&&r++;return n}function Ut(t,e,n=!1){let r=y(u(t)),a=y(u(e)),o=Math.abs(a.getTime()-r.getTime()),s=Math.floor(o/(Y*k*x*O));return n?s+1:s}function vt(t,e){let n=u(t),r=u(e),a=r.getFullYear()-n.getFullYear(),o=r.getMonth()-n.getMonth();return a*12+o}function Ct(t,e){let n=u(t);return u(e).getFullYear()-n.getFullYear()}function _t(t,e=p()){let n=u(t),r=u(e),a=r.getFullYear()-n.getFullYear(),o=r.getMonth()-n.getMonth();return(o<0||o===0&&r.getDate()<n.getDate())&&a--,Math.max(0,a)}function At(t){let e=u(t),n=new Date(e.getFullYear(),0,1),r=(e.getTime()-n.getTime())/(Y*k*x*O);return Math.ceil((r+n.getDay()+1)/b)}function Rt(t){let e=u(t).getMonth();return Math.floor(e/3)+1}function Pt(t,e="full"){let r=u(t).getDay();return e==="full"?P[r]:z[r]}function zt(t,e="full"){let r=u(t).getMonth();return e==="full"?W[r]:L[r]}function Wt(t){let e=u(t);return new Date(e.getFullYear(),e.getMonth()+1,0).getDate()}function Lt(t){return t%4===0&&t%100!==0||t%400===0}function qt(t,e={}){let n=[];try{let r=u(t);if(e.required&&!r&&n.push("Date is required"),e.min||e.minDate){let a=u(e.min||e.minDate);r<a&&n.push(`Date must be on or after ${T(a,{format:"MEDIUM"})}`)}if(e.max||e.maxDate){let a=u(e.max||e.maxDate);r>a&&n.push(`Date must be on or before ${T(a,{format:"MEDIUM"})}`)}e.allowPast===!1&&V(r)&&n.push("Date must be in the future"),e.allowFuture===!1&&Z(r)&&n.push("Date must be in the past")}catch(r){n.push(r instanceof Error?r.message:"Invalid date")}return{isValid:n.length===0,errors:n}}function Bt(t){let e=u(t),n=Intl.DateTimeFormat().resolvedOptions().timeZone,r=-e.getTimezoneOffset(),a=Math.floor(Math.abs(r)/60),o=Math.abs(r)%60,s=r>=0?"+":"-";return{abbreviation:re(e),name:n,offset:r,offsetString:`UTC${s}${String(a).padStart(2,"0")}:${String(o).padStart(2,"0")}`,isDST:ne(e)}}function U(t,e){let n=u(t);if(e==="UTC")return new Date(n.getTime()+n.getTimezoneOffset()*6e4);let a=new Intl.DateTimeFormat("en-US",{timeZone:e,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric"}).formatToParts(n),o=s=>a.find(i=>i.type===s)?.value;return B(parseInt(o("year")),parseInt(o("month"))-1,parseInt(o("day")),parseInt(o("hour")),parseInt(o("minute")),parseInt(o("second")))}function Jt(t){let e=(t.getMonth()+1).toString().padStart(2,"0"),n=t.getDate().toString().padStart(2,"0"),r=t.getFullYear();return`${e}/${n}/${r}`}function Vt(t){let e=t.getDate().toString().padStart(2,"0"),n=(t.getMonth()+1).toString().padStart(2,"0"),r=t.getFullYear();return`${e}/${n}/${r}`}function Zt(t,e){return new Intl.DateTimeFormat(e,{weekday:"long",year:"numeric",month:"long",day:"numeric"}).format(t)}function jt(t,e){return new Intl.DateTimeFormat(e,{year:"numeric",month:"long",day:"numeric"}).format(t)}function A(t,e){return new Intl.DateTimeFormat(e,{year:"numeric",month:"short",day:"numeric"}).format(t)}function Kt(t,e){return new Intl.DateTimeFormat(e,{year:"2-digit",month:"numeric",day:"numeric"}).format(t)}function R(t,e,n){return new Intl.DateTimeFormat(e,{hour:"numeric",minute:"2-digit",second:n?"2-digit":void 0,hour12:!0}).format(t)}function Gt(t,e){let n=t.getHours().toString().padStart(2,"0"),r=t.getMinutes().toString().padStart(2,"0"),a=e?`:${t.getSeconds().toString().padStart(2,"0")}`:"";return`${n}:${r}${a}`}function Qt(t){let e=t.getFullYear(),n=(t.getMonth()+1).toString().padStart(2,"0"),r=t.getDate().toString().padStart(2,"0"),a=t.getHours().toString().padStart(2,"0"),o=t.getMinutes().toString().padStart(2,"0"),s=t.getSeconds().toString().padStart(2,"0");return`${e}${n}${r}${a}${o}${s}`}function Xt(t){return t.toUTCString()}function te(t,e){let n={YYYY:t.getFullYear().toString(),YY:t.getFullYear().toString().slice(-2),MMMM:W[t.getMonth()],MMM:L[t.getMonth()],MM:(t.getMonth()+1).toString().padStart(2,"0"),M:(t.getMonth()+1).toString(),DDDD:P[t.getDay()],DDD:z[t.getDay()],DD:t.getDate().toString().padStart(2,"0"),D:t.getDate().toString(),HH:t.getHours().toString().padStart(2,"0"),H:t.getHours().toString(),hh:(t.getHours()%12||12).toString().padStart(2,"0"),h:(t.getHours()%12||12).toString(),mm:t.getMinutes().toString().padStart(2,"0"),m:t.getMinutes().toString(),ss:t.getSeconds().toString().padStart(2,"0"),s:t.getSeconds().toString(),SSS:t.getMilliseconds().toString().padStart(3,"0"),A:t.getHours()<12?"AM":"PM",a:t.getHours()<12?"am":"pm"};return e.replace(/YYYY|YY|MMMM|MMM|MM|M|DDDD|DDD|DD|D|HH|H|hh|h|mm|m|ss|s|SSS|A|a/g,r=>n[r]||r)}function ee(t,e,n,r=0,a=0,o=0,s=0){if(t<1e3||t>9999)throw new Error(`Year must be between 1000 and 9999: ${t}`);if(e<0||e>11)throw new Error(`Month must be between 0 and 11: ${e}`);let i=new Date(t,e+1,0).getDate();if(n<1||n>i)throw new Error(`Day must be between 1 and ${i} for month ${e}: ${n}`);if(r<0||r>23)throw new Error(`Hour must be between 0 and 23: ${r}`);if(a<0||a>59)throw new Error(`Minute must be between 0 and 59: ${a}`);if(o<0||o>59)throw new Error(`Second must be between 0 and 59: ${o}`);if(s<0||s>999)throw new Error(`Millisecond must be between 0 and 999: ${s}`)}function re(t){let r=new Intl.DateTimeFormat("en-US",{timeZoneName:"short"}).formatToParts(t).find(a=>a.type==="timeZoneName");return r?r.value:"UTC"}function ne(t){let e=new Date(t.getFullYear(),0,1),n=new Date(t.getFullYear(),6,1),r=Math.max(e.getTimezoneOffset(),n.getTimezoneOffset());return t.getTimezoneOffset()<r}
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/primitive/date/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
add: () => add,
|
|
24
|
+
addBusinessDays: () => addBusinessDays,
|
|
25
|
+
addDays: () => addDays,
|
|
26
|
+
addMonths: () => addMonths,
|
|
27
|
+
addYears: () => addYears,
|
|
28
|
+
configureDateUtils: () => configureDateUtils,
|
|
29
|
+
convertTimezone: () => convertTimezone,
|
|
30
|
+
createDate: () => createDate,
|
|
31
|
+
daysBetween: () => daysBetween,
|
|
32
|
+
difference: () => difference,
|
|
33
|
+
endOf: () => endOf,
|
|
34
|
+
endOfDay: () => endOfDay,
|
|
35
|
+
endOfMonth: () => endOfMonth,
|
|
36
|
+
endOfWeek: () => endOfWeek,
|
|
37
|
+
endOfYear: () => endOfYear,
|
|
38
|
+
formatDate: () => formatDate,
|
|
39
|
+
getAge: () => getAge,
|
|
40
|
+
getDayName: () => getDayName,
|
|
41
|
+
getDaysInMonth: () => getDaysInMonth,
|
|
42
|
+
getMonthName: () => getMonthName,
|
|
43
|
+
getQuarter: () => getQuarter,
|
|
44
|
+
getTimezoneInfo: () => getTimezoneInfo,
|
|
45
|
+
getWeekNumber: () => getWeekNumber,
|
|
46
|
+
humanizeDifference: () => humanizeDifference,
|
|
47
|
+
isAfter: () => isAfter,
|
|
48
|
+
isBefore: () => isBefore,
|
|
49
|
+
isBetween: () => isBetween,
|
|
50
|
+
isBusinessDay: () => isBusinessDay,
|
|
51
|
+
isDate: () => isDate,
|
|
52
|
+
isFuture: () => isFuture,
|
|
53
|
+
isLeapYear: () => isLeapYear,
|
|
54
|
+
isPast: () => isPast,
|
|
55
|
+
isSame: () => isSame,
|
|
56
|
+
isToday: () => isToday,
|
|
57
|
+
isWeekday: () => isWeekday,
|
|
58
|
+
isWeekend: () => isWeekend,
|
|
59
|
+
monthsBetween: () => monthsBetween,
|
|
60
|
+
now: () => now,
|
|
61
|
+
parseDate: () => parseDate,
|
|
62
|
+
resetDateConfig: () => resetDateConfig,
|
|
63
|
+
startOf: () => startOf,
|
|
64
|
+
startOfDay: () => startOfDay,
|
|
65
|
+
startOfMonth: () => startOfMonth,
|
|
66
|
+
startOfWeek: () => startOfWeek,
|
|
67
|
+
startOfYear: () => startOfYear,
|
|
68
|
+
subtract: () => subtract,
|
|
69
|
+
subtractDays: () => subtractDays,
|
|
70
|
+
subtractMonths: () => subtractMonths,
|
|
71
|
+
subtractYears: () => subtractYears,
|
|
72
|
+
today: () => today,
|
|
73
|
+
tomorrow: () => tomorrow,
|
|
74
|
+
validateDate: () => validateDate,
|
|
75
|
+
yearsBetween: () => yearsBetween,
|
|
76
|
+
yesterday: () => yesterday
|
|
77
|
+
});
|
|
78
|
+
module.exports = __toCommonJS(index_exports);
|
|
79
|
+
|
|
80
|
+
// src/lib/primitive/date/date.ts
|
|
81
|
+
var MILLISECONDS_IN_SECOND = 1e3;
|
|
82
|
+
var SECONDS_IN_MINUTE = 60;
|
|
83
|
+
var MINUTES_IN_HOUR = 60;
|
|
84
|
+
var HOURS_IN_DAY = 24;
|
|
85
|
+
var DAYS_IN_WEEK = 7;
|
|
86
|
+
var WEEKDAY_NAMES = [
|
|
87
|
+
"Sunday",
|
|
88
|
+
"Monday",
|
|
89
|
+
"Tuesday",
|
|
90
|
+
"Wednesday",
|
|
91
|
+
"Thursday",
|
|
92
|
+
"Friday",
|
|
93
|
+
"Saturday"
|
|
94
|
+
];
|
|
95
|
+
var WEEKDAY_NAMES_SHORT = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
96
|
+
var MONTH_NAMES = [
|
|
97
|
+
"January",
|
|
98
|
+
"February",
|
|
99
|
+
"March",
|
|
100
|
+
"April",
|
|
101
|
+
"May",
|
|
102
|
+
"June",
|
|
103
|
+
"July",
|
|
104
|
+
"August",
|
|
105
|
+
"September",
|
|
106
|
+
"October",
|
|
107
|
+
"November",
|
|
108
|
+
"December"
|
|
109
|
+
];
|
|
110
|
+
var MONTH_NAMES_SHORT = [
|
|
111
|
+
"Jan",
|
|
112
|
+
"Feb",
|
|
113
|
+
"Mar",
|
|
114
|
+
"Apr",
|
|
115
|
+
"May",
|
|
116
|
+
"Jun",
|
|
117
|
+
"Jul",
|
|
118
|
+
"Aug",
|
|
119
|
+
"Sep",
|
|
120
|
+
"Oct",
|
|
121
|
+
"Nov",
|
|
122
|
+
"Dec"
|
|
123
|
+
];
|
|
124
|
+
var DEFAULT_CONFIG = {
|
|
125
|
+
defaultTimezone: "UTC",
|
|
126
|
+
defaultLocale: "en-US",
|
|
127
|
+
weekStartsOn: 0,
|
|
128
|
+
// Sunday
|
|
129
|
+
businessDays: {
|
|
130
|
+
businessDays: [1, 2, 3, 4, 5],
|
|
131
|
+
// Monday to Friday
|
|
132
|
+
holidays: [],
|
|
133
|
+
holidayCheck: () => false,
|
|
134
|
+
workStartHour: 9,
|
|
135
|
+
workEndHour: 17
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
var config = { ...DEFAULT_CONFIG };
|
|
139
|
+
function configureDateUtils(newConfig) {
|
|
140
|
+
config = {
|
|
141
|
+
...config,
|
|
142
|
+
...newConfig,
|
|
143
|
+
businessDays: {
|
|
144
|
+
...config.businessDays,
|
|
145
|
+
...newConfig.businessDays || {}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function resetDateConfig() {
|
|
150
|
+
config = { ...DEFAULT_CONFIG };
|
|
151
|
+
}
|
|
152
|
+
function parseDate(input, options = {}) {
|
|
153
|
+
const {
|
|
154
|
+
format = "ISO",
|
|
155
|
+
customFormat = "",
|
|
156
|
+
timezone = config.defaultTimezone,
|
|
157
|
+
strict = true,
|
|
158
|
+
locale = config.defaultLocale
|
|
159
|
+
} = options;
|
|
160
|
+
if (input instanceof Date && isDate(input)) {
|
|
161
|
+
return input;
|
|
162
|
+
}
|
|
163
|
+
let parsedDate = null;
|
|
164
|
+
if (typeof input === "number") {
|
|
165
|
+
parsedDate = new Date(input);
|
|
166
|
+
if (!isDate(parsedDate)) {
|
|
167
|
+
throw new Error(`Invalid timestamp: ${input}`);
|
|
168
|
+
}
|
|
169
|
+
return applyTimezone(parsedDate, timezone);
|
|
170
|
+
}
|
|
171
|
+
if (typeof input !== "string") {
|
|
172
|
+
throw new Error(`Invalid input type: ${typeof input}`);
|
|
173
|
+
}
|
|
174
|
+
const trimmedInput = input.trim();
|
|
175
|
+
if (!trimmedInput) {
|
|
176
|
+
throw new Error("Empty date string");
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
switch (format) {
|
|
180
|
+
case "ISO":
|
|
181
|
+
case "ISO_DATE":
|
|
182
|
+
case "ISO_TIME":
|
|
183
|
+
parsedDate = parseISODate(trimmedInput, format);
|
|
184
|
+
break;
|
|
185
|
+
case "US":
|
|
186
|
+
parsedDate = parseUSDate(trimmedInput);
|
|
187
|
+
break;
|
|
188
|
+
case "EU":
|
|
189
|
+
parsedDate = parseEUDate(trimmedInput);
|
|
190
|
+
break;
|
|
191
|
+
case "CUSTOM":
|
|
192
|
+
parsedDate = parseCustomDate(trimmedInput, customFormat);
|
|
193
|
+
break;
|
|
194
|
+
case "RFC_2822":
|
|
195
|
+
parsedDate = parseRFC2822Date(trimmedInput);
|
|
196
|
+
break;
|
|
197
|
+
case "TIMESTAMP":
|
|
198
|
+
parsedDate = parseTimestamp(trimmedInput);
|
|
199
|
+
break;
|
|
200
|
+
default:
|
|
201
|
+
parsedDate = parseLocaleDate(trimmedInput, locale, strict);
|
|
202
|
+
}
|
|
203
|
+
if (!parsedDate || !isDate(parsedDate)) {
|
|
204
|
+
if (strict) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Parsing resulted in invalid date from input: "${trimmedInput}"`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
parsedDate = new Date(trimmedInput);
|
|
210
|
+
if (!isDate(parsedDate)) {
|
|
211
|
+
throw new Error(`Invalid date format: ${trimmedInput}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (timezone && timezone !== "UTC") {
|
|
215
|
+
parsedDate = convertTimezone(parsedDate, timezone);
|
|
216
|
+
}
|
|
217
|
+
if (!parsedDate) {
|
|
218
|
+
throw new Error(`Invalid date format: ${trimmedInput}`);
|
|
219
|
+
}
|
|
220
|
+
return parsedDate;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (strict) {
|
|
223
|
+
throw new Error(
|
|
224
|
+
`Failed to parse date "${trimmedInput}" with format ${format}: ${error instanceof Error ? error.message : String(error)}`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
const fallbackDate = new Date(trimmedInput);
|
|
228
|
+
if (isDate(fallbackDate)) {
|
|
229
|
+
const t = applyTimezone(fallbackDate, timezone);
|
|
230
|
+
if (!t) {
|
|
231
|
+
throw new Error(`Invalid date format: ${trimmedInput}`);
|
|
232
|
+
}
|
|
233
|
+
return t;
|
|
234
|
+
}
|
|
235
|
+
throw new Error(`Invalid date format: ${trimmedInput}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function parseISODate(input, format) {
|
|
239
|
+
try {
|
|
240
|
+
if (format === "ISO_DATE") {
|
|
241
|
+
const parts = input.split("-").map((part) => parseInt(part, 10));
|
|
242
|
+
if (parts.length < 3 || parts.some(isNaN)) {
|
|
243
|
+
throw new Error("Invalid ISO date format");
|
|
244
|
+
}
|
|
245
|
+
const [year, month, day] = parts;
|
|
246
|
+
return new Date(Date.UTC(year, month - 1, day));
|
|
247
|
+
}
|
|
248
|
+
if (format === "ISO_TIME") {
|
|
249
|
+
const today2 = /* @__PURE__ */ new Date();
|
|
250
|
+
const datePart = today2.toISOString().split("T")[0];
|
|
251
|
+
return /* @__PURE__ */ new Date(`${datePart}T${input}Z`);
|
|
252
|
+
}
|
|
253
|
+
const date = new Date(input);
|
|
254
|
+
if (!isDate(date)) {
|
|
255
|
+
throw new Error("Invalid ISO date");
|
|
256
|
+
}
|
|
257
|
+
return date;
|
|
258
|
+
} catch {
|
|
259
|
+
throw new Error(`Invalid ISO ${format} format: ${input}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function parseUSDate(input) {
|
|
263
|
+
try {
|
|
264
|
+
const parts = input.split("/");
|
|
265
|
+
if (parts.length !== 3) {
|
|
266
|
+
throw new Error("Invalid US date format - expected MM/DD/YYYY");
|
|
267
|
+
}
|
|
268
|
+
let month = parseInt(parts[0], 10) - 1;
|
|
269
|
+
let day = parseInt(parts[1], 10);
|
|
270
|
+
let year = parseInt(parts[2], 10);
|
|
271
|
+
if (isNaN(month) || isNaN(day) || isNaN(year)) {
|
|
272
|
+
throw new Error("Invalid US date format - non-numeric parts");
|
|
273
|
+
}
|
|
274
|
+
if (year < 100) {
|
|
275
|
+
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
276
|
+
const century = Math.floor(currentYear / 100) * 100;
|
|
277
|
+
year += year < 50 ? century : century - 100;
|
|
278
|
+
}
|
|
279
|
+
if (month < 0 || month > 11) {
|
|
280
|
+
throw new Error(`Month must be between 1 and 12, got ${month + 1}`);
|
|
281
|
+
}
|
|
282
|
+
const date = new Date(year, month, day);
|
|
283
|
+
if (!isDate(date)) {
|
|
284
|
+
throw new Error("Invalid date");
|
|
285
|
+
}
|
|
286
|
+
if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
|
|
287
|
+
throw new Error("Invalid date");
|
|
288
|
+
}
|
|
289
|
+
return date;
|
|
290
|
+
} catch (error) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`Invalid US date format: ${input} - ${error instanceof Error ? error.message : String(error)}`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function parseEUDate(input) {
|
|
297
|
+
try {
|
|
298
|
+
const parts = input.split("/");
|
|
299
|
+
if (parts.length !== 3) {
|
|
300
|
+
throw new Error("Invalid EU date format - expected DD/MM/YYYY");
|
|
301
|
+
}
|
|
302
|
+
let day = parseInt(parts[0], 10);
|
|
303
|
+
let month = parseInt(parts[1], 10) - 1;
|
|
304
|
+
let year = parseInt(parts[2], 10);
|
|
305
|
+
if (isNaN(day) || isNaN(month) || isNaN(year)) {
|
|
306
|
+
throw new Error("Invalid EU date format - non-numeric parts");
|
|
307
|
+
}
|
|
308
|
+
if (year < 100) {
|
|
309
|
+
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
310
|
+
const century = Math.floor(currentYear / 100) * 100;
|
|
311
|
+
year += year < 50 ? century : century - 100;
|
|
312
|
+
}
|
|
313
|
+
if (month < 0 || month > 11) {
|
|
314
|
+
throw new Error(`Month must be between 1 and 12, got ${month + 1}`);
|
|
315
|
+
}
|
|
316
|
+
const date = new Date(year, month, day);
|
|
317
|
+
if (!isDate(date)) {
|
|
318
|
+
throw new Error("Invalid date");
|
|
319
|
+
}
|
|
320
|
+
if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
|
|
321
|
+
throw new Error("Invalid date");
|
|
322
|
+
}
|
|
323
|
+
return date;
|
|
324
|
+
} catch (error) {
|
|
325
|
+
throw new Error(
|
|
326
|
+
`Invalid EU date format: ${input} - ${error instanceof Error ? error.message : String(error)}`
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function parseCustomDate(input, format) {
|
|
331
|
+
try {
|
|
332
|
+
if (!format) {
|
|
333
|
+
throw new Error("Custom format string is required");
|
|
334
|
+
}
|
|
335
|
+
const formatPattern = format.replace(/YYYY/g, "(\\d{4})").replace(/YY/g, "(\\d{2})").replace(/MM/g, "(\\d{2})").replace(/M/g, "(\\d{1,2})").replace(/DD/g, "(\\d{2})").replace(/D/g, "(\\d{1,2})").replace(/HH/g, "(\\d{2})").replace(/H/g, "(\\d{1,2})").replace(/hh/g, "(\\d{2})").replace(/h/g, "(\\d{1,2})").replace(/mm/g, "(\\d{2})").replace(/m/g, "(\\d{1,2})").replace(/ss/g, "(\\d{2})").replace(/s/g, "(\\d{1,2})");
|
|
336
|
+
const regex = new RegExp(`^${formatPattern}$`);
|
|
337
|
+
const match = input.match(regex);
|
|
338
|
+
if (!match) {
|
|
339
|
+
throw new Error(`Input does not match custom format: ${format}`);
|
|
340
|
+
}
|
|
341
|
+
let year = 0, month = 0, day = 1, hour = 0, minute = 0, second = 0;
|
|
342
|
+
let matchIndex = 1;
|
|
343
|
+
const formatTokens = format.match(/YYYY|YY|MM|M|DD|D|HH|H|hh|h|mm|m|ss|s/g) || [];
|
|
344
|
+
for (const token of formatTokens) {
|
|
345
|
+
const value = parseInt(match[matchIndex], 10);
|
|
346
|
+
if (isNaN(value)) {
|
|
347
|
+
throw new Error(`Invalid numeric value for token ${token}`);
|
|
348
|
+
}
|
|
349
|
+
switch (token) {
|
|
350
|
+
case "YYYY":
|
|
351
|
+
year = value;
|
|
352
|
+
break;
|
|
353
|
+
case "YY":
|
|
354
|
+
year = value;
|
|
355
|
+
if (year < 100) {
|
|
356
|
+
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
357
|
+
const century = Math.floor(currentYear / 100) * 100;
|
|
358
|
+
year += year < 50 ? century : century - 100;
|
|
359
|
+
}
|
|
360
|
+
break;
|
|
361
|
+
case "MM":
|
|
362
|
+
case "M":
|
|
363
|
+
month = value - 1;
|
|
364
|
+
break;
|
|
365
|
+
case "DD":
|
|
366
|
+
case "D":
|
|
367
|
+
day = value;
|
|
368
|
+
break;
|
|
369
|
+
case "HH":
|
|
370
|
+
case "H":
|
|
371
|
+
hour = value;
|
|
372
|
+
break;
|
|
373
|
+
case "hh":
|
|
374
|
+
case "h":
|
|
375
|
+
hour = value;
|
|
376
|
+
break;
|
|
377
|
+
case "mm":
|
|
378
|
+
case "m":
|
|
379
|
+
minute = value;
|
|
380
|
+
break;
|
|
381
|
+
case "ss":
|
|
382
|
+
case "s":
|
|
383
|
+
second = value;
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
matchIndex++;
|
|
387
|
+
}
|
|
388
|
+
if (year < 1e3 || year > 9999) {
|
|
389
|
+
throw new Error(`Year must be between 1000 and 9999: ${year}`);
|
|
390
|
+
}
|
|
391
|
+
if (month < 0 || month > 11) {
|
|
392
|
+
throw new Error(`Month must be between 1 and 12: ${month + 1}`);
|
|
393
|
+
}
|
|
394
|
+
const date = new Date(year, month, day, hour, minute, second);
|
|
395
|
+
if (!isDate(date)) {
|
|
396
|
+
throw new Error("Invalid date");
|
|
397
|
+
}
|
|
398
|
+
if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {
|
|
399
|
+
throw new Error("Invalid date");
|
|
400
|
+
}
|
|
401
|
+
return date;
|
|
402
|
+
} catch (error) {
|
|
403
|
+
throw new Error(
|
|
404
|
+
`Failed to parse with custom format "${format}": ${error instanceof Error ? error.message : String(error)}`
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function parseRFC2822Date(input) {
|
|
409
|
+
try {
|
|
410
|
+
const date = new Date(input);
|
|
411
|
+
if (!isDate(date)) {
|
|
412
|
+
throw new Error("Invalid RFC 2822 date");
|
|
413
|
+
}
|
|
414
|
+
return date;
|
|
415
|
+
} catch {
|
|
416
|
+
throw new Error(`Invalid RFC 2822 date format: ${input}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function parseTimestamp(input) {
|
|
420
|
+
try {
|
|
421
|
+
if (!/^\d{8}(\d{6})?$/.test(input)) {
|
|
422
|
+
throw new Error(
|
|
423
|
+
"Invalid timestamp format - expected YYYYMMDD or YYYYMMDDHHMMSS"
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
const year = parseInt(input.substring(0, 4), 10);
|
|
427
|
+
const month = parseInt(input.substring(4, 6), 10) - 1;
|
|
428
|
+
const day = parseInt(input.substring(6, 8), 10);
|
|
429
|
+
let hour = 0, minute = 0, second = 0;
|
|
430
|
+
if (input.length === 14) {
|
|
431
|
+
hour = parseInt(input.substring(8, 10), 10);
|
|
432
|
+
minute = parseInt(input.substring(10, 12), 10);
|
|
433
|
+
second = parseInt(input.substring(12, 14), 10);
|
|
434
|
+
}
|
|
435
|
+
if (month < 0 || month > 11) {
|
|
436
|
+
throw new Error(`Month must be between 1 and 12: ${month + 1}`);
|
|
437
|
+
}
|
|
438
|
+
const date = new Date(year, month, day, hour, minute, second);
|
|
439
|
+
if (!isDate(date)) {
|
|
440
|
+
throw new Error("Invalid timestamp");
|
|
441
|
+
}
|
|
442
|
+
return date;
|
|
443
|
+
} catch (error) {
|
|
444
|
+
throw new Error(
|
|
445
|
+
`Invalid timestamp format: ${input} - ${error instanceof Error ? error.message : String(error)}`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
function parseLocaleDate(input, locale, strict) {
|
|
450
|
+
try {
|
|
451
|
+
const date = new Date(input);
|
|
452
|
+
if (isDate(date)) {
|
|
453
|
+
return date;
|
|
454
|
+
}
|
|
455
|
+
const formatter = new Intl.DateTimeFormat(locale, {
|
|
456
|
+
year: "numeric",
|
|
457
|
+
month: "numeric",
|
|
458
|
+
day: "numeric",
|
|
459
|
+
hour: "numeric",
|
|
460
|
+
minute: "numeric",
|
|
461
|
+
second: "numeric"
|
|
462
|
+
});
|
|
463
|
+
const fallback = new Date(input);
|
|
464
|
+
if (isDate(fallback)) {
|
|
465
|
+
return fallback;
|
|
466
|
+
}
|
|
467
|
+
if (strict) {
|
|
468
|
+
throw new Error(`Could not parse date with locale ${locale}`);
|
|
469
|
+
}
|
|
470
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
471
|
+
} catch (error) {
|
|
472
|
+
if (strict) {
|
|
473
|
+
throw new Error(
|
|
474
|
+
`Failed to parse locale date: ${error instanceof Error ? error.message : String(error)}`
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function applyTimezone(date, timezone) {
|
|
481
|
+
if (!timezone || timezone === "UTC") {
|
|
482
|
+
return date;
|
|
483
|
+
}
|
|
484
|
+
return date;
|
|
485
|
+
}
|
|
486
|
+
function isDate(date) {
|
|
487
|
+
if (!date || typeof date !== "object") {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
const d = date;
|
|
491
|
+
if (typeof d.getTime !== "function" || typeof d.getFullYear !== "function") {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
const time = d.getTime();
|
|
495
|
+
return !isNaN(time) && typeof time === "number" && isFinite(time);
|
|
496
|
+
}
|
|
497
|
+
function formatDate(date, options = {}) {
|
|
498
|
+
const parsedDate = parseDate(date);
|
|
499
|
+
const {
|
|
500
|
+
format = "ISO",
|
|
501
|
+
customFormat = "",
|
|
502
|
+
timezone = config.defaultTimezone,
|
|
503
|
+
locale = config.defaultLocale,
|
|
504
|
+
includeTime = true,
|
|
505
|
+
includeSeconds = false,
|
|
506
|
+
includeMilliseconds = false
|
|
507
|
+
} = options;
|
|
508
|
+
let targetDate = parsedDate;
|
|
509
|
+
if (timezone && timezone !== "UTC") {
|
|
510
|
+
targetDate = convertTimezone(parsedDate, timezone);
|
|
511
|
+
}
|
|
512
|
+
switch (format) {
|
|
513
|
+
case "ISO":
|
|
514
|
+
return targetDate.toISOString();
|
|
515
|
+
case "ISO_DATE":
|
|
516
|
+
return targetDate.toISOString().split("T")[0];
|
|
517
|
+
case "ISO_TIME": {
|
|
518
|
+
const timePart = targetDate.toISOString().split("T")[1];
|
|
519
|
+
return includeMilliseconds ? timePart : timePart.split(".")[0];
|
|
520
|
+
}
|
|
521
|
+
case "US":
|
|
522
|
+
return formatUSDate(targetDate);
|
|
523
|
+
case "EU":
|
|
524
|
+
return formatEUDate(targetDate);
|
|
525
|
+
case "FULL":
|
|
526
|
+
return formatFullDate(targetDate, locale);
|
|
527
|
+
case "LONG":
|
|
528
|
+
return formatLongDate(targetDate, locale);
|
|
529
|
+
case "MEDIUM":
|
|
530
|
+
return formatMediumDate(targetDate, locale);
|
|
531
|
+
case "SHORT":
|
|
532
|
+
return formatShortDate(targetDate, locale);
|
|
533
|
+
case "TIME":
|
|
534
|
+
return formatTime(targetDate, locale, includeSeconds);
|
|
535
|
+
case "TIME_24":
|
|
536
|
+
return formatTime24(targetDate, includeSeconds);
|
|
537
|
+
case "DATETIME":
|
|
538
|
+
return `${formatMediumDate(targetDate, locale)}, ${formatTime(
|
|
539
|
+
targetDate,
|
|
540
|
+
locale,
|
|
541
|
+
includeSeconds
|
|
542
|
+
)}`;
|
|
543
|
+
case "TIMESTAMP":
|
|
544
|
+
return formatTimestamp(targetDate);
|
|
545
|
+
case "RFC_2822":
|
|
546
|
+
return formatRFC2822(targetDate);
|
|
547
|
+
case "CUSTOM":
|
|
548
|
+
return formatCustomDate(targetDate, customFormat);
|
|
549
|
+
default:
|
|
550
|
+
return targetDate.toISOString();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
function now() {
|
|
554
|
+
return /* @__PURE__ */ new Date();
|
|
555
|
+
}
|
|
556
|
+
function today() {
|
|
557
|
+
return startOfDay(/* @__PURE__ */ new Date());
|
|
558
|
+
}
|
|
559
|
+
function tomorrow() {
|
|
560
|
+
return addDays(today(), 1);
|
|
561
|
+
}
|
|
562
|
+
function yesterday() {
|
|
563
|
+
return subtractDays(today(), 1);
|
|
564
|
+
}
|
|
565
|
+
function createDate(year, month, day, hour = 0, minute = 0, second = 0, millisecond = 0) {
|
|
566
|
+
validateDateParts(year, month, day, hour, minute, second, millisecond);
|
|
567
|
+
return new Date(year, month, day, hour, minute, second, millisecond);
|
|
568
|
+
}
|
|
569
|
+
function add(date, amount, unit = "day") {
|
|
570
|
+
const parsedDate = parseDate(date);
|
|
571
|
+
const result = new Date(parsedDate);
|
|
572
|
+
switch (unit) {
|
|
573
|
+
case "millisecond":
|
|
574
|
+
result.setMilliseconds(result.getMilliseconds() + amount);
|
|
575
|
+
break;
|
|
576
|
+
case "second":
|
|
577
|
+
result.setSeconds(result.getSeconds() + amount);
|
|
578
|
+
break;
|
|
579
|
+
case "minute":
|
|
580
|
+
result.setMinutes(result.getMinutes() + amount);
|
|
581
|
+
break;
|
|
582
|
+
case "hour":
|
|
583
|
+
result.setHours(result.getHours() + amount);
|
|
584
|
+
break;
|
|
585
|
+
case "day":
|
|
586
|
+
result.setDate(result.getDate() + amount);
|
|
587
|
+
break;
|
|
588
|
+
case "week":
|
|
589
|
+
result.setDate(result.getDate() + amount * DAYS_IN_WEEK);
|
|
590
|
+
break;
|
|
591
|
+
case "month":
|
|
592
|
+
result.setMonth(result.getMonth() + amount);
|
|
593
|
+
break;
|
|
594
|
+
case "quarter":
|
|
595
|
+
result.setMonth(result.getMonth() + amount * 3);
|
|
596
|
+
break;
|
|
597
|
+
case "year":
|
|
598
|
+
result.setFullYear(result.getFullYear() + amount);
|
|
599
|
+
break;
|
|
600
|
+
default:
|
|
601
|
+
throw new Error(`Unsupported date unit: ${unit}`);
|
|
602
|
+
}
|
|
603
|
+
return result;
|
|
604
|
+
}
|
|
605
|
+
function subtract(date, amount, unit = "day") {
|
|
606
|
+
return add(date, -amount, unit);
|
|
607
|
+
}
|
|
608
|
+
function addDays(date, days) {
|
|
609
|
+
return add(date, days, "day");
|
|
610
|
+
}
|
|
611
|
+
function subtractDays(date, days) {
|
|
612
|
+
return subtract(date, days, "day");
|
|
613
|
+
}
|
|
614
|
+
function addMonths(date, months) {
|
|
615
|
+
return add(date, months, "month");
|
|
616
|
+
}
|
|
617
|
+
function subtractMonths(date, months) {
|
|
618
|
+
return subtract(date, months, "month");
|
|
619
|
+
}
|
|
620
|
+
function addYears(date, years) {
|
|
621
|
+
return add(date, years, "year");
|
|
622
|
+
}
|
|
623
|
+
function subtractYears(date, years) {
|
|
624
|
+
return subtract(date, years, "year");
|
|
625
|
+
}
|
|
626
|
+
function startOf(date, unit) {
|
|
627
|
+
const parsedDate = parseDate(date);
|
|
628
|
+
const result = new Date(parsedDate);
|
|
629
|
+
switch (unit) {
|
|
630
|
+
case "year":
|
|
631
|
+
result.setMonth(0, 1);
|
|
632
|
+
result.setHours(0, 0, 0, 0);
|
|
633
|
+
break;
|
|
634
|
+
case "month":
|
|
635
|
+
result.setDate(1);
|
|
636
|
+
result.setHours(0, 0, 0, 0);
|
|
637
|
+
break;
|
|
638
|
+
case "day":
|
|
639
|
+
result.setHours(0, 0, 0, 0);
|
|
640
|
+
break;
|
|
641
|
+
case "hour":
|
|
642
|
+
result.setMinutes(0, 0, 0);
|
|
643
|
+
break;
|
|
644
|
+
case "minute":
|
|
645
|
+
result.setSeconds(0, 0);
|
|
646
|
+
break;
|
|
647
|
+
case "second":
|
|
648
|
+
result.setMilliseconds(0);
|
|
649
|
+
break;
|
|
650
|
+
case "week": {
|
|
651
|
+
const dayOfWeek = result.getDay();
|
|
652
|
+
const diff = (dayOfWeek - config.weekStartsOn + DAYS_IN_WEEK) % DAYS_IN_WEEK;
|
|
653
|
+
result.setDate(result.getDate() - diff);
|
|
654
|
+
result.setHours(0, 0, 0, 0);
|
|
655
|
+
break;
|
|
656
|
+
}
|
|
657
|
+
case "quarter": {
|
|
658
|
+
const quarter = Math.floor(result.getMonth() / 3);
|
|
659
|
+
result.setMonth(quarter * 3, 1);
|
|
660
|
+
result.setHours(0, 0, 0, 0);
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
default:
|
|
664
|
+
throw new Error(`Unsupported unit for startOf: ${unit}`);
|
|
665
|
+
}
|
|
666
|
+
return result;
|
|
667
|
+
}
|
|
668
|
+
function endOf(date, unit) {
|
|
669
|
+
const start = startOf(date, unit);
|
|
670
|
+
const result = new Date(start);
|
|
671
|
+
switch (unit) {
|
|
672
|
+
case "year":
|
|
673
|
+
result.setFullYear(result.getFullYear() + 1);
|
|
674
|
+
break;
|
|
675
|
+
case "quarter":
|
|
676
|
+
result.setMonth(result.getMonth() + 3);
|
|
677
|
+
break;
|
|
678
|
+
case "month":
|
|
679
|
+
result.setMonth(result.getMonth() + 1);
|
|
680
|
+
break;
|
|
681
|
+
case "week":
|
|
682
|
+
result.setDate(result.getDate() + DAYS_IN_WEEK);
|
|
683
|
+
break;
|
|
684
|
+
case "day":
|
|
685
|
+
result.setDate(result.getDate() + 1);
|
|
686
|
+
break;
|
|
687
|
+
case "hour":
|
|
688
|
+
result.setHours(result.getHours() + 1);
|
|
689
|
+
break;
|
|
690
|
+
case "minute":
|
|
691
|
+
result.setMinutes(result.getMinutes() + 1);
|
|
692
|
+
break;
|
|
693
|
+
case "second":
|
|
694
|
+
result.setSeconds(result.getSeconds() + 1);
|
|
695
|
+
break;
|
|
696
|
+
default:
|
|
697
|
+
throw new Error(`Unsupported unit for endOf: ${unit}`);
|
|
698
|
+
}
|
|
699
|
+
result.setMilliseconds(result.getMilliseconds() - 1);
|
|
700
|
+
return result;
|
|
701
|
+
}
|
|
702
|
+
function startOfDay(date) {
|
|
703
|
+
return startOf(date, "day");
|
|
704
|
+
}
|
|
705
|
+
function endOfDay(date) {
|
|
706
|
+
return endOf(date, "day");
|
|
707
|
+
}
|
|
708
|
+
function startOfMonth(date) {
|
|
709
|
+
return startOf(date, "month");
|
|
710
|
+
}
|
|
711
|
+
function endOfMonth(date) {
|
|
712
|
+
return endOf(date, "month");
|
|
713
|
+
}
|
|
714
|
+
function startOfYear(date) {
|
|
715
|
+
return startOf(date, "year");
|
|
716
|
+
}
|
|
717
|
+
function endOfYear(date) {
|
|
718
|
+
return endOf(date, "year");
|
|
719
|
+
}
|
|
720
|
+
function startOfWeek(date) {
|
|
721
|
+
return startOf(date, "week");
|
|
722
|
+
}
|
|
723
|
+
function endOfWeek(date) {
|
|
724
|
+
return endOf(date, "week");
|
|
725
|
+
}
|
|
726
|
+
function isBetween(date, start, end, inclusive = true) {
|
|
727
|
+
const parsedDate = parseDate(date);
|
|
728
|
+
const parsedStart = parseDate(start);
|
|
729
|
+
const parsedEnd = parseDate(end);
|
|
730
|
+
if (inclusive) {
|
|
731
|
+
return parsedDate >= parsedStart && parsedDate <= parsedEnd;
|
|
732
|
+
}
|
|
733
|
+
return parsedDate > parsedStart && parsedDate < parsedEnd;
|
|
734
|
+
}
|
|
735
|
+
function isBefore(date, compareTo) {
|
|
736
|
+
return parseDate(date) < parseDate(compareTo);
|
|
737
|
+
}
|
|
738
|
+
function isAfter(date, compareTo) {
|
|
739
|
+
return parseDate(date) > parseDate(compareTo);
|
|
740
|
+
}
|
|
741
|
+
function isSame(date1, date2, unit) {
|
|
742
|
+
const d1 = parseDate(date1);
|
|
743
|
+
const d2 = parseDate(date2);
|
|
744
|
+
if (!unit) {
|
|
745
|
+
return d1.getTime() === d2.getTime();
|
|
746
|
+
}
|
|
747
|
+
const start1 = startOf(d1, unit);
|
|
748
|
+
const start2 = startOf(d2, unit);
|
|
749
|
+
return start1.getTime() === start2.getTime();
|
|
750
|
+
}
|
|
751
|
+
function isToday(date) {
|
|
752
|
+
return isSame(date, today(), "day");
|
|
753
|
+
}
|
|
754
|
+
function isPast(date) {
|
|
755
|
+
return parseDate(date) < now();
|
|
756
|
+
}
|
|
757
|
+
function isFuture(date) {
|
|
758
|
+
return parseDate(date) > now();
|
|
759
|
+
}
|
|
760
|
+
function difference(date1, date2) {
|
|
761
|
+
const d1 = parseDate(date1);
|
|
762
|
+
const d2 = parseDate(date2);
|
|
763
|
+
const diffMs = Math.abs(d2.getTime() - d1.getTime());
|
|
764
|
+
const totalSeconds = Math.floor(diffMs / MILLISECONDS_IN_SECOND);
|
|
765
|
+
const totalMinutes = Math.floor(totalSeconds / SECONDS_IN_MINUTE);
|
|
766
|
+
const totalHours = Math.floor(totalMinutes / MINUTES_IN_HOUR);
|
|
767
|
+
const totalDays = Math.floor(totalHours / HOURS_IN_DAY);
|
|
768
|
+
return {
|
|
769
|
+
years: Math.floor(totalDays / 365),
|
|
770
|
+
months: Math.floor(totalDays / 30),
|
|
771
|
+
weeks: Math.floor(totalDays / DAYS_IN_WEEK),
|
|
772
|
+
days: totalDays,
|
|
773
|
+
hours: totalHours,
|
|
774
|
+
minutes: totalMinutes,
|
|
775
|
+
seconds: totalSeconds,
|
|
776
|
+
milliseconds: diffMs,
|
|
777
|
+
totalDays,
|
|
778
|
+
totalHours,
|
|
779
|
+
totalMinutes,
|
|
780
|
+
totalSeconds,
|
|
781
|
+
totalMilliseconds: diffMs
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
function humanizeDifference(date1, date2 = now(), detailed = false) {
|
|
785
|
+
const diff = difference(date1, date2);
|
|
786
|
+
const isPast2 = parseDate(date1) < parseDate(date2);
|
|
787
|
+
const prefix = isPast2 ? "ago" : "in";
|
|
788
|
+
if (diff.years > 0) {
|
|
789
|
+
return detailed ? `${diff.years} year${diff.years === 1 ? "" : "s"} ${prefix}` : `${diff.years}y ${prefix}`;
|
|
790
|
+
}
|
|
791
|
+
if (diff.months > 0) {
|
|
792
|
+
return detailed ? `${diff.months} month${diff.months === 1 ? "" : "s"} ${prefix}` : `${diff.months}mo ${prefix}`;
|
|
793
|
+
}
|
|
794
|
+
if (diff.weeks > 0) {
|
|
795
|
+
return detailed ? `${diff.weeks} week${diff.weeks === 1 ? "" : "s"} ${prefix}` : `${diff.weeks}w ${prefix}`;
|
|
796
|
+
}
|
|
797
|
+
if (diff.days > 0) {
|
|
798
|
+
return detailed ? `${diff.days} day${diff.days === 1 ? "" : "s"} ${prefix}` : `${diff.days}d ${prefix}`;
|
|
799
|
+
}
|
|
800
|
+
if (diff.hours > 0) {
|
|
801
|
+
return detailed ? `${diff.hours} hour${diff.hours === 1 ? "" : "s"} ${prefix}` : `${diff.hours}h ${prefix}`;
|
|
802
|
+
}
|
|
803
|
+
if (diff.minutes > 0) {
|
|
804
|
+
return detailed ? `${diff.minutes} minute${diff.minutes === 1 ? "" : "s"} ${prefix}` : `${diff.minutes}m ${prefix}`;
|
|
805
|
+
}
|
|
806
|
+
return detailed ? `${diff.seconds} second${diff.seconds === 1 ? "" : "s"} ${prefix}` : `${diff.seconds}s ${prefix}`;
|
|
807
|
+
}
|
|
808
|
+
function isWeekend(date) {
|
|
809
|
+
const parsedDate = parseDate(date);
|
|
810
|
+
const day = parsedDate.getDay();
|
|
811
|
+
return day === 0 || day === 6;
|
|
812
|
+
}
|
|
813
|
+
function isWeekday(date) {
|
|
814
|
+
return !isWeekend(date);
|
|
815
|
+
}
|
|
816
|
+
function isBusinessDay(date) {
|
|
817
|
+
const parsedDate = parseDate(date);
|
|
818
|
+
if (isWeekend(parsedDate)) {
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
if (!config.businessDays.businessDays.includes(parsedDate.getDay())) {
|
|
822
|
+
return false;
|
|
823
|
+
}
|
|
824
|
+
const isHoliday = config.businessDays.holidays?.some(
|
|
825
|
+
(holiday) => isSame(holiday, parsedDate, "day")
|
|
826
|
+
) || config.businessDays.holidayCheck?.(parsedDate);
|
|
827
|
+
return !isHoliday;
|
|
828
|
+
}
|
|
829
|
+
function addBusinessDays(date, days) {
|
|
830
|
+
let result = parseDate(date);
|
|
831
|
+
let daysAdded = 0;
|
|
832
|
+
const direction = days > 0 ? 1 : -1;
|
|
833
|
+
while (daysAdded < Math.abs(days)) {
|
|
834
|
+
result = addDays(result, direction);
|
|
835
|
+
if (isBusinessDay(result)) {
|
|
836
|
+
daysAdded++;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return result;
|
|
840
|
+
}
|
|
841
|
+
function daysBetween(start, end, inclusive = false) {
|
|
842
|
+
const startDate = startOfDay(parseDate(start));
|
|
843
|
+
const endDate = startOfDay(parseDate(end));
|
|
844
|
+
const diffMs = Math.abs(endDate.getTime() - startDate.getTime());
|
|
845
|
+
const days = Math.floor(
|
|
846
|
+
diffMs / (MILLISECONDS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY)
|
|
847
|
+
);
|
|
848
|
+
return inclusive ? days + 1 : days;
|
|
849
|
+
}
|
|
850
|
+
function monthsBetween(start, end) {
|
|
851
|
+
const startDate = parseDate(start);
|
|
852
|
+
const endDate = parseDate(end);
|
|
853
|
+
const yearsDiff = endDate.getFullYear() - startDate.getFullYear();
|
|
854
|
+
const monthsDiff = endDate.getMonth() - startDate.getMonth();
|
|
855
|
+
return yearsDiff * 12 + monthsDiff;
|
|
856
|
+
}
|
|
857
|
+
function yearsBetween(start, end) {
|
|
858
|
+
const startDate = parseDate(start);
|
|
859
|
+
const endDate = parseDate(end);
|
|
860
|
+
return endDate.getFullYear() - startDate.getFullYear();
|
|
861
|
+
}
|
|
862
|
+
function getAge(birthDate, asOfDate = now()) {
|
|
863
|
+
const birth = parseDate(birthDate);
|
|
864
|
+
const asOf = parseDate(asOfDate);
|
|
865
|
+
let age = asOf.getFullYear() - birth.getFullYear();
|
|
866
|
+
const monthDiff = asOf.getMonth() - birth.getMonth();
|
|
867
|
+
if (monthDiff < 0 || monthDiff === 0 && asOf.getDate() < birth.getDate()) {
|
|
868
|
+
age--;
|
|
869
|
+
}
|
|
870
|
+
return Math.max(0, age);
|
|
871
|
+
}
|
|
872
|
+
function getWeekNumber(date) {
|
|
873
|
+
const parsedDate = parseDate(date);
|
|
874
|
+
const firstDayOfYear = new Date(parsedDate.getFullYear(), 0, 1);
|
|
875
|
+
const pastDaysOfYear = (parsedDate.getTime() - firstDayOfYear.getTime()) / (MILLISECONDS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY);
|
|
876
|
+
return Math.ceil(
|
|
877
|
+
(pastDaysOfYear + firstDayOfYear.getDay() + 1) / DAYS_IN_WEEK
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
function getQuarter(date) {
|
|
881
|
+
const month = parseDate(date).getMonth();
|
|
882
|
+
return Math.floor(month / 3) + 1;
|
|
883
|
+
}
|
|
884
|
+
function getDayName(date, format = "full") {
|
|
885
|
+
const parsedDate = parseDate(date);
|
|
886
|
+
const dayIndex = parsedDate.getDay();
|
|
887
|
+
return format === "full" ? WEEKDAY_NAMES[dayIndex] : WEEKDAY_NAMES_SHORT[dayIndex];
|
|
888
|
+
}
|
|
889
|
+
function getMonthName(date, format = "full") {
|
|
890
|
+
const parsedDate = parseDate(date);
|
|
891
|
+
const monthIndex = parsedDate.getMonth();
|
|
892
|
+
return format === "full" ? MONTH_NAMES[monthIndex] : MONTH_NAMES_SHORT[monthIndex];
|
|
893
|
+
}
|
|
894
|
+
function getDaysInMonth(date) {
|
|
895
|
+
const parsedDate = parseDate(date);
|
|
896
|
+
return new Date(
|
|
897
|
+
parsedDate.getFullYear(),
|
|
898
|
+
parsedDate.getMonth() + 1,
|
|
899
|
+
0
|
|
900
|
+
).getDate();
|
|
901
|
+
}
|
|
902
|
+
function isLeapYear(year) {
|
|
903
|
+
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
|
904
|
+
}
|
|
905
|
+
function validateDate(date, options = {}) {
|
|
906
|
+
const errors = [];
|
|
907
|
+
try {
|
|
908
|
+
const parsedDate = parseDate(date);
|
|
909
|
+
if (options.required && !parsedDate) {
|
|
910
|
+
errors.push("Date is required");
|
|
911
|
+
}
|
|
912
|
+
if (options.min || options.minDate) {
|
|
913
|
+
const minDate = parseDate(options.min || options.minDate);
|
|
914
|
+
if (parsedDate < minDate) {
|
|
915
|
+
errors.push(
|
|
916
|
+
`Date must be on or after ${formatDate(minDate, {
|
|
917
|
+
format: "MEDIUM"
|
|
918
|
+
})}`
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
if (options.max || options.maxDate) {
|
|
923
|
+
const maxDate = parseDate(options.max || options.maxDate);
|
|
924
|
+
if (parsedDate > maxDate) {
|
|
925
|
+
errors.push(
|
|
926
|
+
`Date must be on or before ${formatDate(maxDate, {
|
|
927
|
+
format: "MEDIUM"
|
|
928
|
+
})}`
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
if (options.allowPast === false && isPast(parsedDate)) {
|
|
933
|
+
errors.push("Date must be in the future");
|
|
934
|
+
}
|
|
935
|
+
if (options.allowFuture === false && isFuture(parsedDate)) {
|
|
936
|
+
errors.push("Date must be in the past");
|
|
937
|
+
}
|
|
938
|
+
} catch (error) {
|
|
939
|
+
errors.push(error instanceof Error ? error.message : "Invalid date");
|
|
940
|
+
}
|
|
941
|
+
return {
|
|
942
|
+
isValid: errors.length === 0,
|
|
943
|
+
errors
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
function getTimezoneInfo(date) {
|
|
947
|
+
const parsedDate = parseDate(date);
|
|
948
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
949
|
+
const offset = -parsedDate.getTimezoneOffset();
|
|
950
|
+
const hours = Math.floor(Math.abs(offset) / 60);
|
|
951
|
+
const minutes = Math.abs(offset) % 60;
|
|
952
|
+
const sign = offset >= 0 ? "+" : "-";
|
|
953
|
+
return {
|
|
954
|
+
abbreviation: getTimezoneAbbreviation(parsedDate),
|
|
955
|
+
name: timezone,
|
|
956
|
+
offset,
|
|
957
|
+
offsetString: `UTC${sign}${String(hours).padStart(2, "0")}:${String(
|
|
958
|
+
minutes
|
|
959
|
+
).padStart(2, "0")}`,
|
|
960
|
+
isDST: isDST(parsedDate)
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
function convertTimezone(date, targetTimezone) {
|
|
964
|
+
const parsedDate = parseDate(date);
|
|
965
|
+
if (targetTimezone === "UTC") {
|
|
966
|
+
return new Date(
|
|
967
|
+
parsedDate.getTime() + parsedDate.getTimezoneOffset() * 6e4
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
971
|
+
timeZone: targetTimezone,
|
|
972
|
+
year: "numeric",
|
|
973
|
+
month: "numeric",
|
|
974
|
+
day: "numeric",
|
|
975
|
+
hour: "numeric",
|
|
976
|
+
minute: "numeric",
|
|
977
|
+
second: "numeric"
|
|
978
|
+
});
|
|
979
|
+
const parts = formatter.formatToParts(parsedDate);
|
|
980
|
+
const getPart = (type) => parts.find((p) => p.type === type)?.value;
|
|
981
|
+
return createDate(
|
|
982
|
+
parseInt(getPart("year")),
|
|
983
|
+
parseInt(getPart("month")) - 1,
|
|
984
|
+
parseInt(getPart("day")),
|
|
985
|
+
parseInt(getPart("hour")),
|
|
986
|
+
parseInt(getPart("minute")),
|
|
987
|
+
parseInt(getPart("second"))
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
function formatUSDate(date) {
|
|
991
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
992
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
993
|
+
const year = date.getFullYear();
|
|
994
|
+
return `${month}/${day}/${year}`;
|
|
995
|
+
}
|
|
996
|
+
function formatEUDate(date) {
|
|
997
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
998
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
999
|
+
const year = date.getFullYear();
|
|
1000
|
+
return `${day}/${month}/${year}`;
|
|
1001
|
+
}
|
|
1002
|
+
function formatFullDate(date, locale) {
|
|
1003
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1004
|
+
weekday: "long",
|
|
1005
|
+
year: "numeric",
|
|
1006
|
+
month: "long",
|
|
1007
|
+
day: "numeric"
|
|
1008
|
+
}).format(date);
|
|
1009
|
+
}
|
|
1010
|
+
function formatLongDate(date, locale) {
|
|
1011
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1012
|
+
year: "numeric",
|
|
1013
|
+
month: "long",
|
|
1014
|
+
day: "numeric"
|
|
1015
|
+
}).format(date);
|
|
1016
|
+
}
|
|
1017
|
+
function formatMediumDate(date, locale) {
|
|
1018
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1019
|
+
year: "numeric",
|
|
1020
|
+
month: "short",
|
|
1021
|
+
day: "numeric"
|
|
1022
|
+
}).format(date);
|
|
1023
|
+
}
|
|
1024
|
+
function formatShortDate(date, locale) {
|
|
1025
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1026
|
+
year: "2-digit",
|
|
1027
|
+
month: "numeric",
|
|
1028
|
+
day: "numeric"
|
|
1029
|
+
}).format(date);
|
|
1030
|
+
}
|
|
1031
|
+
function formatTime(date, locale, includeSeconds) {
|
|
1032
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1033
|
+
hour: "numeric",
|
|
1034
|
+
minute: "2-digit",
|
|
1035
|
+
second: includeSeconds ? "2-digit" : void 0,
|
|
1036
|
+
hour12: true
|
|
1037
|
+
}).format(date);
|
|
1038
|
+
}
|
|
1039
|
+
function formatTime24(date, includeSeconds) {
|
|
1040
|
+
const hours = date.getHours().toString().padStart(2, "0");
|
|
1041
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
1042
|
+
const seconds = includeSeconds ? `:${date.getSeconds().toString().padStart(2, "0")}` : "";
|
|
1043
|
+
return `${hours}:${minutes}${seconds}`;
|
|
1044
|
+
}
|
|
1045
|
+
function formatTimestamp(date) {
|
|
1046
|
+
const year = date.getFullYear();
|
|
1047
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
1048
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
1049
|
+
const hours = date.getHours().toString().padStart(2, "0");
|
|
1050
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
1051
|
+
const seconds = date.getSeconds().toString().padStart(2, "0");
|
|
1052
|
+
return `${year}${month}${day}${hours}${minutes}${seconds}`;
|
|
1053
|
+
}
|
|
1054
|
+
function formatRFC2822(date) {
|
|
1055
|
+
return date.toUTCString();
|
|
1056
|
+
}
|
|
1057
|
+
function formatCustomDate(date, format) {
|
|
1058
|
+
const tokens = {
|
|
1059
|
+
YYYY: date.getFullYear().toString(),
|
|
1060
|
+
YY: date.getFullYear().toString().slice(-2),
|
|
1061
|
+
MMMM: MONTH_NAMES[date.getMonth()],
|
|
1062
|
+
MMM: MONTH_NAMES_SHORT[date.getMonth()],
|
|
1063
|
+
MM: (date.getMonth() + 1).toString().padStart(2, "0"),
|
|
1064
|
+
M: (date.getMonth() + 1).toString(),
|
|
1065
|
+
DDDD: WEEKDAY_NAMES[date.getDay()],
|
|
1066
|
+
DDD: WEEKDAY_NAMES_SHORT[date.getDay()],
|
|
1067
|
+
DD: date.getDate().toString().padStart(2, "0"),
|
|
1068
|
+
D: date.getDate().toString(),
|
|
1069
|
+
HH: date.getHours().toString().padStart(2, "0"),
|
|
1070
|
+
H: date.getHours().toString(),
|
|
1071
|
+
hh: (date.getHours() % 12 || 12).toString().padStart(2, "0"),
|
|
1072
|
+
h: (date.getHours() % 12 || 12).toString(),
|
|
1073
|
+
mm: date.getMinutes().toString().padStart(2, "0"),
|
|
1074
|
+
m: date.getMinutes().toString(),
|
|
1075
|
+
ss: date.getSeconds().toString().padStart(2, "0"),
|
|
1076
|
+
s: date.getSeconds().toString(),
|
|
1077
|
+
SSS: date.getMilliseconds().toString().padStart(3, "0"),
|
|
1078
|
+
A: date.getHours() < 12 ? "AM" : "PM",
|
|
1079
|
+
a: date.getHours() < 12 ? "am" : "pm"
|
|
1080
|
+
};
|
|
1081
|
+
return format.replace(
|
|
1082
|
+
/YYYY|YY|MMMM|MMM|MM|M|DDDD|DDD|DD|D|HH|H|hh|h|mm|m|ss|s|SSS|A|a/g,
|
|
1083
|
+
(match) => tokens[match] || match
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
function validateDateParts(year, month, day, hour = 0, minute = 0, second = 0, millisecond = 0) {
|
|
1087
|
+
if (year < 1e3 || year > 9999) {
|
|
1088
|
+
throw new Error(`Year must be between 1000 and 9999: ${year}`);
|
|
1089
|
+
}
|
|
1090
|
+
if (month < 0 || month > 11) {
|
|
1091
|
+
throw new Error(`Month must be between 0 and 11: ${month}`);
|
|
1092
|
+
}
|
|
1093
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1094
|
+
if (day < 1 || day > daysInMonth) {
|
|
1095
|
+
throw new Error(
|
|
1096
|
+
`Day must be between 1 and ${daysInMonth} for month ${month}: ${day}`
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
if (hour < 0 || hour > 23) {
|
|
1100
|
+
throw new Error(`Hour must be between 0 and 23: ${hour}`);
|
|
1101
|
+
}
|
|
1102
|
+
if (minute < 0 || minute > 59) {
|
|
1103
|
+
throw new Error(`Minute must be between 0 and 59: ${minute}`);
|
|
1104
|
+
}
|
|
1105
|
+
if (second < 0 || second > 59) {
|
|
1106
|
+
throw new Error(`Second must be between 0 and 59: ${second}`);
|
|
1107
|
+
}
|
|
1108
|
+
if (millisecond < 0 || millisecond > 999) {
|
|
1109
|
+
throw new Error(`Millisecond must be between 0 and 999: ${millisecond}`);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
function getTimezoneAbbreviation(date) {
|
|
1113
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
1114
|
+
timeZoneName: "short"
|
|
1115
|
+
});
|
|
1116
|
+
const parts = formatter.formatToParts(date);
|
|
1117
|
+
const timezonePart = parts.find((part) => part.type === "timeZoneName");
|
|
1118
|
+
return timezonePart ? timezonePart.value : "UTC";
|
|
1119
|
+
}
|
|
1120
|
+
function isDST(date) {
|
|
1121
|
+
const jan = new Date(date.getFullYear(), 0, 1);
|
|
1122
|
+
const jul = new Date(date.getFullYear(), 6, 1);
|
|
1123
|
+
const stdTimezoneOffset = Math.max(
|
|
1124
|
+
jan.getTimezoneOffset(),
|
|
1125
|
+
jul.getTimezoneOffset()
|
|
1126
|
+
);
|
|
1127
|
+
return date.getTimezoneOffset() < stdTimezoneOffset;
|
|
1128
|
+
}
|