Расчет даты Java Script работает неправильно

Я рассчитываю дату в JavaScript на основе даты, частоты и периода. Когда я рассчитываю дату за один месяц, она работает отлично, но когда я пытаюсь рассчитать дату три месяца или шесть месяцев, код ниже не работает нормально.

Значение CurrentDate — 01 февраля 2023 г., а значение X — 3.

Когда я даю значение x = 1, тогда код ниже дает 1 марта 2023 года, что правильно, но когда я даю значение x = 3, тогда он дает 1 февраля 2024 года вместо 1 мая 2023 года.

var x = 3;
CurrentDate = "01-Feb-2023"
var d = new Date(CurrentDate);
console.info(d);
d.setMonth(d.getMonth() + x);
console.info(d);
var lastDate = moment(d.toISOString().slice(0, 10)).format("DD-MMM-YYYY");
console.info(lastDate)
<script src = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

Почему вы используете момент, а затем не используете его, чтобы добавить месяц???

mplungjan 01.02.2023 07:25

Что ожидается? Я вижу 31 января (из-за часовых поясов) + 3 месяца дает 30 апреля.

mplungjan 01.02.2023 07:26

У меня есть момент, чтобы изменить формат даты. да, мои ожидания такие же, как и в комментарии выше, в случае частоты 3 это означает следующие три месяца

Moin Khan 01.02.2023 07:28
Не стоит использовать Момент
kevinSpaceyIsKeyserSöze 01.02.2023 10:04

Примечание: авторы момента рекомендуют вам больше его не использовать.

freedomn-m 01.02.2023 10:09
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас проблема с часовым поясом

Также вы теряете момент, не используя его для добавления месяца

Обратите внимание, что этот формат даты заставляет момент жаловаться: '01-Feb-2023'

var x = 3;
var currentDate = moment('01-Feb-2023'); // not a great value for moment
var lastDate = moment(currentDate).add(x, 'M').format("DD-MMM-YYYY");

console.info(lastDate)
<script src = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

Лучше: строгий режим устанавливается путем передачи true в качестве третьего параметра функции момента.

moment('02/01/2023', 'MM/DD/YYYY', true);

var x = 3;
var currentDate = moment('02/01/2023', 'MM/DD/YYYY', true); // better
var lastDate = moment(currentDate).add(x, 'M').format("DD-MMM-YYYY");

console.info(lastDate)
<script src = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

Без момента - обратите внимание, что new Date(dateString); ВСЕ ЕЩЕ не очень хорошая идея с "01-Feb-2023" из-за Почему Date.parse дает неверные результаты?

Но если с этим можно жить, то вот версия

const dateTimeFormat = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'short', day: 'numeric' });

const addToDate = (dateString, offset) => {
  const currentDate = new Date(dateString); // using the Date.parse. Moment warned it would use this
  currentDate.setHours(15, 0, 0, 0) // normalise
  currentDate.setMonth(currentDate.getMonth() + offset); // add the month
  const [month, sp1, day, comma, year] = dateTimeFormat.formatToParts(currentDate);
  return `${day.value}-${month.value}-${year.value}`; // There is no DD-MMM-YYYY in INTL so we make our own
}

let x = 3;
const lastDate = addToDate("01-Feb-2023", x);
console.info("01-Feb-2023 plus",x,"months:",lastDate)
new Date("01-Feb-2023") не очень хорошая идея, см. Почему Date.parse дает неверные результаты? При использовании moment.js нет необходимости менять формат входной метки времени, просто используйте правильные токены: «ДД-МММ-ГГГГ».
RobG 01.02.2023 15:17

@RobG Обратите внимание на предупреждение, которое мы получаем в первом примере: Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.

mplungjan 01.02.2023 15:52

Конечно, но синтаксический анализ с использованием moment(dateString, 'DD-MMM-YYYY') решает проблему заранее. ;-)

RobG 01.02.2023 23:33

Как и во втором примере. Я не уверен, почему недостаточно информации. Это в основном то, что я говорю в своем ответе.

mplungjan 02.02.2023 07:45

Другие вопросы по теме