การเพิ่มชั่วโมงให้กับวัตถุวันที่ของ JavaScript?


399

มันทำให้ฉันประหลาดใจว่าอ็อบเจกต์ Date ของ JavaScript ไม่ได้ใช้ฟังก์ชั่นเพิ่มใด ๆ

ฉันแค่ต้องการฟังก์ชั่นที่สามารถทำได้:

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

function Date.prototype.addHours(h) {

   // how do I implement this?  

}

ฉันแค่อยากให้พอยน์เตอร์ชี้ทางไป

  • ฉันต้องแยกสตริงหรือไม่

  • ฉันสามารถใช้ setTime ได้หรือไม่

  • มิลลิวินาทีเป็นอย่างไร

แบบนี้:

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

ดูเหมือนว่าแฮ็คจริงๆ - และมันใช้งานได้จริงหรือ

คำตอบ:


423

JavaScript เองมี API วันที่ / เวลาที่แย่มาก อย่างไรก็ตามคุณสามารถทำสิ่งนี้ได้ด้วย JavaScript บริสุทธิ์:

Date.prototype.addHours = function(h) {
  this.setTime(this.getTime() + (h*60*60*1000));
  return this;
}

ทำงานเหมือนจับใจ! ขอบคุณ
moreirapontocom

ถ้าคุณบอกว่าคุณเพิ่มชั่วโมงทำให้มันกลิ้งไปในวันถัดไปสิ่งนี้จะจับและเพิ่มทุกอย่างถูกต้อง (วันเดือนปี) หรือไม่
cdoern

@cdoern ฉันคิดว่ามันจะเป็นเพราะ getTime () จะส่งกลับมิลลิวินาทีและคุณเพียงแค่เพิ่มมิลลิวินาทีเพิ่มเติมไป
The1993

370
Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

ทดสอบ:

alert(new Date().addHours(4));

25
ฉันไม่คิดว่ามันจะใช้งานได้หรือลองทดสอบกับบางสิ่งในชั่วโมงที่ 23 เช่น? คำตอบของ Jason Harwig คือสิ่งที่อยู่ในใจของฉัน
Domenic

11
เป็นการดีที่จะเพิ่มสิ่งต่างๆลงในต้นแบบของวัตถุใน Javascript และ Domenic นั้นถูกต้องสิ่งนี้ไม่ได้ผล วิธีแก้ปัญหาของ Jason Harwig ด้านล่างดีกว่า
iKode

19
@Domenic ใช้งานได้ดีกับ 23:00 ทดสอบภายในคอนโซล JavaScript ของ Firefox 10, Chrome 21 และ IE 8/9 ที่นี่รหัสฉันเคยทดสอบ: 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) มันทำงานได้ดีกับ setMinutes ()
tanguy_k

4
แก้ไขปัญหาด้วยวิธีนี้ - การเพิ่มขึ้น 1 ล้มเหลวสำหรับฉันที่จุดเปลี่ยนเวลาของ DST (เลื่อนนาฬิกาไปข้างหน้าหนึ่งชั่วโมง)
andrewb

2
ผมก็ถูกกัด - ผมวนซ้ำหลายชั่วโมงโดยใช้ setHours (getHours-1): ตอนนี้ในเวลา DST ชั่วโมงแรกสิ่งนี้กลายเป็นวงวนไม่สิ้นสุด ดังนั้นตรวจสอบผล!
cfstras

165

โค้ดด้านล่างนี้คือการเพิ่มวันที่ 4 ชั่วโมง (ตัวอย่างเช่นวันที่วันนี้)

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

จะไม่ทำให้เกิดข้อผิดพลาดหากคุณพยายามเพิ่ม 4 ถึง 23 (ดูเอกสาร ):

หากพารามิเตอร์ที่คุณระบุอยู่นอกช่วงที่คาดหวัง setHours () จะพยายามอัปเดตข้อมูลวันที่ในวัตถุวันที่ตามลำดับ


ฉันไม่เห็นสิ่งนี้และทำคำตอบที่ซ้ำกัน ฉันชอบวิธีนี้ แม่นยำและมีประโยชน์
แกนดัล์ฟเดอะไวท์

ดูเหมือนว่าจะไม่ทำงานเมื่อชั่วโมงเป็นทศนิยม (ไม่ใช่จำนวนเต็ม)
gregmagdits

3
นี่คือคำตอบที่ดีที่สุดที่นี่ ... การเพิ่ม "addHours" ลงในต้นแบบวันที่น่าเป็นห่วงเพราะในบางจุด JS อาจเพิ่มการสนับสนุนสำหรับฟังก์ชันนั้นแล้วคุณมีต้นแบบที่ขัดแย้งกัน สิ่งนี้ทำให้คุณได้รับประโยชน์จากการใช้รหัสมาก
Kris Boyd

ประหลาดใจ แต่มันเพิ่มวันจริงเดือนถ้าต้องการเชื่อมโยงไปยังเอกสารจะมีประโยชน์
2oppin

4
ในขณะที่ใช้ค่าชั่วโมง> 23 ไม่ทำลายนี้ก็ยังคงเสียที่ขอบเขตเงินฝากออมทรัพย์ในเวลากลางวัน เนื่องจากว่ามันใช้งานไม่ได้ไม่มีเหตุผลที่จะใช้งาน ชอบsetTimeหรือsetUTCHour.
Mark Amery

40

มันอาจจะดีกว่าที่จะทำให้วิธี addHours ไม่เปลี่ยนรูปได้โดยส่งคืนสำเนาของวัตถุวันที่แทนที่จะกลายพันธุ์พารามิเตอร์

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

วิธีนี้คุณสามารถเชื่อมโยงเมธอดจำนวนมากโดยไม่ต้องกังวลเกี่ยวกับสถานะ


ฟังก์ชั่นนี้มีปัญหาแบบเดียวกับที่ระบุไว้ที่นี่stackoverflow.com/questions/1050720/…มันไม่ได้เกี่ยวกับว่ามันทำงานบนเบราว์เซอร์บางอย่าง แต่สถานที่อื่น ๆ ที่ใช้ Javascript เห็นว่าเป็นปัญหา การรวมโซลูชันของคุณเข้ากับstackoverflow.com/a/1050782/295535อันนี้ ดูเหมือนจะเป็นทางออกที่ดีที่สุด
Ressu

1
คุณควรพิจารณาเปลี่ยนชื่อฟังก์ชั่นเนื่องจากเป็นคำadd*ที่ใช้กันโดยทั่วไปในการกลายพันธุ์ของวัตถุ
mr5

@ mr5 - ไม่แน่ใจว่าaddมันถูกใช้ในDateTimeคลาสNET Framework มากและมีความหมายเหมือนกับ+(บวก) ในคณิตศาสตร์
Tahir Hassan

1
currentDate.addHours(1)<- จากสัญชาตญาณการเขียนโปรแกรมของฉันฉันคาดหวังว่าcurrentDateคุณค่าจะเปลี่ยนแปลง แต่ในการนำไปใช้ของคุณจะไม่เกิดขึ้น สำหรับเหตุผลที่ฉันแนะนำให้เปลี่ยนชื่อหรือเปลี่ยนลายเซ็นเป็นบางสิ่งบางอย่าง
mr5

1
@ TahirHassan ไม่มีอะไรเกี่ยวข้องกับรายละเอียดทางเทคนิค แต่ในการเลือกคำที่เหมาะสมที่จะใช้สำหรับชื่อฟังก์ชั่น ฉันยังคงชอบรุ่นที่ไม่แน่นอนเมื่อฟังก์ชั่นนำหน้าด้วยadd
mr5

23

รุ่นที่แนะนำโดย kennebec จะล้มเหลวเมื่อเปลี่ยนเป็นหรือจาก DST เนื่องจากเป็นหมายเลขชั่วโมงที่ตั้งค่าไว้

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

จะเพิ่มhชั่วโมงในการthisเป็นอิสระจากลักษณะของระบบเวลา วิธีการของ Jason Harwig ก็ใช้ได้เช่นกัน



7

ฉันคิดว่าไม่ควรดัดแปลงวัตถุดั้งเดิม ดังนั้นเพื่อเป็นการประหยัดกำลังคนในอนาคตนี่เป็นคำตอบที่ผสมผสานกันโดยอิงจากJason HarwigและTahir Hasanคำตอบ:

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

5

มีการเพิ่มในไลบรารีDatejs

และนี่คือวิธีการวัน JavaScript kennebec พูดถึง getHours () และ setHours () อย่างชาญฉลาด


โปรดทราบว่าห้องสมุดนั้นดูเหมือนว่าจะอยู่ในสถานะอัลฟ่า
Sam

4

ตรวจสอบว่ายังไม่ได้กำหนดไว้มิฉะนั้นจะกำหนดไว้บนต้นแบบวันที่:

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

3

อีกวิธีในการจัดการสิ่งนี้คือการแปลงวันที่เป็น unixtime (ยุค) จากนั้นเพิ่มจำนวนเทียบเท่าใน (มิลลิวินาที) วินาทีแล้วแปลงกลับ วิธีนี้คุณสามารถจัดการการเปลี่ยนวันและเดือนเช่นเพิ่ม 4 ชั่วโมงถึง 21 ซึ่งจะส่งผลในวันถัดไป 01:00


คุณพูดถูก แต่คุณก็ดึกแค่สองสามปี คำตอบของ Jason Harwigแสดงวิธีนี้เมื่อ 2 ปีก่อน คำตอบนี้ไม่ได้เพิ่มอะไรใหม่
Mark Amery

3

สำหรับฟังก์ชั่นเพิ่ม / ลบชั่วโมง / นาทีอย่างง่ายใน javascript ลองสิ่งนี้:

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

สิ่งนี้สามารถใช้โดยไม่มีพารามิเตอร์เพื่อรับเวลาปัจจุบัน

getTime();

หรือด้วยพารามิเตอร์ที่จะได้รับเวลากับนาที / ชั่วโมงเพิ่ม

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

แม้กระทั่งเวลาที่ไม่ดี

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

ฟังก์ชันนี้ส่งคืนอาร์เรย์ของ

array([Hour], [Minute], [Meridian])

สัตว์ประหลาด 56 บรรทัดของข้อได้เปรียบอะไรที่มีคุณสมบัติเหนือแนวทางสองบรรทัดในคำตอบที่ได้รับการโหวตสูงสุด ? -1 เนื่องจากมีความซับซ้อนเพิ่มมากที่นี่เพื่อประโยชน์ที่ฉันเห็น
Mark Amery

1

SPRBRN ถูกต้อง ในการเริ่มต้น / สิ้นสุดของเดือนและปีคุณต้องเปลี่ยนเป็น Epoch และย้อนกลับ

นี่คือวิธีที่คุณทำ:

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


หรือทำในบรรทัดเดียว (โดยที่ชื่อตัวแปรเหมือนกันกับด้านบน:

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

0

นี่เป็นวิธีที่ง่ายในการรับค่าข้อมูลที่เพิ่มขึ้นหรือลดลง

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 )

-1

ยุ่งเล็กน้อย แต่ใช้งานได้!

ให้รูปแบบวันที่เช่นนี้: 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+"");

ผลลัพธ์ของคุณคือ: 2019-04-03T16: 58

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.