사파리에서 유효하지 않은 날짜


155
 alert(new Date('2010-11-29'));

크롬, ff에는 문제가 없지만 사파리는 "잘못된 날짜"를 외칩니다. 왜 ?

편집 : 좋아, 아래 의견에 따라 문자열 구문 분석을 사용하고 이것을 시도했습니다.

alert(new Date('11-29-2010')); //doesn't work in safari
alert(new Date('29-11-2010')); //doesn't work in safari
alert(new Date('2010-29-11')); //doesn't work in safari

2018 년 3 월 22 일 편집 : 사람들이 여전히 여기에 착륙하는 것처럼 보입니다. 오늘 나는 그것을 사용 moment하거나 date-fns끝낼 것입니다. Date-fns는 통증이없고 가벼워졌습니다.


같은 문제를보고있는 다른 사람을 위해 : DateJS를 사용하여 전반적인 문제를 해결했습니다. 자세한 내용은 허용 된 답변을 참조하십시오.
Shrinath

2
타임 스탬프를 구문 분석 하려면 moment.js 를 사용 하십시오. 특히 크로스 플랫폼 웹을 다룰 때
Ming Yuen

1
이것은 오래된 질문입니다. ECMAScript 2015부터 ISO 8601 날짜 전용 문자열은 UTC로 구문 분석됩니다. 그러나 브라우저를 전혀 구문 분석하지 않거나 로컬로 취급하지 않는 구형 브라우저가 여전히있을 수 있습니다.
RobG

답변:


167

패턴 yyyy-MM-ddDate생성자에 대해 공식적으로 지원되는 형식이 아닙니다 . Firefox는이를 지원하는 것 같지만 다른 브라우저에서도 마찬가지입니다.

지원되는 문자열은 다음과 같습니다.

  • MM-dd-yyyy
  • yyyy / MM / dd
  • MM / dd / yyyy
  • MMMM dd, yyyy
  • MMM dd, yyyy

DateJS 는 비표준 날짜 형식을 구문 분석하는 데 유용한 라이브러리처럼 보입니다.

편집 : 방금 ECMA-262 표준을 확인했습니다 . 섹션 15.9.1.15에서 인용 :

날짜 시간 문자열 형식

ECMAScript는 ISO 8601 확장 형식의 단순화를 기반으로 날짜-시간에 대한 문자열 교환 형식을 정의합니다. 형식은 다음과 같습니다. YYYY-MM-DDTHH : mm : ss.sssZ 여기서 필드는 다음과 같습니다.

  • YYYY는 그레고리력에서 연도의 10 진수입니다.
  • 문자열에 "-"(하이 폰)이 문자 그대로 두 번 나타납니다.
  • MM은 01 (1 월)에서 12 (12 월)까지의 달입니다.
  • DD는 01부터 31까지의 달입니다.
  • 문자열에 "T"가 나타나 시간 요소의 시작을 나타냅니다.
  • HH는 자정 이후 두 자릿수로 경과 한 완료 시간 수입니다.
  • ":"(콜론)은 문자열에서 문자 그대로 두 번 나타납니다.
  • mm은 시간 시작 이후 2 분의 10 진수로 완료된 분 수입니다.
  • ss는 분의 시작 이후 2 자리 10 진수로 표시되는 완료 시간 (초)입니다.
  • "." (점)은 문자 그대로 문자열에 나타납니다.
  • sss는 초가 시작된 이후의 완전한 밀리 초 수입니다 (3 자리 10 진수). "." 밀리 초 필드는 생략 될 수 있습니다.
  • Z는 "Z"(UTC의 경우) 또는 "+"또는 "-"로 지정된 시간대 오프셋이며 시간 표현은 hh : mm입니다.

이 형식에는 날짜 전용 양식이 포함됩니다.

  • YYYY
  • YYYY-MM
  • YYYY-MM-DD

선택적 시간대 오프셋이 추가 된 시간 전용 양식도 포함됩니다.

  • THH : mm
  • THH : mm : ss
  • THH : mm : ss.sss

상기의 임의의 조합 일 수있는 "날짜-시간"도 포함된다.

따라서 YYYY-MM-DD가 표준에 포함 된 것 같지만 어떤 이유로 Safari에서는이를 지원하지 않습니다.

업데이트 : datejs 문서를 보고 그것을 사용하면 다음과 같은 코드를 사용하여 문제를 해결해야합니다.

var myDate1 = Date.parseExact("29-11-2010", "dd-MM-yyyy");
var myDate2 = Date.parseExact("11-29-2010", "MM-dd-yyyy");
var myDate3 = Date.parseExact("2010-11-29", "yyyy-MM-dd");
var myDate4 = Date.parseExact("2010-29-11", "yyyy-dd-MM");

4
ISO8601 형식은 ECMAScript 표준 5 판에서 사용되며 IMO를 사용하는 가장 안전한 방법 인 아직 널리 지원되지는 않습니다. 날짜를 수동으로 구문 분석하십시오. (
CMS

1
그것은 매우 도움이되는 친구 .. 감사합니다 .. :) 마침내 형식화를 위해 datejs를 사용했습니다.
Shrinath

미래의 사람들을 위해, datejs는 대부분의 관점에서 환상적이지만, 특히 사파리에서 모든 날짜 형식 문제를 해결하지는 않습니다. PITA이지만 여전히 문제가있는 경우 수동으로 수행하는 것이 가장 좋습니다.
totallyNotLizards

@ darioo 그래서 나는 다음과 같이 대답을 시도했다 : "var start = Date.parseExact (timestamp,"YYYY-DD-MM HH : mm : SS ");" 타임 스탬프는 "2016-01-28 00:00:00"입니다. 그러나 이제 "Date.parseExact는 함수가 아닙니다"라는 오류가 발생합니다. 여기서 무슨 일이야?
threxx

5
비슷한 문제는 Safari가 시간대를 RFC 822 시간대 형식으로 읽는 방법을 모르기 때문에 발생했습니다. ISO 8601 형식을 사용하여이 문제를 해결할 수있었습니다. 날짜 형식을 제어 할 수있는 경우 "yyyy-MM-dd'T'HH : mm : ss.sssXXX"로 작업하여 ie를 만듭니다. "2018-02-06T20 : 00 : 00.000 + 00 : 00". 어떤 이유로 든 Safari가 "2018-02-06T20 : 00 : 00.000 + 0000"을 읽을 수없는 경우 시간대 형식에서 콜론이 부족합니다.
Olmstov

224

Safari에서 제대로 할 수 없기 때문에 새 라이브러리를 구현하는 것은 너무 많고 정규 표현식이 과도합니다. oneliner 는 다음과 같습니다 .

console.log (new Date('2011-04-12'.replace(/-/g, "/")));

슬래시를 얻는 것이 나의 문제 일 뿐이라면, 나는 당신의 대답을 '수락'했을 것입니다. dateJS를 찾았으므로 더 사용자 친화적 인 경험을 위해 MMM DD, YYYY 형식을 구현했습니다!
Shrinath

13
이 한 줄 도움은 내 필요에 완벽했습니다! 감사!
Cyril N.

4
이것은 나에게도 간단했다. Safari가-를 좋아하지 않는다는 것을 믿을 수는 없지만 \\와 동일한 형식입니다. 질문을 게시 해 주셔서 감사합니다 @Elzo 그리고 감사합니다 Shrinath
Pete

1
대신 / g -이 내가 / 잊지하는 경향이 가장 좋은 대답라고 생각합니다 '-'
제이 섹 Pietal에게

12
라이브러리를 구현하지 않은 것에 대한 박수 .
lharby

56

나는 비슷한 문제에 직면했다. Date.Parse("DATESTRING")Chrome (버전 59.0.3071.115)에서 작동했지만 Safari (버전 10.1.1 (11603.2.5)에서는 작동하지 않음)

원정 여행:

Date.parse("2017-01-22 11:57:00")
NaN

크롬:

Date.parse("2017-01-22 11:57:00")
1485115020000

나를 위해 일한 해결책은 dateString의 공백을로 바꾸는 것입니다 "T". (예 : dateString.replace(/ /g,"T"))

원정 여행:

Date.parse("2017-01-22T11:57:00")
1485086220000

크롬:

Date.parse("2017-01-22T11:57:00")
1485115020000

Safari가 로컬 TZ (UTC보다 8 시간 늦음)로 응답을 반환했기 때문에 Safari 브라우저의 응답이 Chrome 브라우저에서 표시되는 응답보다 8 시간 (28800000ms) 적습니다.

동일한 TZ에서 두 시간을 모두 얻으려면

원정 여행:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

크롬:

Date.parse("2017-01-22T11:57:00Z")
1485086220000

또는 Safari와 Chrome에서 날짜를 동일하게 유지하고 싶지 않은 경우 new Date(year, month, date, hours, minutes, seconds, milliseconds)생성자를 사용할 수 있습니다 . 생성자에서 해당 구성 요소를 사용하려면 문자열 날짜를 해당 구성 요소의 배열로 구문 분석하십시오. @nizantz 당신이 그러한 예가 당신의 대답에 추가 될 수 있다고 생각한다면 좋을 것입니다.
h3dkandi

현지 시간이 아닌 UTC로 날짜를 가져 오기 때문에 특히 유용하지 않습니다.
Jonas Äppelgran

1
dateString.replace(/ /g,"T")마법의 코드 줄은 저에게서 일했습니다. :)
Mazdak Shojaie

replace (/-/ g, '/')
Jack Hu

11

나는 문제를 해결하기 위해 순간을 사용합니다. 예를 들어

var startDate = moment('2015-07-06 08:00', 'YYYY-MM-DD HH:mm').toDate();


6

문자열을 Date fromat로 변환하십시오 (서버 시간대를 알아야 함)

new Date('2015-06-16 11:00:00'.replace(/\s+/g, 'T').concat('.000+08:00')).getTime()  

여기서 +08 : 00 = 서버에서 timeZone


이것은 DST를 고려하지 않습니다. TZ 오프셋은 변동될 수 있으며 날짜 및 시간에 따라 다릅니다.
코스타

5

나는 같은 문제가 있었고 순간을 사용했다 .Js. 문제가 사라졌다.

문자열에서 순간을 만들 때 먼저 문자열이 알려진 ISO 8601 형식과 일치하는지 확인한 다음 알려진 형식을 찾을 수 없으면 새 날짜 (문자열)로 폴백합니다.

경고 : 문자열 구문 분석에 대한 브라우저 지원이 일치하지 않습니다. 어떤 형식을 지원해야하는지에 대한 사양이 없으므로 일부 브라우저에서 작동하는 것은 다른 브라우저에서 작동하지 않습니다.

ISO 8601 문자열 이외의 것을 구문 분석하는 일관된 결과를 얻으려면 String + Format을 사용해야합니다.

예 :

var date= moment(String);

3

브라우저가 ISO 8601 (또는 날짜 전용 하위 집합)을 지원하기를 희망 할 수 있지만 , 그렇지 않습니다. 내가 아는 모든 브라우저 (적어도 내가 사용하는 미국 / 영어 로켈에서)는 끔찍한 미국 MM/DD/YYYY형식 을 구문 분석 할 수 있습니다.

날짜의 일부를 이미 가지고 있다면 대신 Date.UTC () 을 사용해보십시오 . 그렇지 않은 경우 YYYY-MM-DD형식 을 사용해야하는 경우 정규식을 사용하여 알고있는 조각을 구문 분석 한 다음에 전달하는 것이 Date.UTC()좋습니다.


문자열 파싱이 갈 길이라고 생각합니다. (
Shrinath

1

아래 형식을 사용하면 모든 브라우저에서 작동합니다.

var year = 2016;
var month = 02;           // month varies from 0-11 (Jan-Dec)
var day = 23;

month = month<10?"0"+month:month;        // to ensure YYYY-MM-DD format
day = day<10?"0"+day:day;

dateObj = new Date(year+"-"+month+"-"+day);

alert(dateObj); 

// 출력은 다음과 같습니다. "수 3 월 23 2016 00:00:00 GMT + 0530 (IST)"

//이 경우 IST로 표시된 현재 시간대에 있음을 유의하십시오. UTC 시간대로 변환하면 포함 할 수 있습니다

alert(dateObj.toUTCSting);

// 이제 출력은 "화, 2016 년 3 월 22 일 18:30:00 GMT"입니다.

이제 dateObj는 시간을 GMT 형식으로 표시하고 날짜와 시간도 그에 따라 변경되었습니다.

"toUTCSting"함수는 그리니치 자오선에서 해당 시간을 검색합니다. 이는 현재 시간대와 그리니치 자오선 시간대 간의 시차를 설정하여 수행됩니다.

위의 경우 변환 전 시간은 2016 년 3 월 23 일 00:00 시간 및 분이었습니다. GMT + 0530 (IST) 시간에서 GMT로 변환 후 (기본적으로 지정된 타임 스탬프에서 5.30 시간을 뺍니다. 사례) 시간은 2016 년 3 월 22 일 18.30 시간 (정확히 처음 5.30 시간 뒤)을 반영합니다.

또한 날짜 개체를 타임 스탬프로 변환하여 사용할 수 있습니다.

alert(dateObj.getTime());

// 출력은이 "1458671400000"과 유사합니다.

이것은 당신에게 시간의 독특한 타임 스탬프를 줄 것입니다



1

가장 좋은 방법은 다음 형식을 사용하는 것입니다.

new Date(year, month, day, hours, minutes, seconds, milliseconds)
var d = new Date(2018, 11, 24, 10, 33, 30, 0);

이것은 모든 브라우저에서 지원되며 문제를 일으키지 않습니다. 월은 0에서 11 사이로 작성됩니다.


Safari 및 Chrome에서는 잘 작동하지만 Firefox에서는 여전히 문제가 있습니다. Safari : var date = new Date (2018,06,08,19,17) Sun Jul 08 2018 19:17:00 GMT + 0800 (+08) Chrome : var date = 새로운 날짜 (2018,06,08,19, 17) 일 Jul 08 2018 19:17:00 GMT + 0800 (말레이시아 시간) Firefox : var date = new Date (2018,06,08,19,17) Date 2018-07-08T11 : 17 : 00.000Z
Biranchi

0

Safari에서 직면하는 것과 동일한 문제이며 웹 페이지에 삽입하여 해결되었습니다.

 <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script> 

그것이 당신의 경우에도 효과가 있기를 바랍니다.

감사


왜 이것이 효과가 있다고 생각합니까? 스크립트를 살펴본 결과 Date 객체의 메서드를 재정의하지 않는 것 같습니다. 나는 여기에 갔다 : polyfill.io/v3/url-builder 그리고 구문 분석 날짜에 대해서는 아무것도없는 것 같습니다.
코스타

0

@nizantz가 앞에서 언급했듯이 Date.parse () 사용은 Safari에서 작동하지 않았습니다. 약간의 연구 끝에 File 객체의 lastDateModified 속성은 더 이상 사용되지 않으며 Safari에서 더 이상 지원되지 않는다는 것을 알게되었습니다. File 객체의 lastModified 속성을 사용하면 문제가 해결되었습니다. 온라인에서 잘못된 정보가 발견되면 싫어합니다.

이 게시물에 기고 해 주신 모든 분들께 감사드립니다. 제가이 문제에 관해 배우기 위해 필요한 길을 밟도록 도와주었습니다. 이 정보가 없었다면 아마도 내 근본 문제를 알지 못했을 것입니다. 어쩌면 이것은 비슷한 상황에서 다른 누군가를 도울 것입니다.


0

Safari 브라우저에서도 동일한 문제에 직면하고 있습니다.

var date = new Date("2011-02-07");
console.log(date) // IE you get ‘NaN’ returned and in Safari you get ‘Invalid Date’

해결책은 다음과 같습니다.

var d = new Date(2011, 01, 07); // yyyy, mm-1, dd  
var d = new Date(2011, 01, 07, 11, 05, 00); // yyyy, mm-1, dd, hh, mm, ss  
var d = new Date("02/07/2011"); // "mm/dd/yyyy"  
var d = new Date("02/07/2011 11:05:00"); // "mm/dd/yyyy hh:mm:ss"  
var d = new Date(1297076700000); // milliseconds  
var d = new Date("Mon Feb 07 2011 11:05:00 GMT"); // ""Day Mon dd yyyy hh:mm:ss GMT/UTC 

0

이것은 단순히 오류를 포착하고 현재 날짜를 다시 보내지 만 최선의 해결책은 아닙니다. 사용자가 sh * t 비표준 호환 브라우저를 사용하려는 경우 사파리 문제를 해결하지 않는 것 같습니다.

function safeDate(dateString = "") {
  let date = new Date();
  try {
    if (Date.parse(dateString)) {
      date = new Date(Date.parse(dateString))
    }
  } catch (error) {
    // do nothing.
  }
  return date;
}

백엔드에 ISO 날짜를 보내도록 제안합니다.


모든면에서 사용자 코드를 작성한 브라우저를 사용해야 한다는 의미 는 일반적으로보기에 좋지 않습니다. 또한 사용 사례와 대상 고객에 따라 다릅니다. 웹 사이트가 대량 시장 소 비용으로 구축되는 경우 최소한 IE10도 지원할 것입니다. 인터넷 익스플로러를 위해 디자인 / 코딩 할 때 MS의 누군가가 똑같이 생각했다고 확신합니다. 우리는 지금 그것이 어떻게 말하는지 알고 있습니다.
Shrinath

-1

'mm / dd / yyyy'형식을 사용하십시오. 예를 들면 :-new Date ('02 / 28 / 2015 '). 모든 브라우저에서 잘 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.