Kontrola, zda měsíc uplynul od datum ve formátu řetězce(JS)

0

Otázka

V mé Javascriptové aplikace, přijímám data v řetězec formátu, jako je tento: 19/10/2021 (dd/mm/rrrr). Chtěl bych zjistit, jestli měsíc uplynul od data a vrátí pravda, pokud se tak. Snažím něco jako následující kód, ale nefunguje to.

Dostávám nějaké divné hodnoty, když se snažím ladění s konzole.protokoly a tak, jsem nováček v js, takže nevím, kde dělám věci špatně.

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;
}

Díky předem.

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

Zkuste toto:

    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

První, kdy jste nastavili q k new Date() to je dnes. Není třeba, aby se z ní den, měsíc a rok a nastavte ji znovu. Tak pro dnešek stačí udělat var today = new Date().

Secound, měli byste projít do Date() y,m,d a ne d,m,y.

Za třetí, pokud jste odečíst data z jiného, bude výpočet na milisecounds, ne dny.

Tohle by mělo fungovat:

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()) bude téměř jistě vrátí chybu neplatné Datum.
RobG

@RobG pokud userDate je řetězec ve formátu dd/mm/rrrr, pak userDate.split('/').reverse() vrací pole jako [yyyy,mm,dd]. a to je to, co Date() konstruktor dostává jako parametry.
Mordy Stern

Jste kolem jedné hodnoty, pole. Viz ECMA-262 a můj komentář na tuto odpověď.
RobG
0

Protože definice "věk v měsících"... flexibilní, nejjednodušší způsob, jak je použít trochu aritmetiky, jako byste to spočítat v hlavě, a ne zapojit Date třídy.

Pro [a] lidské interpretace "věk v měsících", pravidlo je

  • Vypočítat rozdíl mezi dvěma daty v měsících, jako kdyby den-of-the-měsíc byl 1 měsíc pro obě data

  • Odečíst 1 vyloučit poslední měsíc

  • Pak, pokud den-of-the-měsíc poslední den období je na nebo po celý den-of-the-měsíc v první den období, [potenciálně částečné] poslední měsíc je kompletní: přidejte 1 obnovit počítat

Ten, létat v masti je, že od měsíce obsahují různé počty dní, které se zabývají případy, kdy 2 měsíce se liší v jejich počtu dní.

Pokud, nicméně, do konce měsíce je kratší než na začátku měsíce, můžete se dostat do situace, kdy okrajová podmínka nemůže být nikdy splněna (např. počáteční datum je 28. února a datum ukončení je 31. Března. Chcete-li to, musíte se podívat na "konci měsíce" jako okna od posledního dne začátku měsíce přes poslední den na konci měsíce včetně.

To vede k tomuto kódu. Používám strukturu, jako na následujícím představují datum:

{
  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
}

Zajištění toho, že údaje v tomto struct představuje platné datum je ponechán jako cvičení pro čtenáře.

Kód není tak složité:

/**
 * 
 * @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

Problém je, že jste odečtením řetězec od data. Potřebujete mydate být stejné typu jako dnes.

mydate = new Date(userDate)

(Poznámka: To funguje pouze s 'měsíc/den/rok formát

2021-11-24 04:30:59

"To funguje pouze s 'měsíc/den/rok formát" není správné, vestavěné analyzátory bude parse (správně nebo jinak), velké množství formátů, často s rozdílnými výsledky. Obecná rada zní "nepoužívejte vestavěný parser", ručně rozebrat d/m/y, není těžké.
RobG
-1

Pokud je vaše datum v tomto formátu (19/10/2021) můžete nejprve extrahovat.

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 )
}

Pokud chcete vědět, jestli je to například 12. září a další datum je 12. října, Budete muset zvážit, že září je 30 dní. Budete muset zkontrolovat na základě 31/30/29/28-den měsíce.


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()) je vážně špatný, je účinně Date.parse('2021,10,19') který se vrátí NaN alespoň některé, pokud ne všechny, implementace. Vidět, Proč to Datum.analyzovat dát nesprávné výsledky? a MDN: Datum.parse.
RobG

V jiných jazycích

Tato stránka je v jiných jazycích

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