ใหม่ Date () ใช้งานได้ใน Chrome แต่ไม่ใช่ Firefox


93

ฉันกำลังสร้างสตริงวันที่และเวลาที่มีลักษณะดังนี้: 2010-07-15 11:54:21

และด้วยรหัสต่อไปนี้ฉันได้รับวันที่ไม่ถูกต้องใน Firefox แต่ใช้งานได้ดีใน Chrome

var todayDateTime = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;
var date1 = new Date(todayDateTime);

ใน firefox date1 ให้วันที่ที่ไม่ถูกต้องแก่ฉัน แต่ใน chrome มันใช้งานได้ดีอะไรคือสาเหตุหลัก?


2
หากคุณต้องการเล่นด้วยวิธีใดก็ได้ที่คุณต้องการไปกับdatejs.com
Sinan

การใช้งานบางอย่างไม่สนับสนุนรูปแบบใน ECMA-262 ดังนั้นจึงควรแยกวิเคราะห์สตริงด้วยตนเองเสมอ (ไลบรารีสามารถช่วยได้ แต่อาจไม่จำเป็นสำหรับรูปแบบเดียว)
RobG

ตอนนี้ใช้งาน Firefox ได้แล้ว
Sm Yamashita

คำตอบ:


80

คุณไม่สามารถสร้างอินสแตนซ์วัตถุวันที่ได้ตามที่คุณต้องการ จะต้องเป็นไปในลักษณะเฉพาะ นี่คือตัวอย่างที่ถูกต้อง:

new Date() // current date and time
new Date(milliseconds) //milliseconds since 1970/01/01
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)

หรือ

d1 = new Date("October 13, 1975 11:13:00")
d2 = new Date(79,5,24)
d3 = new Date(79,5,24,11,33,0)

Chrome ต้องมีความยืดหยุ่นมากขึ้น

ที่มา: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

จากความคิดเห็นของapsillers :

ข้อกำหนด EMCAScript ต้องการรูปแบบวันที่เดียวเท่านั้น (เช่น YYYY-MM-DDTHH: mm: ss.sssZ) แต่รูปแบบวันที่ที่กำหนดเองอาจได้รับการสนับสนุนอย่างอิสระโดยการใช้งาน : " หากสตริงไม่เป็นไปตามรูปแบบ [กำหนดโดย ECMAScript] นั้น ฟังก์ชันนี้อาจกลับไปใช้การวิเคราะห์พฤติกรรมเฉพาะการใช้งานหรือรูปแบบวันที่เฉพาะการนำไปใช้งาน "Chrome และ FF มี" รูปแบบวันที่เฉพาะการใช้งาน "ที่แตกต่างกัน


4
ฉันได้รับโซลูชันที่ใช้ได้กับทุกเบราว์เซอร์รวมถึง Firefox: stackoverflow.com/a/21984717/586051
Rahul Desai

7
สาเหตุที่ความแตกต่างของเบราว์เซอร์นี้มีอยู่: ข้อกำหนด EMCAScript ต้องการรูปแบบวันที่เดียวเท่านั้น (กล่าวคือYYYY-MM-DDTHH:mm:ss.sssZ) แต่รูปแบบวันที่ที่กำหนดเองอาจได้รับการสนับสนุนอย่างอิสระจากการใช้งาน : " หากสตริงไม่สอดคล้องกับรูปแบบ [กำหนดโดย ECMAScript] ฟังก์ชันอาจ ถอยกลับไปใช้การวิเคราะห์พฤติกรรมเฉพาะการใช้งานหรือรูปแบบวันที่เฉพาะการนำไปใช้งาน "Chrome และ FF มี" รูปแบบวันที่เฉพาะการใช้งาน "ที่แตกต่างกัน
apsillers

ตัวอย่างหนึ่งของรูปแบบวันที่ (เดือนที่มี ".") ที่ทำงานใน Chrome แต่ใช้ไม่ได้ใน Firefox: 'ก.พ. 14, 2019 '
codecribblr

สิ่งนี้ใช้ได้กับฉันใน firefox เท่านั้นถ้าฉันเพิ่ม'เป็นมิลลิวินาทีDate('milliseconds')มิฉะนั้นฉันได้รับข้อผิดพลาดที่แจ้งว่าไม่ได้กำหนดมิลลิวินาที แต่อย่างน้อยก็ใช้ได้ผลโดยที่การทดลองอื่น ๆ ล้มเหลว ดูเหมือนว่ายังมีความสุขใน Chrome
Steve

24

สิ่งนี้ใช้ได้กับทุกเบราว์เซอร์ -

new Date ('2001/01/31 12:00:00 AM')

new Date('2001-01-31 12:00:00')

รูปแบบ: YYYY-MM-DDTHH: mm: ss.sss

รายละเอียด: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15


เพราะเราทุกคนรู้ดีว่าเป็นมาตรฐานสากล w3.org/International/questions/qa-date-format
Bobby Tables

6
คุณได้ทดสอบเบราว์เซอร์ทั้งหมดแล้วจริงหรือ? และสมมติว่าคุณมีคุณรู้ด้วยว่าเบราว์เซอร์ทั้งหมดในอนาคตจะรองรับรูปแบบ (ที่ไม่ได้มาตรฐาน) นั้นด้วยหรือไม่
RobG

1
สิ่งนี้ใช้ได้กับฉัน ดังนั้นหากคุณได้สตริง '2001-1-31 12:00:00' แล้วเราสามารถทำได้: new Date (str.replace (/ - / g, '/'));
Jianwu Chen

@JianwuChen คุณจงใจแก้ไขรูปแบบมาตรฐานให้เป็นรูปแบบที่ไม่ได้มาตรฐาน ไม่ใช่ความคิดที่ดี
JJJ

2
หลังจาก 3 ปีต่อมาจะไม่ทำงานบน Edge และ Window Safari
Mg Thar

13

ตัวเลือกที่ 1 :

สมมติว่าการลงเวลาของคุณมีรูปแบบที่มีลักษณะดังนี้:

'2016-03-10 16:00:00.0'

ในกรณีนั้นคุณสามารถทำการ regex ง่ายๆเพื่อแปลงเป็นISO 8601:

'2016-03-10 16:00:00.0'.replace(/ /g,'T')

สิ่งนี้จะส่งผลลัพธ์ต่อไปนี้:

'2016-03-10T16:00:00.0'

นี่คือรูปแบบวันที่และเวลามาตรฐานซึ่งรองรับโดยเบราว์เซอร์ทั้งหมด:

document.body.innerHTML = new Date('2016-03-10T16:00:00.0') // THIS IS SAFE TO USE

ทางเลือกที่ 2:

สมมติว่าการลงเวลาของคุณมีรูปแบบที่มีลักษณะดังนี้:

'02-24-2015 09:22:21 PM'

คุณสามารถทำ regex ต่อไปนี้ได้ที่นี่:

'02-24-2015 09:22:21 PM'.replace(/-/g,'/');

สิ่งนี้ก็สร้างรูปแบบที่รองรับโดยเบราว์เซอร์ทั้งหมด:

document.body.innerHTML = new Date('02/24/2015 09:22:21 PM') // THIS IS SAFE TO USE

ทางเลือกที่ 3:

สมมติว่าคุณมีสตริงเวลาที่ไม่ง่ายในการปรับให้เข้ากับมาตรฐานที่รองรับอย่างดี

ในกรณีนี้ขอแนะนำให้แยกสตริงเวลาออกเป็นส่วนต่างๆและใช้เป็นพารามิเตอร์แต่ละตัวสำหรับDate:

document.body.innerHTML = new Date(2016, 2, 26, 3, 24, 0); // THIS IS SAFE TO USE


1
var d = new Date ('2017-08-28 20:02 PM'.replace (/ - / g,' / ')); สิ่งนี้ใช้ได้กับฉันในโครเมี่ยมและในโมซิลล่า
Rahul Mankar

13

ซึ่งใช้ได้กับเบราว์เซอร์ส่วนใหญ่เช่นกัน

new Date('2001/01/31 12:00:00')

นั่นคือรูปแบบของ

"yyyy/MM/dd HH:mm:ss"

3
ไม่มีการรับประกันว่ารูปแบบจะทำงานในเบราว์เซอร์ใด ๆ น้อยกว่า "ทั้งหมด" มาก
RobG

คุณพูดถูกแล้วคำตอบนั้นมาจากประสบการณ์ของฉัน
Alvis

8

หากคุณยังต้องการสร้างวันที่โดยใช้ขีดกลางคุณสามารถใช้รูปแบบนี้:

var date = new Date('2013-08-31T17:00:00Z')

แต่จำไว้ว่ามันสร้างเวลาตาม UTC หมายความว่าถ้าคุณอาศัยอยู่ในเขตเวลา GMT + 3 (3 ชั่วโมงก่อนเวลา GMT) ระบบจะเพิ่มเขตเวลานี้ให้กับเวลา ดังนั้นตัวอย่างข้างต้นจะมีค่านี้ถ้า GMT + 3 (โปรดทราบว่าเป็นเวลา 20:00 น. และไม่ใช่ 17:00 น.):

Sat Aug 31 2013 20:00:00 GMT+0300 (FLE Standard Time)

อย่าลืมเพิ่มตัวอักษร 'Z' ต่อท้ายเพราะมิฉะนั้น Chrome และ Firefox จะแยกวิเคราะห์สตริงต่างกัน (อันหนึ่งจะเพิ่มการชดเชยเวลาและอีกอันจะไม่)


1
ใช่ Chrome และ Firefox ทำงานแตกต่างกันหากคุณไม่ได้ระบุเขตเวลา และไม่น่าสนใจฉันคิดว่า firefox ทำผิด ควรถือว่า GMT หากไม่มีเขตเวลา Chrome ทำ แต่ firefox ไม่ทำ ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
Julian Jelfs

@ JulianJelfs— " ควรถือว่า GMT ถ้าไม่มีเขตเวลา " เฉพาะวันที่ (ตรงกันข้ามกับ ISO 8601) สำหรับสตริงวันที่และเวลาควรถือว่าเป็นค่าท้องถิ่น (สอดคล้องกับ ISO 8601) แต่ไม่ว่าในกรณีใดการแยกวิเคราะห์ด้วยตนเองเป็นวิธีเดียวที่ปลอดภัยที่จะไป
RobG

5

ฉันมีปัญหาคล้ายกันทั้งใน Firefox และ Safari เมื่อทำงานกับ AngularJS ตัวอย่างเช่นหากวันที่กลับมาจาก Angular มีลักษณะดังนี้:

2014-06-02 10:28:00

โดยใช้รหัสนี้:

new Date('2014-06-02 10:28:00').toISOString();

ส่งกลับข้อผิดพลาดวันที่ที่ไม่ถูกต้องใน Firefox และ Safari อย่างไรก็ตามใน Chrome ใช้งานได้ดี ตามคำตอบอื่นที่ระบุไว้ Chrome มักจะยืดหยุ่นกว่าด้วยการแยกวิเคราะห์สตริงวันที่

เป้าหมายในที่สุดของฉันคือการจัดรูปแบบวันที่ด้วยวิธีหนึ่ง ฉันพบไลบรารีที่ยอดเยี่ยมที่จัดการทั้งปัญหาความเข้ากันได้ข้ามเบราว์เซอร์และปัญหาการจัดรูปแบบวันที่ ห้องสมุดที่เรียกว่าmoment.js

การใช้ไลบรารีนี้รหัสต่อไปนี้ทำงานได้อย่างถูกต้องในทุกเบราว์เซอร์ที่ฉันทดสอบ:

moment('2014-06-02 10:28:00').format('MMM d YY')

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


คุณควรเสมอผ่านรูปแบบการmoment.jsเมื่อแยกสตริงมิฉะนั้นมันก็เดาได้จนกว่าจะพบหนึ่งที่สร้างวันที่ถูกต้อง
RobG

4

สิ่งนี้ควรได้ผลสำหรับคุณ:

var date1 = new Date(year, month, day, hour, minute, seconds);

ฉันต้องสร้างวันที่ในรูปแบบสตริงดังนั้นฉันจึงทำดังนี้:

var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2), d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));

จำไว้ว่าเดือนในจาวาสคริปต์อยู่ระหว่าง 0 ถึง 11 ดังนั้นคุณควรลดค่าเดือนลง 1 เช่นนี้:

var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2) - 1, d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));

2

วิธีแก้ปัญหาง่ายๆใช้ได้กับเบราว์เซอร์ทั้งหมด

var StringDate = "24-11-2017"   
var DateVar = StringDate.split("-");
var DateVal = new Date(DateVar[1] + "/" + DateVar[0] + "/" + DateVar[2]);
alert(DateVal);

1

สถานการณ์หนึ่งที่ฉันพบคือเมื่อต้องรับมือกับมิลลิวินาที FF และ IE จะไม่แยกวิเคราะห์สตริงวันที่นี้อย่างถูกต้องเมื่อพยายามสร้างวันที่ใหม่ "2014/11/24 17:38:20.177Z" พวกเขาไม่รู้ว่าจะจัดการ.177Zอย่างไร Chrome จะทำงานได้


1

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉันFirefoxและChrome:

// The format is 'year-month-date hr:mins:seconds.milliseconds'
const d = new Date('2020-1-4 12:00:00.999') 
// we use the `.` separator between seconds and milliseconds.

โชคดี...


0

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

  var outputDate = new Date(Date.parse(inputString));

แต่สำหรับ Firefox และ Safari สิ่งต่างๆมีความซับซ้อนมากขึ้น อันที่จริงในเอกสารของ Firefox ได้กล่าวไว้แล้ว: ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse )

สตริงที่แสดงวันที่ RFC2822 หรือ ISO 8601 (อาจใช้รูปแบบอื่นได้ แต่ผลลัพธ์อาจไม่คาดคิด)

ดังนั้นเมื่อคุณต้องการใช้Date.parseใน Firefox และ Safari คุณควรระมัดระวัง สำหรับฉันฉันใช้วิธีหลอกล่อเพื่อจัดการกับมัน (หมายเหตุ: อาจไม่ถูกต้องเสมอไปในทุกกรณี)

if (input.indexOf("UTC") != -1) {
  var tempInput = inputString.substr(0, 10) + "T" + inputString.substr(11, 8) + "Z";
  date = new Date(Date.parse(tempInput));
}

ที่นี่จะแปลง2013-08-08 11:52:18 UTCเป็น2013-08-08T11: 52: 18Zก่อนจากนั้นรูปแบบจะพอดีกับคำในเอกสารของ Firefox ในเวลานี้ Date.parse จะถูกเสมอในทุกเบราว์เซอร์


0

มีข้อกำหนด W3C ที่กำหนดสตริงวันที่ที่เป็นไปได้ซึ่งเบราว์เซอร์ใด ๆ ควรแยกวิเคราะห์ (รวมถึง Firefox และ Safari):

Year:
   YYYY (e.g., 1997)
Year and month:
   YYYY-MM (e.g., 1997-07)
Complete date:
   YYYY-MM-DD (e.g., 1997-07-16)
Complete date plus hours and minutes:
   YYYY-MM-DDThh:mmTZD (e.g., 1997-07-16T19:20+01:00)
Complete date plus hours, minutes and seconds:
   YYYY-MM-DDThh:mm:ssTZD (e.g., 1997-07-16T19:20:30+01:00)
Complete date plus hours, minutes, seconds and a decimal fraction of a
second
   YYYY-MM-DDThh:mm:ss.sTZD (e.g., 1997-07-16T19:20:30.45+01:00)

ที่ไหน

YYYY = four-digit year
MM   = two-digit month (01=January, etc.)
DD   = two-digit day of month (01 through 31)
hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
mm   = two digits of minute (00 through 59)
ss   = two digits of second (00 through 59)
s    = one or more digits representing a decimal fraction of a second
TZD  = time zone designator (Z or +hh:mm or -hh:mm)

ตามYYYY-MM-DDThh:mmTZDตัวอย่าง2010-07-15 11:54:21จะต้องถูกแปลงเป็น2010-07-15T11:54:21Zหรือ2010-07-15T11:54:21+02:00(หรือด้วยเขตเวลาอื่น)

นี่คือตัวอย่างสั้น ๆ ที่แสดงผลลัพธ์ของแต่ละตัวแปร:

const oldDateString = '2010-07-15 11:54:21'
const newDateStringWithoutTZD = '2010-07-15T11:54:21Z'
const newDateStringWithTZD = '2010-07-15T11:54:21+02:00'
document.getElementById('oldDateString').innerHTML = (new Date(oldDateString)).toString()
document.getElementById('newDateStringWithoutTZD').innerHTML = (new Date(newDateStringWithoutTZD)).toString()
document.getElementById('newDateStringWithTZD').innerHTML = (new Date(newDateStringWithTZD)).toString()
div {
  padding: 10px;
}
<div>
  <strong>Old Date String</strong>
  <br>
  <span id="oldDateString"></span>
</div>
<div>
  <strong>New Date String (without Timezone)</strong>
  <br>
  <span id="newDateStringWithoutTZD"></span>
</div>
<div>
  <strong>New Date String (with Timezone)</strong>
  <br>
  <span id="newDateStringWithTZD"></span>
</div>


-1

ใน Firefox, วันที่ไม่ถูกต้องจะถูกส่งกลับเป็นวัตถุวันที่เป็นวัน1899-11-29T19:00:00.000Zจึงตรวจสอบว่าเบราว์เซอร์ Firefox "1899-11-29T19:00:00.000Z".getDate()จากนั้นได้รับวัตถุวันของสตริง สุดท้ายเปรียบเทียบกับวันที่


นี่ไม่ได้อธิบายถึงสาเหตุของปัญหา แต่เป็นการอธิบายว่าผลลัพธ์ของปัญหาจะเป็นอย่างไร
Rytis

-1

ฉันใช้รูปแบบวันที่ต่อไปนี้และใช้งานได้ในทุกเบราว์เซอร์

var target_date = new Date("Jul 17, 2015 16:55:22").getTime();

var days, hours, minutes, seconds;

var countdown = document.getElementById("countdown");

remaining = setInterval(function () {

    var current_date = new Date().getTime();
    var seconds_left = (target_date - current_date) / 1000;
    days = parseInt(seconds_left / 86400);
    seconds_left = seconds_left % 86400;
    hours = parseInt(seconds_left / 3600);
    seconds_left = seconds_left % 3600;
    minutes = parseInt(seconds_left / 60);
    seconds = parseInt(seconds_left % 60);
    countdown.innerHTML = "<b>"+days + " day, " + hours + " hour, "
        + minutes + " minute, " + seconds + " second.</b>";  
}, 1000);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.