Menambahkan jam ke objek Tanggal JavaScript?

401

Sungguh mengherankan saya bahwa objek Date JavaScript tidak mengimplementasikan fungsi tambahan apa pun.

Saya hanya ingin fungsi yang dapat melakukan ini:

var now = Date.now();
var fourHoursLater = now.addHours(4);

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

Saya hanya ingin beberapa petunjuk ke suatu arah.

  • Apakah saya perlu melakukan penguraian string?

  • Bisakah saya menggunakan setTime?

  • Bagaimana dengan milidetik?

Seperti ini:

new Date(milliseconds + 4*3600*1000 /*4 hrs in ms*/)?  

Ini tampaknya sangat retas - dan apakah itu bekerja?

Jeff Meatball Yang
sumber

Jawaban:

424

JavaScript sendiri memiliki API Tanggal / Waktu yang mengerikan. Meskipun demikian, Anda dapat melakukan ini dalam JavaScript murni:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}
Jason Harwig
sumber
Bekerja seperti pesona! Terima kasih
moreirapontocom
jika per mengatakan Anda menambahkan satu jam yang menyebabkannya berguling ke hari berikutnya, apakah ini akan menangkapnya dan menambah semuanya dengan benar (hari bulan tahun)?
cdoern
@doern saya pikir itu akan, karena getTime () akan mengembalikan milidetik dan Anda hanya menambahkan lebih banyak milidetik untuk itu
The1993
370
Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

Uji:

alert(new Date().addHours(4));
kennebec
sumber
25
Saya tidak berpikir ini bekerja --- mengujinya pada sesuatu dengan jam 23, misalnya? Jawaban Jason Harwig adalah apa yang terlintas dalam pikiran saya.
Domenic
11
Ini praktik buruk untuk menambahkan sesuatu ke prototipe objek dalam Javascript, dan Domenic benar, ini tidak berhasil. Solusi Jason Harwig di bawah ini lebih baik.
iKode
19
@Domenic Ini berfungsi baik dengan 23:00, diuji di dalam konsol JavaScript Firefox 10, Chrome 21 dan IE 8/9 Di sini kode yang saya gunakan untuk menguji: var date = new Date(2012, 10, 22, 23, 0, 1); date.toString(); // Thu Nov 22 2012 23:00:01 GMT+0100 (CET) date.setHours(date.getHours() + 1); date.toString(); // Fri Nov 23 2012 00:00:01 GMT+0100 (CET) Ini juga berfungsi dengan baik dengan setMinutes ()
tanguy_k
4
Terjadi masalah dengan solusi ini - Menambah 1 gagal bagi saya pada titik pergantian DST (jam bergerak maju satu jam).
andrewb
2
Juga digigit oleh ini - saya perulangan melalui jam dengan menggunakan setHours (getHours-1): sekarang, pada jam DST pertama, ini akhirnya menjadi loop tak terbatas. Jadi, periksa hasilnya!
cfstras
165

Kode di bawah ini untuk menambahkan 4 jam ke tanggal (contoh tanggal hari ini)

var today = new Date();
today.setHours(today.getHours() + 4);

Itu tidak akan menyebabkan kesalahan jika Anda mencoba menambahkan 4 hingga 23 (lihat dokumen ):

Jika parameter yang Anda tentukan berada di luar kisaran yang diharapkan, setHours () mencoba memperbarui informasi tanggal di objek Tanggal sesuai

SuperNova
sumber
Saya tidak melihat ini dan membuat jawaban rangkap. Saya suka metode ini. Tepat dan bermanfaat.
Gandalf si Putih
Ini sepertinya tidak berfungsi ketika
jamnya
3
Ini adalah jawaban terbaik di sini ... menambahkan "addHours" ke prototipe Date mengkhawatirkan karena pada titik tertentu JS mungkin menambahkan dukungan untuk fungsi itu dan kemudian Anda memiliki prototipe yang saling bertentangan. Ini memberi Anda fungsionalitas dengan menggunakan kode sebanyak mungkin.
Kris Boyd
terkejut, tapi itu sebenarnya menambah hari, berbulan-bulan jika perlu, tautan ke dokumen akan berguna
2oppin
4
Meskipun menggunakan nilai jam> 23 tidak mematahkan ini, namun tetap saja rusak pada batas penghematan siang hari . Mengingat itu rusak, tidak ada alasan untuk menggunakannya; lebih suka setTimeatau setUTCHour.
Mark Amery
40

Mungkin lebih baik untuk membuat metode addHours tidak berubah dengan mengembalikan salinan objek Date daripada memutasikan parameternya.

Date.prototype.addHours= function(h){
    var copiedDate = new Date(this.getTime());
    copiedDate.setHours(copiedDate.getHours()+h);
    return copiedDate;
}

Dengan cara ini Anda dapat membuat banyak panggilan metode tanpa khawatir tentang keadaan.

Tahir Hassan
sumber
Fungsi ini memiliki masalah yang sama seperti yang dinyatakan di sini stackoverflow.com/questions/1050720/... Ini tidak benar-benar tentang apakah itu bekerja pada browser tertentu, tapi tempat-tempat lain yang menggunakan Javascript melihat ini sebagai masalah. menyisir solusi Anda dengan ini stackoverflow.com/a/1050782/295535 tampaknya menjadi solusi terbaik
Ressu
1
Anda harus mempertimbangkan mengubah nama fungsi, karena kata add*tersebut biasanya digunakan untuk mengubah objek itu sendiri.
mr5
@ mr5 - tidak yakin tentang itu, adddigunakan dalam kelas .NET framework DateTime, dan memiliki arti yang sama dengan +(plus) dalam Matematika.
Tahir Hassan
1
currentDate.addHours(1)<- Dari insting pemrograman saya, saya mengharapkan currentDatenilai berubah, tetapi dalam implementasi Anda, itu tidak akan terjadi. Mengenai mengapa saya menyarankan untuk mengganti nama atau mengubah tanda tangannya menjadi sesuatu
mr5
1
@TahirHassan tidak ada hubungannya dengan detail teknis tetapi memilih kata yang tepat untuk digunakan untuk nama fungsi. Saya masih lebih suka versi yang bisa berubah ketika fungsi diawali denganadd
mr5
23

Versi yang disarankan oleh kennebec akan gagal ketika mengubah ke atau dari DST, karena itu adalah angka jam yang ditetapkan.

this.setUTCHours(this.getUTCHours()+h);

akan menambah hjam untuk thisindependen dari kekhasan sistem waktu. Metode Jason Harwig juga berfungsi.

petter
sumber
19

Anda dapat menggunakan perpustakaan momentjs http://momentjs.com/ .

var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
Cmag
sumber
7

Saya juga berpikir objek aslinya tidak boleh dimodifikasi. Jadi untuk menghemat tenaga kerja masa depan, inilah solusi gabungan berdasarkan jawaban Jason Harwig dan Tahir Hasan :

Date.prototype.addHours= function(h){
    var copiedDate = new Date();
    copiedDate.setTime(this.getTime() + (h*60*60*1000)); 
    return copiedDate;
}
Edward Olamisan
sumber
5

Ada tambahan di perpustakaan Datejs .

Dan inilah metode tanggal JavaScript . kennebec dengan bijak menyebutkan getHours () dan setHours ();

Nosredna
sumber
Perhatikan bahwa pustaka itu tampaknya dalam status alfa.
Sam
4

Periksa apakah belum ditentukan, atau tentukan di prototipe Date:

if (!Date.prototype.addHours) {
    Date.prototype.addHours = function(h) {
        this.setHours(this.getHours() + h);
        return this;
    };
}
Mikael Engver
sumber
3

Cara lain untuk mengatasinya adalah dengan mengubah tanggal menjadi unixtime (zaman), kemudian menambahkan yang setara dalam (mili) detik, kemudian mengubahnya kembali. Dengan cara ini Anda dapat menangani transisi hari dan bulan, seperti menambahkan 4 jam menjadi 21, yang akan menghasilkan hari berikutnya, 01:00.

SPRBRN
sumber
Anda benar - tetapi Anda juga terlambat beberapa tahun. Jawaban Jason Harwig menunjukkan metode ini 2 tahun sebelum Anda; jawaban ini menambahkan tidak ada yang baru.
Mark Amery
3

Untuk fungsi add / kurangi jam / menit sederhana dalam javascript, coba ini:

function getTime (addHour, addMin){
    addHour = (addHour?addHour:0);
    addMin = (addMin?addMin:0);
    var time = new Date(new Date().getTime());
    var AM = true;
    var ndble = 0;
    var hours, newHour, overHour, newMin, overMin;
    //change form 24 to 12 hour clock
    if(time.getHours() >= 13){
        hours = time.getHours() - 12;
        AM = (hours>=12?true:false);
    }else{
        hours = time.getHours();
        AM = (hours>=12?false:true);
    }
    //get the current minutes
    var minutes = time.getMinutes();
    // set minute
    if((minutes+addMin) >= 60 || (minutes+addMin)<0){
        overMin = (minutes+addMin)%60;
        overHour = Math.floor((minutes+addMin-Math.abs(overMin))/60);
        if(overMin<0){
            overMin = overMin+60;
            overHour = overHour-Math.floor(overMin/60);
        }
        newMin = String((overMin<10?'0':'')+overMin);
        addHour = addHour+overHour;
    }else{
        newMin = minutes+addMin;
        newMin = String((newMin<10?'0':'')+newMin);
    }
    //set hour
    if(( hours+addHour>=13 )||( hours+addHour<=0 )){
        overHour = (hours+addHour)%12;
        ndble = Math.floor(Math.abs((hours+addHour)/12));
        if(overHour<=0){
            newHour = overHour+12;
            if(overHour == 0){
                ndble++;
            }
        }else{
            if(overHour ==0 ){
                newHour = 12;
                ndble++;
            }else{
                ndble++;
                newHour = overHour;
            }
        }
        newHour = (newHour<10?'0':'')+String(newHour);
        AM = ((ndble+1)%2===0)?AM:!AM;
    }else{
        AM = (hours+addHour==12?!AM:AM);
        newHour = String((Number(hours)+addHour<10?'0':'')+(hours+addHour));
    }
    var am = (AM)?'AM':'PM';
    return new Array(newHour, newMin, am);
};

Ini dapat digunakan tanpa parameter untuk mendapatkan waktu saat ini

getTime();

atau dengan parameter untuk mendapatkan waktu dengan menit / jam tambahan

getTime(1,30); // adds 1.5 hours to current time
getTime(2);    // adds 2 hours to current time
getTime(0,120); // same as above

bahkan waktu negatif bekerja

getTime(-1, -30); // subtracts 1.5 hours from current time

fungsi ini mengembalikan array

array([Hour], [Minute], [Meridian])
durkinza
sumber
Apa keuntungan yang dimiliki monster 56 baris fungsi ini daripada pendekatan dua baris dalam jawaban terpilih ? -1 karena ada kompleksitas ekstra besar di sini tanpa manfaat yang dapat saya lihat.
Mark Amery
1

SPRBRN benar. Untuk memperhitungkan awal / akhir bulan dan tahun, Anda harus mengonversi ke Zaman dan kembali.

Begini cara Anda melakukannya:

var milliseconds = 0;          //amount of time from current date/time
var sec = 0;                   //(+): future
var min = 0;                   //(-): past
var hours = 2;
var days = 0;

var startDate = new Date();     //start date in local time (we'll use current time as an example)

var time = startDate.getTime(); //convert to milliseconds since epoch

//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24)

var newDate = new Date(newTime);//convert back to date; in this example: 2 hours from right now


atau melakukannya dalam satu baris (di mana nama variabel sama seperti di atas:

var newDate = 
    new Date(startDate.getTime() + millisecond + 
        1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
JED
sumber
0

Ini adalah cara mudah untuk mendapatkan nilai data yang bertambah atau berkurang.

const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour

const _date = new Date(date)
return new Date( _date.getTime() + inc )
return new Date( _date.getTime() + dec )
Henrique Van Klaveren
sumber
-1

Sedikit berantakan, tapi berhasil!

Diberi format tanggal seperti ini: 2019-04-03T15: 58

  //Get the start date.
  var start = $("#start_date").val();
  //Split the date and time.
  var startarray = start.split("T");
  var date = startarray[0];
  var time = startarray[1];

  //Split the hours and minutes.
  var timearray = time.split(":");

  var hour = timearray[0];
  var minute = timearray[1];
  //Add an hour to the hour.
  hour++;
  //$("#end_date").val = start;
  $("#end_date").val(""+date+"T"+hour+":"+minute+"");

Output Anda akan menjadi: 2019-04-03T16: 58

Carl Du Plessis
sumber