fix: handle datetime-local timezone conversion correctly
- Convert datetime-local values to UTC ISO strings before sending to API (new Date(r).toISOString()) in both create and update flows - Parse UTC ISO strings directly in API instead of manual Date.UTC() parsing that treated local components as UTC, causing timezone offset bugs - Convert UTC API response times to local on load using new Date(str + 'Z') and date-fns format() to avoid double-timezone shift when editing
This commit is contained in:
@@ -77,15 +77,9 @@ export async function PUT(
|
|||||||
nextOccurrence: nextOccurrence ? new Date(nextOccurrence) : undefined,
|
nextOccurrence: nextOccurrence ? new Date(nextOccurrence) : undefined,
|
||||||
reminders: {
|
reminders: {
|
||||||
deleteMany: {},
|
deleteMany: {},
|
||||||
create: (reminders || []).map((r: string) => {
|
create: (reminders || []).map((r: string) => ({
|
||||||
// Parse local datetime string and construct Date to preserve local time
|
reminder: new Date(r),
|
||||||
const [datePart, timePart] = r.split('T');
|
})),
|
||||||
const [year, month, day] = datePart.split('-').map(Number);
|
|
||||||
const [hours, minutes] = timePart.split(':').map(Number);
|
|
||||||
return {
|
|
||||||
reminder: new Date(Date.UTC(year, month - 1, day, hours, minutes)),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
|
|||||||
@@ -93,15 +93,9 @@ export async function POST(request: NextRequest) {
|
|||||||
parentTaskId: parentTaskId || undefined,
|
parentTaskId: parentTaskId || undefined,
|
||||||
sortOrder: (maxSort._max.sortOrder ?? 0) + 1,
|
sortOrder: (maxSort._max.sortOrder ?? 0) + 1,
|
||||||
reminders: {
|
reminders: {
|
||||||
create: (reminders || []).map((r: string) => {
|
create: (reminders || []).map((r: string) => ({
|
||||||
// Parse local datetime string and construct Date to preserve local time
|
reminder: new Date(r),
|
||||||
const [datePart, timePart] = r.split('T');
|
})),
|
||||||
const [year, month, day] = datePart.split('-').map(Number);
|
|
||||||
const [hours, minutes] = timePart.split(':').map(Number);
|
|
||||||
return {
|
|
||||||
reminder: new Date(Date.UTC(year, month - 1, day, hours, minutes)),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
|
|||||||
@@ -44,7 +44,11 @@ export default function EditTaskModal() {
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
setSubtasks(data.subtasks || []);
|
setSubtasks(data.subtasks || []);
|
||||||
if (data.reminders && data.reminders.length > 0) {
|
if (data.reminders && data.reminders.length > 0) {
|
||||||
setReminders(data.reminders.map((r: any) => r.reminder));
|
// API returns UTC times — convert to local for datetime-local input
|
||||||
|
setReminders(data.reminders.map((r: any) => {
|
||||||
|
const d = new Date(r.reminder + 'Z');
|
||||||
|
return format(d, "yyyy-MM-dd'T'HH:mm");
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
@@ -81,7 +85,9 @@ export default function EditTaskModal() {
|
|||||||
status,
|
status,
|
||||||
recurrenceRule,
|
recurrenceRule,
|
||||||
recurrenceInterval,
|
recurrenceInterval,
|
||||||
reminders: reminders.filter((r) => r !== ''),
|
reminders: reminders
|
||||||
|
.filter((r) => r !== '')
|
||||||
|
.map((r) => new Date(r).toISOString()),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ export default function NewTaskModal() {
|
|||||||
status,
|
status,
|
||||||
recurrenceRule,
|
recurrenceRule,
|
||||||
recurrenceInterval,
|
recurrenceInterval,
|
||||||
reminders: reminders.filter((r) => r !== ''),
|
reminders: reminders
|
||||||
|
.filter((r) => r !== '')
|
||||||
|
.map((r) => new Date(r).toISOString()),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user