Calendar/.workbench/poc-layouts/calendar-date-utils.js

231 lines
5.9 KiB
JavaScript
Raw Permalink Normal View History

// js/utils/DateUtils.js
/**
* Date and time utility functions
*/
export class DateUtils {
/**
* Get start of week for a given date
* @param {Date} date
* @param {number} firstDayOfWeek - 0 = Sunday, 1 = Monday
* @returns {Date}
*/
static getWeekStart(date, firstDayOfWeek = 1) {
const d = new Date(date);
const day = d.getDay();
const diff = (day - firstDayOfWeek + 7) % 7;
d.setDate(d.getDate() - diff);
d.setHours(0, 0, 0, 0);
return d;
}
/**
* Get end of week for a given date
* @param {Date} date
* @param {number} firstDayOfWeek
* @returns {Date}
*/
static getWeekEnd(date, firstDayOfWeek = 1) {
const start = this.getWeekStart(date, firstDayOfWeek);
const end = new Date(start);
end.setDate(end.getDate() + 6);
end.setHours(23, 59, 59, 999);
return end;
}
/**
* Format date to YYYY-MM-DD
* @param {Date} date
* @returns {string}
*/
static formatDate(date) {
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
}
/**
* Format time to HH:MM
* @param {Date} date
* @returns {string}
*/
static formatTime(date) {
return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
}
/**
* Format time to 12-hour format
* @param {Date} date
* @returns {string}
*/
static formatTime12(date) {
const hours = date.getHours();
const minutes = date.getMinutes();
const period = hours >= 12 ? 'PM' : 'AM';
const displayHours = hours % 12 || 12;
return `${displayHours}:${String(minutes).padStart(2, '0')} ${period}`;
}
/**
* Convert minutes since midnight to time string
* @param {number} minutes
* @returns {string}
*/
static minutesToTime(minutes) {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
const period = hours >= 12 ? 'PM' : 'AM';
const displayHours = hours % 12 || 12;
return `${displayHours}:${String(mins).padStart(2, '0')} ${period}`;
}
/**
* Convert time string to minutes since midnight
* @param {string} timeStr - Format: "HH:MM" or "HH:MM:SS"
* @returns {number}
*/
static timeToMinutes(timeStr) {
const [time] = timeStr.split('T').pop().split('.');
const [hours, minutes] = time.split(':').map(Number);
return hours * 60 + minutes;
}
/**
* Get minutes since start of day
* @param {Date|string} date
* @returns {number}
*/
static getMinutesSinceMidnight(date) {
const d = typeof date === 'string' ? new Date(date) : date;
return d.getHours() * 60 + d.getMinutes();
}
/**
* Calculate duration in minutes between two dates
* @param {Date|string} start
* @param {Date|string} end
* @returns {number}
*/
static getDurationMinutes(start, end) {
const startDate = typeof start === 'string' ? new Date(start) : start;
const endDate = typeof end === 'string' ? new Date(end) : end;
return Math.floor((endDate - startDate) / 60000);
}
/**
* Check if date is today
* @param {Date} date
* @returns {boolean}
*/
static isToday(date) {
const today = new Date();
return date.toDateString() === today.toDateString();
}
/**
* Check if two dates are on the same day
* @param {Date} date1
* @param {Date} date2
* @returns {boolean}
*/
static isSameDay(date1, date2) {
return date1.toDateString() === date2.toDateString();
}
/**
* Check if event spans multiple days
* @param {Date|string} start
* @param {Date|string} end
* @returns {boolean}
*/
static isMultiDay(start, end) {
const startDate = typeof start === 'string' ? new Date(start) : start;
const endDate = typeof end === 'string' ? new Date(end) : end;
return !this.isSameDay(startDate, endDate);
}
/**
* Get day name
* @param {Date} date
* @param {string} format - 'short' or 'long'
* @returns {string}
*/
static getDayName(date, format = 'short') {
const days = {
short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
};
return days[format][date.getDay()];
}
/**
* Add days to date
* @param {Date} date
* @param {number} days
* @returns {Date}
*/
static addDays(date, days) {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
/**
* Add minutes to date
* @param {Date} date
* @param {number} minutes
* @returns {Date}
*/
static addMinutes(date, minutes) {
const result = new Date(date);
result.setMinutes(result.getMinutes() + minutes);
return result;
}
/**
* Snap time to nearest interval
* @param {Date} date
* @param {number} intervalMinutes
* @returns {Date}
*/
static snapToInterval(date, intervalMinutes) {
const minutes = date.getMinutes();
const snappedMinutes = Math.round(minutes / intervalMinutes) * intervalMinutes;
const result = new Date(date);
result.setMinutes(snappedMinutes);
result.setSeconds(0);
result.setMilliseconds(0);
return result;
}
/**
* Get current time in minutes since day start
* @param {number} dayStartHour
* @returns {number}
*/
static getCurrentTimeMinutes(dayStartHour = 0) {
const now = new Date();
const minutesSinceMidnight = now.getHours() * 60 + now.getMinutes();
return minutesSinceMidnight - (dayStartHour * 60);
}
/**
* Format duration to human readable string
* @param {number} minutes
* @returns {string}
*/
static formatDuration(minutes) {
if (minutes < 60) {
return `${minutes} min`;
}
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
if (mins === 0) {
return `${hours} hour${hours > 1 ? 's' : ''}`;
}
return `${hours} hour${hours > 1 ? 's' : ''} ${mins} min`;
}
}