Migrate to luxon. Fixes wrong weekday to date bug as well.

This commit is contained in:
2025-06-23 10:33:37 +02:00
parent 7ddca43a01
commit 9b793d47d8
2 changed files with 44 additions and 56 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@tp/tp-date-picker", "name": "@tp/tp-date-picker",
"version": "2.3.0", "version": "3.0.0",
"description": "", "description": "",
"main": "tp-date-picker.js", "main": "tp-date-picker.js",
"scripts": { "scripts": {
@ -13,8 +13,7 @@
"author": "trading_peter", "author": "trading_peter",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@date-fns/utc": "^2.1.0", "luxon": "^3.6.1",
"date-fns": "^4.0.0",
"lit": "^2.2.0" "lit": "^2.2.0"
} }
} }

View File

@ -7,7 +7,7 @@ This program is available under Apache License Version 2.0
import '@tp/tp-icon/tp-icon.js'; import '@tp/tp-icon/tp-icon.js';
import { FormElement } from '@tp/helpers/form-element'; import { FormElement } from '@tp/helpers/form-element';
import { LitElement, html, css, svg } from 'lit'; import { LitElement, html, css, svg } from 'lit';
import { UTCDate } from '@date-fns/utc'; import { DateTime } from 'luxon';
class TpDatePicker extends FormElement(LitElement) { class TpDatePicker extends FormElement(LitElement) {
static get styles() { static get styles() {
@ -142,14 +142,17 @@ class TpDatePicker extends FormElement(LitElement) {
render() { render() {
let { month, year, dayNames, value, yearsForward, yearsBackwards } = this; let { month, year, dayNames, value, yearsForward, yearsBackwards } = this;
const today = new UTCDate(); const today = DateTime.utc();
if ((!month && month !== 0) || (!year && year !== 0)) { if ((!month && month !== 0) || (!year && year !== 0)) {
month = today.getMonth(); month = today.month - 1; // Luxon uses 1-based months, convert to 0-based for compatibility
year = today.getFullYear(); year = today.year;
} }
const years = Array(yearsForward + yearsBackwards).fill().map((_, i) => today.getFullYear()-yearsBackwards+i).reverse(); const years = Array(yearsForward + yearsBackwards)
.fill()
.map((_, i) => today.year - yearsBackwards + i)
.reverse();
const curMonth = this.getMonthDates(month, year); const curMonth = this.getMonthDates(month, year);
return html` return html`
@ -183,9 +186,9 @@ class TpDatePicker extends FormElement(LitElement) {
const eventCount = this.countEventsForDate(d); const eventCount = this.countEventsForDate(d);
return html` return html`
<div .date=${d} part="date ${d.getMonth() !== month ? 'filler' : 'of-month'}"> <div .date=${d} part="date ${d.month - 1 !== month ? 'filler' : 'of-month'}">
<div class="number" part="number ${matchesValue ? 'selected' : ''} ${isToday ? 'today' : ''} ${d.getMonth() === month ? 'of-month' : ''}"> <div class="number" part="number ${matchesValue ? 'selected' : ''} ${isToday ? 'today' : ''} ${d.month - 1 === month ? 'of-month' : ''}">
${d.getDate()} ${d.day}
${eventCount > 0 ? html` ${eventCount > 0 ? html`
<div class="event-dots"> <div class="event-dots">
<div class="event-dot" part="event-dot"></div> <div class="event-dot" part="event-dot"></div>
@ -207,8 +210,8 @@ class TpDatePicker extends FormElement(LitElement) {
static get properties() { static get properties() {
return { return {
value: { type: Date }, value: { type: Object }, // Changed from Date to Luxon DateTime
today: { type: Date }, today: { type: Object }, // Changed from Date to Luxon DateTime
month: { type: Number }, month: { type: Number },
year: { type: Number }, year: { type: Number },
monthNames: { type: Array }, monthNames: { type: Array },
@ -235,9 +238,9 @@ class TpDatePicker extends FormElement(LitElement) {
constructor() { constructor() {
super(); super();
this.today = new UTCDate(); this.today = DateTime.utc();
this.month = this.today.getMonth(); this.month = this.today.month - 1; // Convert 1-based to 0-based month
this.year = this.today.getFullYear(); this.year = this.today.year;
this.yearsForward = 10; this.yearsForward = 10;
this.yearsBackwards = 100; this.yearsBackwards = 100;
this.events = []; this.events = [];
@ -269,17 +272,17 @@ class TpDatePicker extends FormElement(LitElement) {
} }
shouldUpdate(changes) { shouldUpdate(changes) {
if (changes.has('value')) { if (changes.has('value') && this.value) {
this.month = this.value.getMonth(); this.month = this.value.month - 1; // Convert 1-based to 0-based month
this.year = this.value.getFullYear(); this.year = this.value.year;
} }
return true; return true;
} }
equalDate(d, value) { equalDate(d1, d2) {
if (!value) return false; if (!d1 || !d2) return false;
return d.getDate() === value.getDate() && d.getFullYear() === value.getFullYear() && d.getMonth() === value.getMonth(); return d1.day === d2.day && d1.year === d2.year && d1.month === d2.month;
} }
selectDate(e) { selectDate(e) {
@ -331,50 +334,36 @@ class TpDatePicker extends FormElement(LitElement) {
} }
getMonthDates(month = null, year = null) { getMonthDates(month = null, year = null) {
month = month !== null ? month : new UTCDate().getMonth(); month = month !== null ? month : DateTime.utc().month - 1; // Convert 1-based to 0-based
year = year || new UTCDate().getFullYear(); year = year || DateTime.utc().year;
const firstOfMonth = new UTCDate(); // Create DateTime for the first of the month (convert 0-based month back to 1-based)
firstOfMonth.setFullYear(year); const firstOfMonth = DateTime.utc(year, month + 1, 1, 0, 0, 0);
firstOfMonth.setMonth(month);
firstOfMonth.setDate(1);
firstOfMonth.setHours(0);
firstOfMonth.setMinutes(0);
firstOfMonth.setSeconds(0);
const lastOfMonth = new UTCDate(); // Create DateTime for the last of the month
lastOfMonth.setDate(1); const lastOfMonth = firstOfMonth.endOf('month').startOf('day');
lastOfMonth.setFullYear(year);
lastOfMonth.setMonth(month + 1);
lastOfMonth.setDate(lastOfMonth.getDate() - 1);
lastOfMonth.setHours(0);
lastOfMonth.setMinutes(0);
lastOfMonth.setSeconds(0);
const dates = []; const dates = [];
while (firstOfMonth.getDay() > 1) { // Calculate dates before the first of month to fill the calendar
firstOfMonth.setDate(firstOfMonth.getDate() - 1); let firstDayOfCalendar = firstOfMonth;
dates.push(new UTCDate(firstOfMonth)); while (firstDayOfCalendar.weekday > 1) { // 1 is Monday in Luxon
firstDayOfCalendar = firstDayOfCalendar.minus({ days: 1 });
dates.push(firstDayOfCalendar);
} }
dates.reverse(); dates.reverse();
for (let i = 1; i <= lastOfMonth.getDate(); ++i) { // Add all days of the current month
const d = new UTCDate(); for (let i = 1; i <= lastOfMonth.day; i++) {
d.setFullYear(year); dates.push(DateTime.utc(year, month + 1, i, 0, 0, 0));
d.setMonth(month);
d.setDate(i);
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
dates.push(d);
} }
// Make sure we always fill 42 date get guarantee equal size of the date picker. // Make sure we always fill 42 dates to guarantee equal size of the date picker
let nextDate = lastOfMonth;
while (dates.length < 42) { while (dates.length < 42) {
lastOfMonth.setDate(lastOfMonth.getDate() + 1); nextDate = nextDate.plus({ days: 1 });
dates.push(new UTCDate(lastOfMonth)); dates.push(nextDate);
} }
return dates; return dates;