Odejmij dni od daty w JavaScript

603

Czy ktoś wie o łatwym sposobie umawiania się na randki (np. Dzisiaj) i cofania się o X dni?

Na przykład, jeśli chcę obliczyć datę 5 dni przed dzisiaj.

jonhobbs
źródło
4
Znalazłem problemy przy użyciu zaakceptowanej odpowiedzi. Najwyraźniej użycie ujemnych wartości w setDate () nie działa zgodnie z oczekiwaniami. Zobacz stackoverflow.com/a/9037132/792287, aby znaleźć inne (lepsze?) Rozwiązanie.
vandiedakaf
5
Możliwy duplikat: stackoverflow.com/questions/1187824/...
Anderson Green
Sprawdź github.com/viebig/datetreta
Guilherme Viebig

Odpowiedzi:

961

Wypróbuj coś takiego:

 var d = new Date();
 d.setDate(d.getDate()-5);

Zauważ, że modyfikuje to obiekt daty i zwraca wartość czasu zaktualizowanej daty.

var d = new Date();

document.write('Today is: ' + d.toLocaleString());

d.setDate(d.getDate() - 5);

document.write('<br>5 days ago was: ' + d.toLocaleString());

Stephen Wrighton
źródło
9
Wynik tego daje mi długi ciąg liczb całkowitych. Masz pomysł, jak sformatować go do 14.05.2012?
user525146
162
Biorąc pod uwagę, że jest to na górze Google, myślę, że odpowiedziałbym na powyższy komentarz: new Date(new Date().setDate(new Date().getDate()-5))- to będzie 5 dni temu. W przykładzie odpowiedzi przekaż ją do nowej daty, aby uzyskać obiekt daty. Właśnie new Date(d)tego chcesz.
Jesse
8
Problem w tym, że możesz skończyć na 00, co nie jest prawidłową wartością daty.
DominicM
24
setDate(-1)wyznaczy datę ostatniego dnia miesiąca
Peter
5
@ user525146 zapytał, jak sformatować numer, a nie jaki jest numer. Nie ma potrzeby protekcjonalnych odpowiedzi. Aby sformatować liczbę, jeden wykorzystywanie daty toStringmetod, takich jak toISOString, toDateStringitp
Bad Request
83
var dateOffset = (24*60*60*1000) * 5; //5 days
var myDate = new Date();
myDate.setTime(myDate.getTime() - dateOffset);

Jeśli wykonujesz wiele kłopotliwych manipulacji datami w swojej aplikacji internetowej, DateJS znacznie ułatwi Ci życie:

http://simonwillison.net/2007/Dec/3/datejs/

karim79
źródło
23
jest to przypadek na krawędzi, ale może się nie powieść na początku / na końcu czasu letniego. nie odejmujesz 5 dni, ale 5 * 24 godzin. pierwszy dzień czasu letniego trwa tylko 23 godziny, a ostatni 25 godzin. to zwykle nie ma znaczenia, ale należy wziąć pod uwagę.
Kip
11
@Kip Nienawidzę czasu letniego ... i stref czasowych. Wszyscy powinniśmy przejść na GMT.
cwallenpoole
6
@cwallenpoole, aby nie rozerwać bańki, ale używają DST nawet w Greenwich. Więc jeśli naprawdę chcesz być na GMT, jesteś ograniczony do Islandii i kilku krajów Afryki Zachodniej.
Kip
1
Problem z tą metodą polega na tym, że nie działa z nowym rokiem itp.
Daniel Williams
4
@danielWilliams Jak to nie działa z nowym rokiem? getTime()i setTime()są milisekundami od epoki. Nie powinno mieć znaczenia, czy czas przekroczy granicę roku.
Mashmagar,
52

Wygląda to mniej więcej tak:

var d = new Date(); // today!
var x = 5; // go back 5 days!
d.setDate(d.getDate() - x);
Chris Nielsen
źródło
Wynik tego daje mi długi ciąg liczb całkowitych. Masz pomysł, jak sformatować go do 14.05.2012?
user525146
7
Zwracana wartość d.setDate jest rzeczywiście liczbą całkowitą. Jednak prawdopodobnie nie interesuje Cię w tym momencie wartość zwracana, ponieważ rzeczywista wartość „d” została zmodyfikowana. Twoje prawdziwe pytanie brzmi: jak sformatować datę, która jest teraz w „d”, a nie w ogóle wartość zwracaną przez setDate. (Cóż, w rzeczywistości jest to wartość zwracana, ale do tego momentu nie jest to data i nie chcę cię mylić - po prostu użyj d, będzie szybciej). Do formatowania dat potrzebne są metody d.getMonth (), d.getFullYear () i d.getDate (). Chcesz dodać jeden do d.getMonth (), ponieważ Jan ma 0.
Chris Nielsen
2
Jako prosta metoda: function getDaysAgo(b){var a=new Date;a.setDate(a.getDate()-b);return a};następnievar daysAgo45 = getDaysAgo(45);
SpYk3HH
@MiroKrsjak Oczywiście działa to, jeśli przekroczysz koniec / początek miesiąca. Dlaczego to nie zadziała?
Chris Nielsen
23

Zauważyłem, że getDays + X nie działa w granicach dnia / miesiąca. Korzystanie z getTime działa tak długo, jak twoja data nie jest wcześniejsza niż 1970.

var todayDate = new Date(), weekDate = new Date();
weekDate.setTime(todayDate.getTime()-(7*24*3600000));
awjr
źródło
3
Zauważyłem to samo. Jestem zaskoczony, że jeszcze nie, czy coś mi brakuje?
Sean Glover,
11
Jest to niepoprawne, nowa data (). SetDate (-1) da ci ostatni dzień poprzedniego miesiąca.
zbrunson
2
Jest to również niepoprawne w przypadku krawędzi początku / końca czasu letniego. Twoje podejście odejmuje 7 * 24 godzin, przy założeniu, że każdy dzień ma 24 godziny. Pierwszy dzień DST trwa tylko 23 godziny, a ostatni dzień 25 godzin. setDate (getDate () - 7) nie ma tego problemu.
Kip
1
getTime działa poza czasem uniwersalnym. Więc poprawnie odejmie 7 dni od obiektu Date. Po przekonwertowaniu go na ciąg znaków w określonej strefie czasowej poprawnie wyświetli godzinę dla tej strefy.
awjr
Uważaj na dzień zmiany czasu. Kiedy upadniemy jesienią, ten dzień ma 25 godzin, więc odjęcie 24 godzin od północy wyląduje w tym samym dniu. Ale ta technika (odejmowanie milisekund) DZIAŁA, jeśli zaokrąglisz dzień po każdej operacji do najbliższej północy. Możesz to zrobić, dodając najpierw 12 godzin, a następnie ustawiając godziny na zero.
Magmatic,
18

get moment.js. Korzystają z niego wszystkie fajne dzieciaki. Ma więcej opcji formatowania itp. Gdzie

var n = 5;
var dateMnsFive = moment(<your date>).subtract(n , 'day');

Opcjonalny! Konwertuj na JS Data obj w celu powiązania kątowego.

var date = new Date(dateMnsFive.toISOString());

Opcjonalny! Format

var date = dateMnsFive.format("YYYY-MM-DD");
Kentonbmax
źródło
przekazując datę w mgnieniu oka, zaczniesz otrzymywać ostrzeżenia. Ostrzeżenie o rezygnacji: podana wartość nie ma rozpoznanego formatu RFC2822 lub ISO. konstrukcja moment wraca do js Date (), która nie jest niezawodna we wszystkich przeglądarkach i wersjach. Formaty daty inne niż RFC2822 / ISO są odradzane i zostaną usunięte w nadchodzącym wydaniu głównym. Więcej informacji można znaleźć na stronie momentjs.com/guides/#/warnings/js-date .
Przełącz
13

Zrobiłem ten prototyp dla Date, aby móc przekazywać wartości ujemne, aby odjąć dni, a wartości dodatnie, aby dodać dni.

if(!Date.prototype.adjustDate){
    Date.prototype.adjustDate = function(days){
        var date;

        days = days || 0;

        if(days === 0){
            date = new Date( this.getTime() );
        } else if(days > 0) {
            date = new Date( this.getTime() );

            date.setDate(date.getDate() + days);
        } else {
            date = new Date(
                this.getFullYear(),
                this.getMonth(),
                this.getDate() - Math.abs(days),
                this.getHours(),
                this.getMinutes(),
                this.getSeconds(),
                this.getMilliseconds()
            );
        }

        this.setTime(date.getTime());

        return this;
    };
}

Aby go użyć, mogę po prostu napisać:

var date_subtract = new Date().adjustDate(-4),
    date_add = new Date().adjustDate(4);
Rob Dawley
źródło
2
Możesz używać d.setDate(d.getDate() + days)zarówno wartości dodatnich, jak i ujemnych dla dni, aby odpowiednio dodawać i odejmować dni. Powinien on działać na instancji (podobnie jak inne metody Date), a nie tworzyć i zwracać kopii.
RobG
13

Kilka istniejących rozwiązań było blisko, ale niezupełnie tego, czego chciałem. Ta funkcja działa zarówno z wartościami dodatnimi, jak i ujemnymi i obsługuje przypadki graniczne.

function addDays(date, days) {
    return new Date(
        date.getFullYear(),
        date.getMonth(),
        date.getDate() + days,
        date.getHours(),
        date.getMinutes(),
        date.getSeconds(),
        date.getMilliseconds()
    );
}
Joel Fillmore
źródło
2
czy „rozleje się” na następny miesiąc, jeśli użyję tej metody, aby dodać 20 dni do 15 dnia bieżącego miesiąca? Nie wydaje się.
Bora,
2
@Bora - tak, w razie potrzeby poprawnie zwiększa miesiąc. Na przykład dodanie 20 dni do 15 sierpnia: addDays (nowa data (2015, 07, 15), 20) zwróci „Pt 04 września 2015 00:00:00 GMT-0700 (PDT)”
Joel Fillmore
12

Lubię robić matematyki w milisekundach. Więc użyjDate.now()

var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds

a jeśli ci się podoba to sformatowane

new Date(newDate).toString(); // or .toUTCString or .toISOString ...

UWAGA: Date.now()nie działa w starszych przeglądarkach (np. Myślę, że IE8).Polyfill tutaj .

AKTUALIZACJA Czerwiec 2015

@socketpair zwrócił uwagę na moją niechlujność. Jak mówi: „Pewnego dnia w roku mają 23 godziny, a około 25 ze względu na reguły strefy czasowej”.

Aby rozwinąć tę kwestię, powyższa odpowiedź będzie zawierała niedokładności dotyczące czasu letniego w przypadku, gdy chcesz obliczyć LOKALNY dzień 5 dni temu w strefie czasowej ze zmianami czasu letniego, a Ty

  • zakładamy (błędnie), że Date.now()daje bieżący LOKALNY czas teraz, lub
  • użycie, .toString()które zwraca lokalną datę i dlatego jest niezgodne z Date.now()datą podstawową w UTC.

Działa to jednak, jeśli robisz matematykę w UTC, np

A. Chcesz mieć datę UTC 5 dni temu od TERAZ (UTC)

var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds UTC
new Date(newDate).toUTCString(); // or .toISOString(), BUT NOT toString

B. Zaczynasz z datą bazową UTC inną niż „teraz”, używając Date.UTC()

newDate = new Date(Date.UTC(2015, 3, 1)).getTime() + -5*24*3600000;
new Date(newDate).toUTCString(); // or .toISOString BUT NOT toString
najszerszy
źródło
3
To nie jest precyzyjne. Niektóre dni w roku mają 23 godziny, a około 25 ze względu na reguły strefy czasowej.
socketpair
Mógłbym się martwić o warunki awarii, gdy są sekundy przestępne ... więc może nie jest dobre dla kodu krytycznego.
robocat
12

Znalazłem problem z metodą getDate () / setDate () polegającą na tym, że zbyt łatwo zamienia wszystko w milisekundy, a czasem trudno jest mi przestrzegać składni.

Zamiast tego chciałbym zrezygnować z faktu, że 1 dzień = 86 400 000 milisekund.

Zatem w przypadku konkretnego pytania:

today = new Date()
days = 86400000 //number of milliseconds in a day
fiveDaysAgo = new Date(today - (5*days))

Działa jak marzenie.

Cały czas używam tej metody do wykonywania ciągłych obliczeń na 30/60/365 dni.

Możesz łatwo ekstrapolować to, aby stworzyć jednostki czasu dla miesięcy, lat itp.

Jonathan Bechtel
źródło
11

podziel datę na części, a następnie zwróć nową datę ze skorygowanymi wartościami

function DateAdd(date, type, amount){
    var y = date.getFullYear(),
        m = date.getMonth(),
        d = date.getDate();
    if(type === 'y'){
        y += amount;
    };
    if(type === 'm'){
        m += amount;
    };
    if(type === 'd'){
        d += amount;
    };
    return new Date(y, m, d);
}

Pamiętaj, że miesiące liczone są od zera, ale dni nie. tj. nowa data (2009, 1, 1) == 01 lutego 2009 r., nowa data (2009, 1, 0) == 31 stycznia 2009 r .;

Jozuego
źródło
2
Co się stanie, jeśli dodasz na przykład 50 dni do daty w ten sposób? Czy wyznaczy datę na 68 sierpnia 2009 r.? A może masz pewność, że zawsze będzie to poprawnie łączyć się z odpowiednim miesiącem i / lub rokiem?
Jesper
Służyło to do dodawania addDays, addMonths i addYears to Date.prototype. Ładne i proste.
Scott Isaacs
1
To powinna być poprawna odpowiedź - działa nawet w ostatnim dniu roku, w którym przyjęta odpowiedź nie powiedzie się.
Kris,
Nie działa dla dat z latami od 1 do 99. ;-) Znacznie lepiej jest po prostu użyć metod get * i set * .
RobG
8

Bez korzystania z drugiej zmiennej możesz zastąpić 7 przez wstecz x dniami:

let d=new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))
vaibhavmaster
źródło
5

function addDays (date, daysToAdd) {
  var _24HoursInMilliseconds = 86400000;
  return new Date(date.getTime() + daysToAdd * _24HoursInMilliseconds);
};

var now = new Date();

var yesterday = addDays(now, - 1);

var tomorrow = addDays(now, 1);

Petr Makarov
źródło
2

Utworzyłem funkcję do manipulowania datami. możesz dodawać lub odejmować dowolną liczbę dni, godzin, minut.

function dateManipulation(date, days, hrs, mins, operator) {
   date = new Date(date);
   if (operator == "-") {
      var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
      var newDate = new Date(date.getTime() - durationInMs);
   } else {
      var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
      var newDate = new Date(date.getTime() + durationInMs);
   }
   return newDate;
 }

Teraz wywołaj tę funkcję, przekazując parametry. Na przykład tutaj jest wywołanie funkcji umożliwiające uzyskanie daty przed 3 dniami od dzisiaj.

var today = new Date();
var newDate = dateManipulation(today, 3, 0, 0, "-");
Malvi Panchal
źródło
2

Użyj MomentJS .

function getXDaysBeforeDate(referenceDate, x) {
  return moment(referenceDate).subtract(x , 'day').format('MMMM Do YYYY, h:mm:ss a');
}

var yourDate = new Date(); // let's say today
var valueOfX = 7; // let's say 7 days before

console.log(getXDaysBeforeDate(yourDate, valueOfX));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

UtkarshPramodGupta
źródło
1

Najlepsze odpowiedzi doprowadziły do ​​błędu w moim kodzie, w którym pierwszego miesiąca ustawiałaby przyszłą datę w bieżącym miesiącu. Oto co zrobiłem

curDate = new Date(); // Took current date as an example
prvDate = new Date(0); // Date set to epoch 0
prvDate.setUTCMilliseconds((curDate - (5 * 24 * 60 * 60 * 1000))); //Set epoch time
Kishore Avineni
źródło
0

Łatwym sposobem na zarządzanie datami jest użycie Moment.js

Możesz użyć add. Przykład

var startdate = "20.03.2014";
var new_date = moment(startdate, "DD.MM.YYYY");
new_date.add(5, 'days'); //Add 5 days to start date
alert(new_date);

Dokumenty http://momentjs.com/docs/#/manipicing/add/

Juan Caicedo
źródło
0

Lubię następujące, ponieważ jest to jedna linia. Nie idealny ze zmianami DST, ale zwykle wystarczająco dobry dla moich potrzeb.

var fiveDaysAgo = new Date(new Date() - (1000*60*60*24*5));
ScottE
źródło
0

dla mnie wszystkie kombinacje działały dobrze z poniższym fragmentem kodu, fragment jest przeznaczony do implementacji Angular-2, jeśli chcesz dodać dni, przekazać dodatnią liczbę dni, jeśli chcesz odjąć przekazać liczbę ujemną dni

function addSubstractDays(date: Date, numberofDays: number): Date {
let d = new Date(date);
return new Date(
    d.getFullYear(),
    d.getMonth(),
    (d.getDate() + numberofDays)
);
}
pritesh agrawal
źródło
0

Mam dobry przebieg z date.js:

http://www.datejs.com/

d = new Date();
d.add(-10).days();  // subtract 10 days

Miły!

Strona zawiera to piękno:

Datejs nie tylko analizuje ciągi, ale dzieli je na dwie części

Bret Weinraub
źródło
0

Jeśli chcesz odjąć liczbę dni i sformatować datę w formacie czytelnym dla człowieka, powinieneś rozważyć utworzenie niestandardowego DateHelperobiektu, który wygląda mniej więcej tak:

var DateHelper = {
    addDays : function(aDate, numberOfDays) {
        aDate.setDate(aDate.getDate() + numberOfDays); // Add numberOfDays
        return aDate;                                  // Return the date
    },
    format : function format(date) {
        return [
           ("0" + date.getDate()).slice(-2),           // Get day and pad it with zeroes
           ("0" + (date.getMonth()+1)).slice(-2),      // Get month and pad it with zeroes
           date.getFullYear()                          // Get full year
        ].join('/');                                   // Glue the pieces together
    }
}

// With this helper, you can now just use one line of readable code to :
// ---------------------------------------------------------------------
// 1. Get the current date
// 2. Subtract 5 days
// 3. Format it
// 4. Output it
// ---------------------------------------------------------------------
document.body.innerHTML = DateHelper.format(DateHelper.addDays(new Date(), -5));

(zobacz także to skrzypce )

John Slegers
źródło
0

Zobacz poniższy kod, odejmij dni od bieżącej daty. Ustaw także miesiąc zgodnie z odjętą datą.

var today = new Date();
var substract_no_of_days = 25;

today.setTime(today.getTime() - substract_no_of_days* 24 * 60 * 60 * 1000);
var substracted_date = (today.getMonth()+1) + "/" +today.getDate() + "/" + today.getFullYear();

alert(substracted_date);
Manoj Jha
źródło
-1

Podczas ustawiania daty data jest konwertowana na milisekundy, więc musisz przekonwertować ją z powrotem na datę:

Ta metoda uwzględnia również zmianę nowego roku itp.

function addDays( date, days ) {
    var dateInMs = date.setDate(date.getDate() - days);
    return new Date(dateInMs);
}

var date_from = new Date();
var date_to = addDays( new Date(), parseInt(days) );
Daniel Williams
źródło
-1

Możesz używać Javascript.

var CurrDate = new Date(); // Current Date
var numberOfDays = 5;
var days = CurrDate.setDate(CurrDate.getDate() + numberOfDays);
alert(days); // It will print 5 days before today

Dla PHP

$date =  date('Y-m-d', strtotime("-5 days")); // it shows 5 days before today.
echo $date;

Mam nadzieję, że ci to pomoże.

Feniks
źródło
-1

Przeliczyłem na milisekundę i odliczyłem dni, w przeciwnym razie miesiąc i rok nie zmienią się i nie będą logiczne

var numberOfDays = 10;//number of days need to deducted or added
var date = "01-01-2018"// date need to change
var dt = new Date(parseInt(date.substring(6), 10),        // Year
              parseInt(date.substring(3,5), 10) - 1, // Month (0-11)
              parseInt(date.substring(0,2), 10));
var new_dt = dt.setMilliseconds(dt.getMilliseconds() - numberOfDays*24*60*60*1000);
new_dt = new Date(new_dt);
var changed_date = new_dt.getDate()+"-"+(new_dt.getMonth()+1)+"-"+new_dt.getFullYear();

Nadzieja pomaga

hemanjosko
źródło
-1

var date = new Date();
var day = date.getDate();
var mnth = date.getMonth() + 1;

var fDate = day + '/' + mnth + '/' + date.getFullYear();
document.write('Today is: ' + fDate);
var subDate = date.setDate(date.getDate() - 1);
var todate = new Date(subDate);
var today = todate.getDate();
var tomnth = todate.getMonth() + 1;
var endDate = today + '/' + tomnth + '/' + todate.getFullYear();
document.write('<br>1 days ago was: ' + endDate );

Belal Ahmad
źródło
1
Zawsze powinieneś komentować swój kod / odpowiedź, ponieważ niektórzy ludzie mogą nie dostać tego, co robisz
Michael
-1

Używanie nowoczesnej składni funkcji JavaScript

const getDaysPastDate = (daysBefore, date = new Date) => new Date(date - (1000 * 60 * 60 * 24 * daysBefore));

console.log(getDaysPastDate(1)); // yesterday

Vdegenne
źródło
-1

Spróbuj czegoś takiego

dateLimit = (curDate, limit) => {
    offset  = curDate.getDate() + limit
    return new Date( curDate.setDate( offset) )
}

currDate może być dowolną datą

limit może być różnicą liczby dni (dodatnia dla przyszłości i ujemna dla przeszłości)

wahid_abdul
źródło
-1

To daje wynik z ostatnich 10 dni 110% pracy nie dostaniesz żadnego rodzaju problemu

var date = new Date();
var day=date.getDate();
var month=date.getMonth() + 1;
var year=date.getFullYear();
var startDate=day+"/"+month+"/"+year;
var dayBeforeNineDays=moment().subtract(10, 'days').format('DD/MM/YYYY');
startDate=dayBeforeNineDays;
var endDate=day+"/"+month+"/"+year;

możesz zmienić dni odejmowania zgodnie ze swoimi wymaganiami

Zubair
źródło
-2
var daysToSubtract = 3;
$.datepicker.formatDate('yy/mm/dd', new Date() - daysToSubtract) ;
SirWaltmore III
źródło
-2

var d = new Date();

document.write('Today is: ' + d.toLocaleString());

d.setDate(d.getDate() - 31);

document.write('<br>5 days ago was: ' + d.toLocaleString());

gatlingovind
źródło