@@ -46,6 +46,41 @@ var dateHelper = (function () {
4646 } ;
4747 }
4848
49+ // Pads a number to 2 digits with leading zero
50+ const pad = ( n ) => n . toString ( ) . padStart ( 2 , '0' ) ;
51+
52+ /**
53+ * Formats a Date object as 'YYYY-MM-DD' or 'YYYY-MM-DD HH:mm'.
54+ *
55+ * By default, uses local time components (getFullYear, getMonth, getDate, etc.).
56+ * Set useUtc=true to use UTC components (getUTCFullYear, ...).
57+ *
58+ * WARNING: For Date objects created from 'YYYY-MM-DD' (e.g., via parseYMDDate),
59+ * using toISOString() or UTC methods will shift the day if your local timezone is behind UTC.
60+ * Always use the default (local) mode for calendar and reservation logic unless you explicitly need UTC.
61+ *
62+ * Examples:
63+ * formatDate(new Date(2026, 3, 22)) // '2026-04-22' (local)
64+ * formatDate(new Date(2026, 3, 22, 15, 30), true) // '2026-04-22 15:30' (local)
65+ * formatDate(new Date(Date.UTC(2026, 3, 22)), false, true) // '2026-04-22' (UTC)
66+ *
67+ * @param {Date } date
68+ * @param {boolean } withTime - If true, includes ' HH:mm'
69+ * @param {boolean } useUtc - If true, uses UTC components (default: false)
70+ * @returns {string }
71+ */
72+ function formatDate ( date , withTime = false , useUtc = false ) {
73+ if ( ! ( date instanceof Date ) || isNaN ( date ) ) return '' ;
74+ const y = useUtc ? date . getUTCFullYear ( ) : date . getFullYear ( ) ;
75+ const m = useUtc ? date . getUTCMonth ( ) + 1 : date . getMonth ( ) + 1 ;
76+ const d = useUtc ? date . getUTCDate ( ) : date . getDate ( ) ;
77+ const ymd = y + '-' + pad ( m ) + '-' + pad ( d ) ;
78+ if ( ! withTime ) return ymd ;
79+ const hh = useUtc ? date . getUTCHours ( ) : date . getHours ( ) ;
80+ const mm = useUtc ? date . getUTCMinutes ( ) : date . getMinutes ( ) ;
81+ return ymd + ' ' + pad ( hh ) + ':' + pad ( mm ) ;
82+ }
83+
4984 /**
5085 * Parses a time string into a Date object (today's date).
5186 *
@@ -93,7 +128,6 @@ var dateHelper = (function () {
93128 * text: string // Human-readable representation according to format
94129 * }}
95130 */
96- const pad = ( n ) => n . toString ( ) . padStart ( 2 , '0' ) ;
97131
98132 function formatTime ( hour24 , minute , format ) {
99133 const value = `${ pad ( hour24 ) } :${ pad ( minute ) } ` ; // internal value always 24h
@@ -191,7 +225,26 @@ var dateHelper = (function () {
191225 }
192226 }
193227
228+ /**
229+ * Parses a 'YYYY-MM-DD' string into a Date object (local time).
230+ *
231+ * @param {string } ymd - Date string in 'YYYY-MM-DD' format
232+ * @returns {Date|null }
233+ */
234+ function parseYMDDate ( ymd ) {
235+ if ( ! ymd || typeof ymd !== 'string' ) return null ;
236+ var parts = ymd . split ( '-' ) ;
237+ if ( parts . length !== 3 ) return null ;
238+ var year = parseInt ( parts [ 0 ] , 10 ) ;
239+ var month = parseInt ( parts [ 1 ] , 10 ) - 1 ;
240+ var day = parseInt ( parts [ 2 ] , 10 ) ;
241+ if ( isNaN ( year ) || isNaN ( month ) || isNaN ( day ) ) return null ;
242+ return new Date ( year , month , day ) ;
243+ }
244+
194245 return {
246+ formatDate,
247+ parseYMDDate,
195248 MoreThanOneDayBetweenBeginAndEnd : function ( beginDateElement , beginTimeElement , endDateElement , endTimeElement ) {
196249 var begin = this . GetDate ( beginDateElement , beginTimeElement ) ;
197250 var end = this . GetDate ( endDateElement , endTimeElement ) ;
0 commit comments