Проверка того, прошел ли месяц с даты в строковом формате(JS)

0

Вопрос

В моем приложении JavaScript я получаю дату в строковом формате, например: 19/10/2021 (дд/мм/гггг). Я хочу проверить, прошел ли месяц с указанной даты, и вернуть значение true, если да. Я пытаюсь сделать что-то вроде следующего кода, но он не работает.

Я получаю некоторые странные значения, когда пытаюсь отладить его с помощью консоли.журналы и тому подобное, я новичок в js, поэтому я не знаю, где я делаю что-то неправильно.

var q = new Date();
var d = q.getDate();
var m = q.getMonth() + 1; //+1 because january is 0 and etc
var y = q.getFullYear();

var today = new Date(d, m, y);

mydate = userDate; // this is the string the app is receiving

if (today - mydate > 30) {
    return true;
} else {
    return false;
}

Заранее спасибо.

date javascript
2021-11-23 20:24:55
5
0

Попробуйте это:

    var q = new Date();
    var d = q.getDate();
    var m = q.getMonth(); 
    var y = q.getFullYear();
    var today = new Date(y,m,d);
    var mydate = new Date("2021-11-22"); 
    if(((today - mydate)/ (1000 * 60 * 60 * 24)) > 30)
    {
        return true;
    }
    else
    {
      return false;
    }
2021-11-23 20:53:55
0

Во-первых, когда вы установите q Для new Date() это сегодня. Нет необходимости извлекать из него день, месяц и год, а затем устанавливать его снова. Так что на сегодня вы можете просто сделать var today = new Date().

Во-вторых, вы должны перейти к дате() y,m,d и не d,m,y.

В-третьих, если вы вычтете одну дату из другой, расчет будет производиться в миллисекундах, а не в днях.

Это должно сработать:

var userDate = '19/10/2021';
var myDate = new Date(userDate.split('/').reverse());
var today = new Date();

var thirtyDays = 1000*60*60*24*30;

return today - myDate > thirtyDays;
2021-11-23 22:09:04

new Date(userDate.split('/').reverse()) почти наверняка вернет неверную дату.
RobG

@RobG если userDate-это строка в формате дд/мм/гггг, то userDate.split('/').reverse() вернет массив, подобный [yyyy,mm,dd]. и это то, что конструктор Date() получает в качестве параметров.
Mordy Stern

Вы передаете одно значение, массив. См. ECMA-262 и мой комментарий к этому ответу.
RobG
0

Поскольку определение "возраст в месяцах"... гибкое, самый простой способ-использовать небольшую арифметику, как вы бы вычислили ее в уме, и не включать Date класс.

Для [а] человеческой интерпретации "возраста в месяцах" правило таково

  • Вычислите разницу между двумя датами в месяцах, как если бы день месяца был 1-м числом месяца для обеих дат

  • Вычтите 1, чтобы исключить последний месяц

  • Затем, если день месяца последнего дня периода приходится на день месяца первого дня периода или после него, [потенциально частичный] последний месяц завершен: добавьте 1, чтобы восстановить счетчик

Одна ложка дегтя в бочке меда заключается в том, что месяцы содержат разное количество дней, что касается случаев, когда 2 месяца отличаются по количеству дней.

Однако, если конечный месяц короче начального, вы можете оказаться в ситуации, когда граничное условие никогда не может быть выполнено (например, дата начала-28 февраля, а дата окончания-31 марта. Чтобы исправить это, вам нужно посмотреть на "конец месяца" как на окно в диапазоне от последнего дня начального месяца до последнего дня последнего месяца включительно.

Это приводит к следующему коду. Я использую структуру, подобную следующей, для представления даты:

{
  year:  2021 , // 4-digit year
  month:   11 , // month of year (1-12 mapping to January-December)
  day:     23   // day of month (1-[28-31] depending on year/month
}

Обеспечение того, чтобы данные в этой структуре представляли действительную дату, оставляется в качестве упражнения для читателя.

Код не такой уж сложный:

/**
 * 
 * @param {object} bgn       - start date of period
 * @param {number} bgn.year  - 4-digit year
 * @param {number} bgn.month - month of year [1-12]
 * @param {number} bgn.day   - day of month [1-31]
 * 
 * @param {object} end       - end date of period
 * @param {number} end.year  - 4-digit year
 * @param {number} end.month - month of year [1-12]
 * @param {number} end.day   - day of month [1-31]
 * 
*/
function diffInMonths( bgn , end ) {
  const between = ( x , min , max ) => x >= min && x <= max;

  // We'll need to add back the final month based on the following:
  // - end.day >=  bgn.day -- we've passed the month boundary, or
  // - end.day is within the end-of-month window
  //   (when the end month is shorter than the start month)
  const needAdjustment = end.day >= bgn.day
    || between( end.day, daysInMonth(bgn), daysInMonth(end) );
  const finalMonthAdjustment = needsAdjustment ? 1 : 0;

  const deltaM = 12 * ( end.year - bgn.year )
    + ( end.month - bgn.month )
    - 1                    // remove the final month from the equation
    + finalMonthAdjustment // add in the precomputed final month adjustment
    ;

  return deltaM;
}

/**
 * 
 * @param {object} dt       - date
 * @param {number} dt.year  - 4-digit year
 * @param {number} dt.month - month of year [1-12]
 * @param {number} dt.day   - day of month [1-31]
 *
 */
function daysInMonth(dt) {
  const leapYear = ( dt.year % 4 === 0 && dt.year % 100 !== 0 ) || dt.year % 400 === 0;
  const monthDays = leapYear ? daysPerMonthLeap : daysPerMonth;
  const days = monthDays[dt.month];
  return days;
}
//                                    jan feb mar apr may jun jul aug sep oct nov dec
//                         ---------- --- --- --- --- --- --- --- --- --- --- --- ---
const daysPerMonth     = [ undefined, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ];
const daysPerMonthLeap = [ undefined, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ];
2021-11-23 20:49:22
-1

Проблема в том, что вы вычитаете строку из даты. Вам нужно, чтобы моя дата была того же типа, что и сегодня.

mydate = new Date(userDate)

(Примечание: Это работает только с форматом "месяц/день/год"

2021-11-24 04:30:59

"Это работает только с форматом" месяц/день/год "" неверно, встроенные анализаторы будут анализировать (правильно или иначе) множество форматов, часто с разными результатами. Общий совет: "не используйте встроенный синтаксический анализатор", разбор d/m/y вручную не составляет труда.
RobG
-1

Если ваша дата в этом формате (19/10/2021), вы можете сначала извлечь их.

const thOneMonth = 1000*60*60*24*31 //31 days in milliseconds
let formated = '19/10/2021'.split('/')
let date = Date.parse(formated[2], formated[1]-1, formated[0])
let date2 = 1634591678400 //date + 2678400000 a month later. This is in UNIX format.
if(date + thOneMonth == date2 ){//31 days 
  //A month have passed  
  console.log(date + thOneMonth )
}

Если вы хотите знать, например, 12 сентября, а следующая дата-12 октября, вы должны учитывать, что сентябрь длится 30 дней. Вы должны проверить на основе 31/30/29/28-дневных месяцев.


const thMonth = 1000*60*60*24*30 //30 days in milliseconds
let formated = '19/10/2021'.split('/')
let date = new Date(formated[2], formated[1]-1, formated[0])// make months start from 0
let date2 = 1634591678400 //date + 2678400000 a month later
if([5,7,10,12].includes(date.getMonth()+1) && Date.parse(date) + thMonth == date2 ){ // 30 days months 1000*60*60*24*30 //it won't enter here
  //A month have passed  
  console.log(date + thMonth)
}

2021-11-23 20:59:52

Date.parse('19/10/2021'.split('/').reverse()) имеет серьезные недостатки, это эффективно Date.parse('2021,10,19') что вернет NaN по крайней мере в некоторых, если не во всех, реализациях. Посмотрите, почему Date.parse дает неправильные результаты? и MDN: Дата.разбор.
RobG

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................