Dates are really weird, and I can't seem to solve this issue:
Client lives in GMT+2
time zone and server saves everything in UTC
time zone.
Client provides date 2024-12-01
which is converted to UTC time 2024-11-30T22:00:00.000Z
and saved in the server.
Then client needs to get a date from the server that is one month after the saved date, which should be 2025-01-01
. However, the server will return to client: 2024-12-31
Because server saved date is going to be the last day of the month but not the first as client provided. So, the following function does not work:
const setToNextMonth = (date) => {
date.setMonth(date.getMonth()+1)
}
// Correct
const clientDate = new Date('2024-12-01')
setToNextMonth(clientDate)
console.log(clientDate, '- Should return')
// Incorrect
const serverDate = new Date('2024-11-30T22:00:00.000Z')
setToNextMonth(serverDate)
console.log(serverDate, '- Actual return')
Dates are really weird, and I can't seem to solve this issue:
Client lives in GMT+2
time zone and server saves everything in UTC
time zone.
Client provides date 2024-12-01
which is converted to UTC time 2024-11-30T22:00:00.000Z
and saved in the server.
Then client needs to get a date from the server that is one month after the saved date, which should be 2025-01-01
. However, the server will return to client: 2024-12-31
Because server saved date is going to be the last day of the month but not the first as client provided. So, the following function does not work:
const setToNextMonth = (date) => {
date.setMonth(date.getMonth()+1)
}
// Correct
const clientDate = new Date('2024-12-01')
setToNextMonth(clientDate)
console.log(clientDate, '- Should return')
// Incorrect
const serverDate = new Date('2024-11-30T22:00:00.000Z')
setToNextMonth(serverDate)
console.log(serverDate, '- Actual return')
The question is how to get the correct next month date without knowing client timezone?
Share Improve this question edited Nov 19, 2024 at 11:06 MCTG asked Nov 19, 2024 at 8:09 MCTGMCTG 611 silver badge12 bronze badges 6- 2024-01-01(2024-12-31T22:00:00.000Z)? What format is: yyyy-mm=dd(yyyy-mm-ddThh:mm:ss. sssZ)? – zer00ne Commented Nov 19, 2024 at 9:13
- My bad, I've updated description. First is formatted date according to client time zone and in the brackets I've provided server response. – MCTG Commented Nov 19, 2024 at 10:23
- "…server will take November (30) month days instead of December (31)". Not exactly, it just adds 1 to the month number, so 30 Nov becomes 30 Dec. You want to treat a date as just the date part, without time, i.e. independent of timezone. The new Temporal object will let you do that. In the meantime consider passing date strings, treating them as local everywhere, making them timezone independent. "2024-12-01" should be parsed as local, but the ECMA-262 authors thought differently (which I consider a bug in the specification but it will be obviated by Temporal when it's introduced). – RobG Commented Nov 19, 2024 at 10:29
- 1 Store dates without timezone as dates without timezone, not as JavaScript date. – Salman Arshad Commented Nov 19, 2024 at 10:57
- What if storing the date as string is not an option? For example MongoDB strongly encourages using only native data type. – MCTG Commented Nov 19, 2024 at 11:30
1 Answer
Reset to default 1Your issue is when the day does not exist in the next month. You said you want the last of next month if current day is larger than the number of days in next month.
I normalise on 15:00 to not run into DSL and timezone issues since the largest TZ difference is 13 hours.
const getNextMonthDate = (dateStringUTC) => {
const date = new Date(dateStringUTC);
const savedDays = date.getUTCDate(); // Days of the passed month
const time = dateStringUTC.split('T')[1]; // Extract the time part
// Normalize to 15:00 UTC to handle DSL and TZ
date.setUTCHours(15, 0, 0, 0);
// Add one month
date.setUTCMonth(date.getUTCMonth() + 1);
// If saved days are greater than 28 and the our new date < saved days we overshot the date
if (savedDays > 28 && date.getUTCDate() < savedDays) {
// Adjust to the last day of the next month
const lastDayOfNextMonth = new Date(
date.getUTCFullYear(), // No issue with year transitions
date.getUTCMonth(), // Month is already the next month
0, // 0th day gives the last day of the month we are aiming for
15, 0, 0, 0 // Set time to 15:00 for consistency
).getUTCDate();
// Roll back the month
date.setUTCMonth(date.getUTCMonth() - 1);
// Set the date to the last day of the month
date.setUTCDate(lastDayOfNextMonth);
} else {
// Otherwise, set the date to the saved days
date.setUTCDate(savedDays);
}
// Return the final ISO string with the preserved time
return `${date.toISOString().split('T')[0]}T${time};`
};
const inputDate = "2024-11-30T22:00:00.000Z";
console.log(getNextMonthDate(inputDate)); // Expected: 2024-12-30T22:00:00.000Z;
const inputDate1 = "2024-01-30T22:00:00.000Z";
console.log(getNextMonthDate(inputDate1)); // Feb 28 or 29 depending on leap
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745577443a4634051.html
评论列表(0条)