วัตถุวันที่ Javascript เป็นวันหยุดหนึ่งวันเสมอหรือไม่?


238

ในแอป Java Script ของฉันฉันมีวันที่เก็บในรูปแบบดังนี้:

2011-09-24

ตอนนี้เมื่อฉันลองใช้ค่าข้างต้นเพื่อสร้างวัตถุ Date ใหม่ (ดังนั้นฉันสามารถดึงวันที่ในรูปแบบที่แตกต่างกัน) วันที่จะกลับมาหยุดหนึ่งวัน ดูด้านล่าง:

var doo = new Date("2011-09-24");
console.log(doo);

บันทึก:

Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)

11
คลาส Date ของ Javascript ไม่ได้เป็นตัวแทนของวันที่ แต่มันหมายถึง timestamp (เหมือนกันใน Java) เพื่อให้เป็นวันที่มันใช้เขตเวลาและนั่นคือสาเหตุของปัญหาของคุณ แยกวิเคราะห์ด้วยเขตเวลา GMT / UTC (24 ก.ย. 2554, 00:00 น . UTC) แล้วส่งออกด้วยเขตเวลาอื่น 4 ชั่วโมง (23 ก.ย. 2554, 20 : 00 GMT-0400)
Codo

2
ฉันได้รับ "วันที่ไม่ถูกต้อง" แทนที่อักขระ '-' ด้วยอักขระ '/' แล้วลองอีกครั้ง หรือแยกวันที่เป็นบิตและตั้งค่าส่วนประกอบแยกกัน (ถ้าคุณทำอย่างนั้นให้ลบ 1 จากหมายเลขเดือน)
RobG

@Codo - ใช่คำตอบที่ดี ใช้ ECMA-262 15.9.1.15 OP ควรใช้ "2011-09-24T20: 00: 00-04: 00" หรือคล้ายกัน
RobG

1
ฉันพบว่ารูปแบบ "Sep 24 2011" จะส่งคืนวันที่ที่เหมาะสม ดูคำอธิบายได้ที่นี่: stackoverflow.com/questions/2587345/javascript-date-parse
christurnerio

คำตอบ:


98

ขอให้สังเกตว่าเวลากลางวันตะวันออกเป็นและชั่วโมงในวันที่คุณได้รับกลับมาเป็น-4 hours20

20h + 4h = 24h

ซึ่งเป็นเวลาเที่ยงคืนของปี 2011-09-24 วันที่แยกวิเคราะห์ใน UTC (GMT) เนื่องจากคุณระบุสตริงวันที่อย่างเดียวโดยไม่มีตัวบ่งชี้เขตเวลาใด ๆ หากคุณได้รับสตริงวันที่ / เวลาโดยไม่มีตัวบ่งชี้แทน ( new Date("2011-09-24T00:00:00")) สตริงนั้นจะถูกแยกวิเคราะห์ในเขตเวลาท้องถิ่นของคุณ (ในอดีตมีความไม่สอดคล้องกันอยู่ที่นั่นอย่างน้อยก็เพราะสเป็คเปลี่ยนไปมากกว่าหนึ่งครั้ง แต่เบราว์เซอร์สมัยใหม่ควรจะไม่เป็นไรหรือคุณสามารถใส่ตัวบ่งชี้เขตเวลา)

คุณได้รับวันที่ที่ถูกต้องคุณไม่เคยระบุเขตเวลาที่ถูกต้อง

หากคุณต้องการเข้าถึงค่าวันที่คุณสามารถใช้getUTCDate()หรือฟังก์ชั่นอื่น ๆ ได้getUTC*() :

var d,
    days;
d = new Date('2011-09-24');
days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
console.log(days[d.getUTCDay()]);

24
คุณ "ระบุเขตเวลาที่ถูกต้อง" ได้อย่างไร ตัวสร้างวันที่ตีความสตริงวันที่เป็น UTC เสมอ แต่จากนั้นจะปรับสำหรับเขตเวลา ฉันยังสามารถทำ `ใหม่วันที่ ('2012-01-02 EDT') และยังคงย้ายกลับไปยังวันก่อนหน้าเนื่องจากการใช้ออฟเซ็ตเพื่อประหยัดเวลากลางวันซึ่งไม่มีเหตุผลเพราะถ้าฉันบอกคุณว่าเป็นวันที่ตาม เขตเวลาท้องถิ่นปัจจุบันของ EDT จากนั้นไม่ใช้การชดเชยเพิ่มเติมกับมัน ฉันบอกว่าเขตเวลาคือ EDT แต่ก็ยังใช้การชดเชยเพิ่มเติมที่ย้ายมันกลับมาหนึ่งวัน
AaronLS

1
@AaronLS, EDTเป็นกลางวันเวลาออมทรัพย์ (ยังเป็นที่รู้จักกันเป็นเวลาฤดูร้อน) , ESTเป็นเขตที่มีผลบังคับใช้ในเดือนมกราคม
zzzzBov

1
สร้างเป็น UTC เพียงแค่จากสตริงจะเป็นสิ่งที่ฉันต้องการทำดังนั้นทำไมฉันถาม "คุณจะ" ระบุเขตเวลาที่ถูกต้อง "ได้อย่างไร? เกี่ยวกับตำแหน่งที่คุณระบุ "คุณไม่เคยระบุโซนเวลาที่ถูกต้อง" หากฉันnew Date('2012-01-01 GMT')ยังคงใช้การชดเชยตามที่แปลงเป็นเวลาท้องถิ่นของผู้ใช้
AaronLS

7
@AaronLS ถ้าคุณถูกบังคับให้ใช้get*วิธีการและต้องการที่จะกลับมาที่ถูกต้องวันที่ / เวลารวมทั้งเขตที่ไม่รู้จักชดเชยเพียงแค่เพิ่มในเขตที่ไม่รู้จักชดเชย: d = new Date('2013-01-08 GMT'); d.setMinutes(d.getMinutes() + d.getTimezoneOffset());นี้จะปกติวันที่สถานที่ของผู้ใช้เพื่อให้.get*กลับมาใช้วิธีการ ค่าที่คาดหวัง .getUTC*วิธีการนั้นจะไม่ถูกต้องจึงควรระมัดระวัง
zzzzBov

1
มีความแตกต่างระหว่างการกำหนดพฤติกรรมเพื่อให้การอ้างอิงและใช้มันเป็นทางหนีเมื่อผู้ดำเนินการไม่สามารถใช้บางอย่างได้อย่างถูกต้อง และมันก็ไม่ได้เป็นตัวแทนเดียวกันหากข้อมูลไม่สอดคล้องกับความคาดหวัง
Rage แตกต่าง

252

มีหลายสิ่งที่บ้าที่เกิดขึ้นกับวัตถุJS DATEที่แปลงสตริงตัวอย่างเช่นพิจารณาวันที่ต่อไปนี้ที่คุณให้ไว้

หมายเหตุ:ตัวอย่างต่อไปนี้อาจจะหรืออาจจะไม่ONE DAY OFFขึ้นอยู่กับคุณเขตเวลาและเวลาปัจจุบัน

new Date("2011-09-24"); // Year-Month-Day
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.

อย่างไรก็ตามหากเราจัดรูปแบบสตริงเป็นเดือนวันวัน ...

new Date("09-24-2011");
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

อีกสิ่งหนึ่งที่แปลก

new Date("2011-09-24");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF AS BEFORE.

new Date("2011/09/24"); // change from "-" to "/".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

เราสามารถเปลี่ยนเครื่องหมายขีดคั่นในวันที่ของคุณ"2011-09-24"ได้อย่างง่ายดายเมื่อทำการนัดใหม่

new Date("2011-09-24".replace(/-/g, '\/')); // => "2011/09/24".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

ถ้าเรามีสตริงวันที่เช่น"2011-09-24T00: 00: 00"

new Date("2011-09-24T00:00:00");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.

ตอนนี้เปลี่ยนเครื่องหมายขีดกลางเพื่อส่งต่อเครื่องหมายทับเหมือนเดิม เกิดอะไรขึ้น?

new Date("2011/09/24T00:00:00");
// => Invalid Date

ฉันมักจะต้องจัดการรูปแบบวันที่2011-09-24T00: 00: 00ดังนั้นนี่คือสิ่งที่ฉันทำ

new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, ''));
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

UPDATE

หากคุณระบุอาร์กิวเมนต์แยกต่างหากกับตัวสร้าง Date คุณสามารถรับเอาท์พุทที่มีประโยชน์อื่น ๆ ตามที่อธิบายไว้ด้านล่าง

หมายเหตุ:อาร์กิวเมนต์สามารถเป็นชนิด Number หรือ String ฉันจะแสดงตัวอย่างที่มีค่าผสม

รับเดือนและวันแรกของปีที่กำหนด

new Date(2011, 0); // Normal behavior as months in this case are zero based.
=> // Sat Jan 01 2011 00:00:00 GMT-0700 (MST)

รับเดือนและวันสุดท้ายของปี

new Date((2011 + 1), 0, 0); // The second zero roles back one day into the previous month's last day.
=> // Sat Dec 31 2011 00:00:00 GMT-0700 (MST)

ตัวอย่างของ Number, อาร์กิวเมนต์ String โปรดทราบว่าเดือนนี้เป็นเดือนมีนาคมเพราะเป็นศูนย์ตามเดือนอีกครั้ง

new Date(2011, "02"); 
=> // Tue Mar 01 2011 00:00:00 GMT-0700 (MST)

ถ้าเราทำสิ่งเดียวกัน แต่มีศูนย์วันหนึ่งเราจะได้อะไรที่แตกต่างออกไป

new Date(2011, "02", 0); // again the zero roles back from March to the last day of February.
=> // Mon Feb 28 2011 00:00:00 GMT-0700 (MST)

การเพิ่มวันที่เป็นศูนย์ในอาร์กิวเมนต์ปีและเดือนใด ๆ จะได้รับวันสุดท้ายของเดือนก่อนหน้า หากคุณยังคงมีตัวเลขติดลบคุณสามารถย้อนกลับได้อีกวัน

new Date(2011, "02", -1);
=> // Sun Feb 27 2011 00:00:00 GMT-0700 (MST)

12
สิ่งนี้ช่วยฉันได้ดีที่สุดจริง ๆ ฉันเพิ่งเพิ่ม. แทนที่ (/ - / g, '\ /') แทนที่ (/ T. + /, '') ที่ส่วนท้ายของข้อมูลของฉันเมื่อฉันทำวันที่ใหม่ ง่ายสุด ๆ !
Devin Prejean

64
ว้าว - จาวาสคริปต์นั้นไม่สอดคล้องกันอย่างมาก
psparrow

2
.replace () การโทรเข้ามาช่วยจริงๆในเวลาเย็นนี้
เลิกใช้งาน

2
ใช่ฉันได้ทดสอบทั้งหมดนี้และมันแปลกมาก
chintan adatiya

27
ทั้งหมดนี้เกิดจากการทำงานของ Date.parse () ที่พยายามทำตาม ISO 8601 เมื่อสตริงวันที่ตามรูปแบบ yyyy-mm-dd จะถือว่าเป็น ISO 8601 โดยปริยาย UTC 00:00 เมื่อสตริงเบี่ยงเบนจากรูปแบบ (เช่น mm-dd-yyyy หรือเครื่องหมายสแลชแทนที่จะใช้เครื่องหมายขีดกลาง) สตริงจะกลับไปที่ตัวแยกวิเคราะห์โยกตาม RFC 2822 ซึ่งใช้เวลาท้องถิ่นเมื่อไม่มีเขตเวลา เป็นที่ยอมรับว่าสิ่งนี้จะค่อนข้างเป็นเรื่องธรรมดาสำหรับคนทั่วไป
Mizstik

71

หากต้องการทำให้วันที่เป็นมาตรฐานเป็นปกติและกำจัดออฟเซตที่ไม่ต้องการ (ทดสอบที่นี่: https://jsfiddle.net/7xp1xL5m/ ):

var doo = new Date("2011-09-24");
console.log(  new Date( doo.getTime() + Math.abs(doo.getTimezoneOffset()*60000) )  );
// Output: Sat Sep 24 2011 00:00:00 GMT-0400 (Eastern Daylight Time)

สิ่งนี้จะได้ผลเช่นเดียวกันและให้เครดิตกับ @tpartee (ทดสอบที่นี่: https://jsfiddle.net/7xp1xL5m/1/ ):

var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 )  );

สิ่งนี้ทำเพื่อฉัน - ฉันต้องทำงานกับวันที่จาก API จากนั้นเรียงลำดับ / เปรียบเทียบดังนั้นเพียงเพิ่มการชดเชยเขตเวลาทำงานได้ดีที่สุด
chakeda

สิ่งนี้ใช้งานได้สำหรับฉันยกเว้นฉันต้องลบ timeZoneOffset ไม่ต้องเพิ่ม
ErikAGriffin

@ErikAGriffin คุณอยู่ในโซนเวลาบวก IE GMT + 0X00 แทนที่จะเป็น GMT-0X00 หรือไม่?
AaronLS

ฉันทำสิ่งที่คล้ายกัน:doo.setMinutes(doo.getMinutes() + doo.getTimezoneOffset())
Rage แตกต่าง

2
@ AaronLS คุณกำลังติดตามถูก แต่ตรรกะผิดเล็กน้อย เพื่อชดเชยค่าชดเชย TZ ตรรกะที่ถูกต้องคือ: console.log (วันที่ใหม่ (doo.getTime () - doo.getTimezoneOffset () * -60000)); - เครื่องหมายของออฟเซ็ตนั้นสำคัญและไม่สามารถทำให้สำเร็จได้ แต่คุณต้องใช้เครื่องหมายผกผันสำหรับการแก้ไขดังนั้นเราจึงคูณออฟเซ็ตด้วย -60000 เพื่อให้มีการใช้เครื่องหมายผกผัน
tpartee

28

หากคุณต้องการรับชั่วโมง 0 ของวันที่ในเขตเวลาท้องถิ่นให้ส่งส่วนของวันที่แต่ละรายการไปยังตัวDateสร้าง

new Date(2011,08,24); // month value is 0 based, others are 1 based.

26

เพียงต้องการเพิ่มที่เห็นได้ชัดว่าการเพิ่มช่องว่างที่ส่วนท้ายของสตริงจะใช้ UTC สำหรับการสร้าง

new Date("2016-07-06")
> Tue Jul 05 2016 17:00:00 GMT-0700 (Pacific Daylight Time)

new Date("2016-07-06 ")
> Wed Jul 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time)

แก้ไข: นี่ไม่ใช่วิธีแก้ปัญหาที่แนะนำ แต่เป็นคำตอบอื่น โปรดอย่าใช้วิธีนี้เนื่องจากไม่ชัดเจนว่าเกิดอะไรขึ้น มีหลายวิธีที่บางคนสามารถ refactor นี้โดยไม่ตั้งใจทำให้เกิดข้อผิดพลาด


สำหรับตัวอย่างที่มีช่องว่างในตอนท้ายคอนโซลจะคืนค่า "วันที่ไม่ถูกต้อง = $ 2"
Brian Risk

1
ทำงานได้ดีมาก! ใหม่วันที่ (data.Date + "") .toLocaleDateString ("en-US")
Nakres

เพื่อความเป็นธรรมนี่เป็นเพียงคำตอบทางเลือกและไม่ใช่วิธีแก้ปัญหาที่แนะนำ
Kyle Shrader

25

ฉันเชื่อว่าเกี่ยวข้องกับการปรับเขตเวลา วันที่ที่คุณสร้างคือ GMT และเวลาเริ่มต้นคือเที่ยงคืน แต่เขตเวลาของคุณคือ EDT ดังนั้นจะลบ 4 ชั่วโมง ลองใช้วิธีนี้เพื่อยืนยัน:

var doo = new Date("2011-09-25 EDT");

3
นี่คือคำตอบที่ดีที่สุดที่นี่ + 1million สำหรับการใช้สตริงการโลคัลไลซ์เซชันการแบ่งเขตเวลาที่มีอยู่ภายในแทนที่จะเป็นการแปลงแบบเป็นโปรแกรม
# # #

2
อันนี้ช่วยได้ มันทำงานเช่นนี้: $ scope.dat = วันที่ใหม่ (datestring + 'EDT') สังเกตความแตกต่างระหว่าง EDT กับ EST แม้ว่า: ลิงก์
Weihui Guo

ฉันไม่รู้ว่าเกิดอะไรขึ้นเบื้องหลัง แต่มันทำงานได้อย่างสมบูรณ์แบบ
the_haystacker

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

ขอบคุณฉันพิจารณาวิธีที่ดีที่สุดสำหรับฉัน
Janderson Constantino

11

ปัญหาของคุณมีเฉพาะในเขตเวลา ส่วนหมายเหตุGMT-0400- นั่นคือคุณอยู่หลัง 4 ชั่วโมง GMT หากคุณเพิ่ม 4 ชั่วโมงในวันที่ / เวลาที่แสดงคุณจะได้รับเที่ยงคืน 2011/09/24 ใช้toUTCString()วิธีการแทนรับสตริง GMT:

var doo = new Date("2011-09-24");
console.log(doo.toUTCString());

7

นี่อาจไม่ใช่คำตอบที่ดี แต่ฉันต้องการแบ่งปันประสบการณ์ของฉันกับปัญหานี้

แอพของฉันใช้วันที่ utc ทั่วโลกด้วยรูปแบบ 'YYYY-MM-DD' ในขณะที่ปลั๊กอิน datepicker ที่ฉันใช้ยอมรับเฉพาะวันที่ js มันยากที่จะพิจารณาทั้ง utc และ js ดังนั้นเมื่อฉันต้องการผ่านวันที่จัดรูปแบบ 'YYYY-MM-DD' เป็น datepicker ของฉันฉันจะแปลงเป็นรูปแบบ 'MM / DD / YYYY' โดยใช้ moment.js หรืออะไรก็ตามที่คุณชอบและวันที่จะแสดงใน datepicker ตอนนี้ แก้ไข. สำหรับตัวอย่างของคุณ

var d = new Date('2011-09-24'); // d will be 'Fri Sep 23 2011 20:00:00 GMT-0400 (EDT)' for my lacale
var d1 = new Date('09/24/2011'); // d1 will be 'Sat Sep 24 2011 00:00:00 GMT-0400 (EDT)' for my lacale

เห็นได้ชัดว่า d1 คือสิ่งที่ฉันต้องการ หวังว่านี่จะเป็นประโยชน์สำหรับบางคน


1
เพียงแค่เปลี่ยนรูปแบบเช่นเดียวกับที่คุณทำทำงานแบบเดียวกันสำหรับฉัน แปลกมาก
jAC

5

นี่คือสิ่งที่ฉันห่วงสำหรับ +1 บนคำตอบของ zzzBov นี่คือการแปลงวันที่ที่เหมาะกับฉันโดยใช้วิธี UTC:

//myMeeting.MeetingDate = '2015-01-30T00:00:00'

var myDate = new Date(myMeeting.MeetingDate);
//convert to JavaScript date format
//returns date of 'Thu Jan 29 2015 19:00:00 GMT-0500 (Eastern Standard Time)' <-- One Day Off!

myDate = new Date(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate());
//returns date of 'Fri Jan 30 2015 00:00:00 GMT-0500 (Eastern Standard Time)' <-- Correct Date!

4

มันหมายความว่า2011-09-24 00:00:00 GMTและเมื่อคุณอยู่ที่GMT -4นั่นมันจะเป็น20:00วันก่อนหน้า

ส่วนตัวผมได้รับเพราะฉันอาศัยอยู่ที่2011-09-24 02:00:00GMT +2


3

แม้ว่าในกรณีของ OP คือเขตเวลา EDT แต่ก็ไม่รับประกันว่าผู้ใช้ที่เรียกใช้สคริปต์ของคุณจะเป็นเขตเวลา EDT ดังนั้นการเข้ารหัสแบบออฟเซตจึงไม่จำเป็นต้องทำงาน วิธีการแก้ปัญหาที่ฉันพบแยกสตริงวันที่และใช้ค่าแยกในตัวสร้างวันที่

var dateString = "2011-09-24";
var dateParts = dateString.split("-");
var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);

โปรดทราบว่าคุณต้องพิจารณาชิ้นส่วนของความแปลกใหม่ของ JS: เดือนจะเป็นศูนย์


2

ฉันพบปัญหาตรงนี้ที่ลูกค้าของฉันอยู่ในเวลามาตรฐานแอตแลนติก ค่าวันที่ไคลเอนต์ดึงข้อมูลคือ"2018-11-23"และเมื่อรหัสผ่านเข้าไปnew Date("2018-11-23")ในเอาต์พุตสำหรับลูกค้าเป็นวันก่อนหน้า ฉันสร้างฟังก์ชั่นยูทิลิตี้ตามที่แสดงในตัวอย่างที่ทำให้ปกติวันที่ให้ลูกค้าวันที่คาดหวัง

date.setMinutes(date.getMinutes() + date.getTimezoneOffset());

var normalizeDate = function(date) {
  date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
  return date;
};

var date = new Date("2018-11-23");

document.getElementById("default").textContent = date;
document.getElementById("normalized").textContent = normalizeDate(date);
<h2>Calling new Date("2018-11-23")</h2>
<div>
  <label><b>Default</b> : </label>
  <span id="default"></span>
</div>
<hr>
<div>
  <label><b>Normalized</b> : </label>
  <span id="normalized"></span>
</div>


2

หากคุณต้องการตรวจสอบให้แน่ใจว่าแต่ละส่วนของวันที่ยังคงเหมือนเดิมสำหรับจุดประสงค์ในการแสดงผล * สิ่งนี้ดูเหมือนว่าจะใช้งานได้แม้ว่าฉันจะเปลี่ยนเขตเวลาของฉัน:

var doo = new Date("2011-09-24 00:00:00")

เพียงเพิ่มศูนย์ในนั้น

ในรหัสของฉันฉันทำสิ่งนี้:

let dateForDisplayToUser = 
  new Date( `${YYYYMMDDdateStringSeparatedByHyphensFromAPI} 00:00:00` )
  .toLocaleDateString( 
    'en-GB', 
    { day: 'numeric', month: 'short', year: 'numeric' }
  )

และฉันสลับรอบเขตเวลาของฉันบนคอมพิวเตอร์ของฉันและวันที่จะคงที่เหมือนกับสตริงวันที่ yyyy-mm-dd ที่ฉันได้รับจาก API

แต่ฉันทำบางสิ่งบางอย่าง / นี่เป็นความคิดที่ไม่ดีหรือไม่?

* อย่างน้อยในโครเมียม สิ่งนี้ใช้ไม่ได้ใน Safari! ตามที่เขียนนี้


เมื่อคุณทำ.toISOString()มันจะย้อนกลับไป 1 วัน
vivek_23

new Date('2019/11/18 05:30:00').toISOString();ทำงานให้ฉัน
vivek_23

1

วิธีที่ดีที่สุดในการจัดการสิ่งนี้โดยไม่ต้องใช้วิธีการแปลงมากขึ้น

 var mydate='2016,3,3';
 var utcDate = Date.parse(mydate);
 console.log(" You're getting back are 20.  20h + 4h = 24h :: "+utcDate);

ตอนนี้เพียงแค่เพิ่ม GMT ในวันที่ของคุณหรือคุณสามารถผนวกมัน

 var  mydateNew='2016,3,3'+ 'GMT';
 var utcDateNew = Date.parse(mydateNew);
 console.log("the right time that you want:"+utcDateNew)

สด: https://jsfiddle.net/gajender/2kop9vrk/1/


1

ฉันประสบปัญหาเช่นนี้ แต่ปัญหาของฉันคือการตั้งค่าปิดในขณะที่รับวันที่จากฐานข้อมูล

นี่คือ stroed ในฐานข้อมูลและอยู่ในรูปแบบ UTC

2019-03-29 19: 00: 00.0000000 +00: 00

ดังนั้นเมื่อฉันได้รับจากฐานข้อมูลและตรวจสอบวันที่มันจะเพิ่มออฟเซ็ตด้วยและส่งกลับไปที่จาวาสคริปต์

ป้อนคำอธิบายรูปภาพที่นี่

มันเพิ่ม +05: 00 เพราะนี่เป็นเขตเวลาของเซิร์ฟเวอร์ของฉัน ลูกค้าของฉันอยู่ในโซนเวลาอื่น +07: 00

2019-03-28T19: 00: 00 + 05: 00 // นี่คือสิ่งที่ฉันได้รับในจาวาสคริปต์

ดังนั้นนี่คือทางออกของฉันสิ่งที่ฉันทำกับปัญหานี้

var dates = price.deliveryDate.split(/-|T|:/);
var expDate = new Date(dates[0], dates[1] - 1, dates[2], dates[3], dates[4]);
var expirationDate = new Date(expDate);

ดังนั้นเมื่อวันที่มาจากเซิร์ฟเวอร์และมีเซิร์ฟเวอร์ออฟเซ็ตดังนั้นฉันแยกวันและลบเซิร์ฟเวอร์ออฟเซ็ตแล้วแปลงเป็นวันที่ มันช่วยแก้ไขปัญหาของฉัน


1

หากคุณต้องการโซลูชันที่เรียบง่ายสำหรับสิ่งนี้โปรดดู:

new Date('1993-01-20'.split('-')); 

ป้อนคำอธิบายรูปภาพที่นี่


0

คุณกำลังใช้รูปแบบสตริงวันที่ ISO ซึ่งตามหน้านี้ทำให้วันที่จะสร้างโดยใช้เขตเวลา UTC:

หมายเหตุ: การแยกสตริงวันที่ด้วยตัวสร้างวันที่ (และ Date.parse พวกเขาเทียบเท่า) จะหมดกำลังใจอย่างยิ่งเนื่องจากความแตกต่างเบราว์เซอร์และความไม่สอดคล้องกัน การสนับสนุนสำหรับสตริงรูปแบบ RFC 2822 เป็นเพียงการประชุมเท่านั้น การสนับสนุนสำหรับรูปแบบ ISO 8601 แตกต่างกันในสตริงวันที่เท่านั้น (เช่น "1970-01-01") จะถือว่าเป็น UTC ไม่ใช่ในพื้นที่

หากคุณจัดรูปแบบข้อความแตกต่างกันเช่น"Jan 01 1970"นั้น (อย่างน้อยในเครื่องของฉัน) จะใช้เขตเวลาท้องถิ่นของคุณ


0

กำลังพยายามเพิ่ม 2 เซ็นต์ของฉันไปยังเธรดนี้ (ทำอย่างละเอียดใน @ paul-wintz answer)

ดูเหมือนว่าเมื่อตัวสร้าง Date ได้รับสตริงที่ตรงกับส่วนแรกของรูปแบบ ISO 8601 (ส่วนของวันที่) มันทำการแปลงวันที่อย่างแม่นยำในเขตเวลา UTC ด้วยเวลา 0 เมื่อวันที่ดังกล่าวถูกแปลงเป็นเวลาท้องถิ่นการเปลี่ยนวันที่อาจเกิดขึ้นหากเที่ยงคืน UTC เป็นวันที่ก่อนหน้านี้ในโซนเวลาท้องถิ่น

new Date('2020-05-07')
Wed May 06 2020 20:00:00 GMT-0400 (Eastern Daylight Time)

หากสตริงวันที่อยู่ในรูปแบบ "โยก" อื่น ๆ (ใช้ "/" หรือวันที่ / เดือนจะไม่เต็มด้วยศูนย์) มันจะสร้างวันที่ในโซนเวลาท้องถิ่นจึงไม่มีปัญหาการขยับวันที่

new Date('2020/05/07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-05-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)

ดังนั้นหนึ่งการแก้ไขด่วนดังกล่าวข้างต้นคือการแทนที่ "-" ด้วย "/" ในสตริงวันที่จัดรูปแบบ ISO เท่านั้นของคุณ

new Date('2020-05-07'.replace('-','/'))
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)

0

การจัดเก็บyyyy-mm-ddในรูปแบบวันที่ MySql คุณต้องทำสิ่งต่อไปนี้:

const newDate = new Date( yourDate.getTime() + Math.abs(yourDate.getTimezoneOffset()*60000) );
console.log(newDate.toJSON().slice(0, 10)); // yyyy-mm-dd

-1

บันทึกของคุณส่งออก GMT ดังนั้นคุณต้องการระบุเขตเวลาของคุณ:

var doo = new Date("2011-09-24 EST");

3
คำถามนี้มีคำตอบมากมายแล้ว หากคุณต้องการตอบคำถามคุณควรพูดถึงสิ่งใหม่ที่คำตอบอื่นไม่ทำ คำตอบยอดนิยมอธิบายถึงปัญหาของเขตเวลาโดยละเอียดแล้ว
Calvin Godfrey

คำตอบนี้เกือบเหมือนกับstackoverflow.com/a/7556642/8828658
หิน arachnid

ใครจะสนใจว่าคำอธิบายของเขานั้นลึกซึ้งกว่าใคร ... รหัสของเขายังคงแตกต่างจากของฉัน ของฉันนั้นง่ายกว่ามาก และใช่หินอาราคินคุณถูกต้อง ความผิดฉันเอง.
bmacx7

-3

ไม่เป็นไรไม่ได้สังเกต GMT -0400 ซึ่งทำให้วันที่เป็นวันวาน

คุณสามารถลองตั้งค่า "เวลา" เริ่มต้นเป็น 12:00:00


ใช่ฉันเร็วไปหน่อยกับคำตอบของฉันขอโทษเกี่ยวกับเรื่องนั้น แก้ไขคำตอบของฉัน
ChrisH

-3

ต่อไปนี้ทำงานให้ฉัน -

    var doo = new Date("2011-09-24").format("m/d/yyyy");

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