사례 하나 :
new Date(Date.parse("Jul 8, 2005"));
산출:
2005 년 7 월 08 일 00:00:00 GMT-0700 (PST)
사례 2 :
new Date(Date.parse("2005-07-08"));
산출:
2005 년 7 월 7 일 목요일 17:00:00 GMT-0700 (PST)
두 번째 구문 분석이 왜 올바르지 않습니까?
답변
5 판 사양이 나왔다까지, Date.parse
방법은 완전히이었다 의존 구현 ( new Date(string)
와 같습니다 Date.parse(string)
(A)보다 숫자가 아니라 후자의 반환을 제외시켰다 Date
). 5 판 개정판에서는 단순화 된 (약간 틀린) ISO-8601 을 지원하기 위해 요구 사항이 추가되었습니다 (또한 참조). JavaScript에서 유효한 날짜 시간 문자열이란 무엇입니까? 참조 ). 하지만 그 이외 없었다 어떤 무엇에 대한 요구 사항 Date.parse
/ new Date(string)
무엇이든 그들이 동의했다는 것을 이외의 동의를해야 Date#toString
출력 (했다 그 어떤 말도없이).
ECMAScript 2017 (버전 8)부터 Date#toString
및 의 출력을 구문 분석하려면 구현이 필요 Date#toUTCString
했지만 해당 문자열의 형식은 지정되지 않았습니다.
ECMAScript 2019 (9 판)부터 Date#toString
및 의 형식은 Date#toUTCString
(각각)으로 지정되었습니다.
- ddd MMM DD YYYY HH : mm : ss ZZ [(시간대 이름)]
예 : 2018 년 7 월 10 일 화요일 18:39:58 GMT + 0530 (IST) - ddd, DD MMM YYYY HH : mm : ss Z
예 : 화 10 Jul 2018 13:09:58 GMT
Date.parse
새로운 구현에서 안정적으로 구문 분석해야하는 2 가지 형식을 추가로 제공 합니다 (지원이 어디에서나 사용되지 않으며 비준수 구현은 얼마 동안 계속 사용됨).
날짜 문자열을 수동으로 구문 분석하고 Date 생성자 가 연도, 월 및 일 인수와 함께 사용하여 모호성을 피하는 것이 좋습니다 .
// parse a date in yyyy-mm-dd format
function parseDate(input) {
let parts = input.split('-');
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}
답변
최근 JS 통역사를 쓴 경험을 통해 ECMA / JS 날짜의 내부 작업에 많은 어려움을 겪었습니다. 그래서 여기에 2 센트를 넣을 것이라고 생각합니다. 이 자료를 공유하면 브라우저가 날짜를 처리하는 방식의 차이점에 대한 질문에 다른 사람들이 도움이되기를 바랍니다.
입력측
모든 구현은 1970-01-01 UTC (GMT는 UTC와 동일 함) 이후 밀리 초 (ms) 수를 나타내는 64 비트 숫자로 내부적으로 날짜 값을 저장합니다. 이 날짜는 ECMAScript 시대이며 Java와 같은 다른 언어와 UNIX와 같은 POSIX 시스템에서도 사용됩니다. 신기원 이후에 발생한 날짜는 양수이고 이전 날짜는 음수입니다.
다음 코드는 모든 현재 브라우저에서 동일한 날짜로 해석되지만 현지 시간대 오프셋이 사용됩니다.
Date.parse('1/1/1970'); // 1 January, 1970
내 시간대 (EST, -05 : 00)에서 결과는 18000000입니다. 왜냐하면 5 시간 안에 몇 ms가 있기 때문입니다 (일광 절약 시간 동안 4 시간에 불과합니다). 시간대에 따라 값이 달라집니다. 이 동작은 ECMA-262에 지정되어 있으므로 모든 브라우저가 동일한 방식으로 작동합니다.
주요 브라우저가 날짜로 구문 분석하는 입력 문자열 형식에는 약간의 차이가 있지만, 구문 분석이 구현에 크게 의존하더라도 시간대와 일광 절약에 관한 한 기본적으로 동일하게 해석합니다.
그러나 ISO 8601 형식이 다릅니다. ECMAScript 2015 (ed 6)에 요약 된 두 가지 형식 중 하나이며 특히 모든 구현에서 동일한 방식으로 구문 분석해야합니다 (다른 형식은 Date.prototype.toString에 지정된 형식 임 ).
그러나 ISO 8601 형식 문자열의 경우에도 일부 구현에서는 잘못 구현됩니다. 다음은이 답변이 모든 구현에서 정확히 동일한 값으로 구문 분석 해야하는 ISO 8601 형식 문자열을 사용하여 내 컴퓨터에서 1/1/1970 (에포크)로 작성된 경우 Chrome과 Firefox의 비교 출력입니다 .
Date.parse('1970-01-01T00:00:00Z'); // Chrome: 0 FF: 0
Date.parse('1970-01-01T00:00:00-0500'); // Chrome: 18000000 FF: 18000000
Date.parse('1970-01-01T00:00:00'); // Chrome: 0 FF: 18000000
- 첫 번째 경우 “Z”지정자는 입력이 UTC 시간이므로 에포크에서 오프셋되지 않고 결과가 0임을 나타냅니다.
- 두 번째 경우 “-0500″지정자는 입력이 GMT-05 : 00에 있고 두 브라우저 모두 입력이 -05 : 00 시간대에있는 것으로 해석합니다. 즉, UTC 값은 에포크에서 오프셋되어 날짜의 내부 시간 값에 18000000ms를 추가하는 것을 의미합니다.
- 지정자가없는 세 번째 경우 는 호스트 시스템의 로컬로 처리 해야 합니다. FF는 입력을 현지 시간으로 올바르게 처리하는 반면 Chrome은 입력을 UTC로 처리하므로 다른 시간 값을 생성합니다. 나에게 이것은 저장된 값에서 5 시간의 차이를 생성하는데 문제가 있습니다. 오프셋이 다른 다른 시스템은 다른 결과를 얻습니다.
이 차이는 2020 년부터 수정되었지만 ISO 8601 형식 문자열을 구문 분석 할 때 브라우저간에 다른 문제가 있습니다.
그러나 악화됩니다. ECMA-262의 단점은 ISO 8601 날짜 전용 형식 (YYYY-MM-DD)을 UTC로 구문 분석해야하는 반면 ISO 8601은 로컬 형식으로 구문 분석해야한다는 점입니다. 시간대 지정자가없는 길고 짧은 ISO 날짜 형식의 FF 출력 결과는 다음과 같습니다.
Date.parse('1970-01-01T00:00:00'); // 18000000
Date.parse('1970-01-01'); // 0
따라서 첫 번째는 표준 시간대가없는 ISO 8601 날짜 및 시간이므로 로컬로 구문 분석되고 두 번째는 ISO 8601 날짜 만이므로 UTC로 구문 분석됩니다.
따라서 원래 질문에 직접 대답하려면 "YYYY-MM-DD"
ECMA-262에서 UTC로 해석해야하고 다른 질문은 로컬로 해석해야합니다. 그 이유는 다음과 같습니다.
이것은 동등한 결과를 생성하지 않습니다.
console.log(new Date(Date.parse("Jul 8, 2005")).toString()); // Local
console.log(new Date(Date.parse("2005-07-08")).toString()); // UTC
이것은 :
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());
결론은 날짜 문자열을 구문 분석하는 것입니다. 브라우저에서 안전하게 구문 분석 할 수있는 유일한 ISO 8601 문자열 은 오프셋 이있는 긴 형식 (± HH : mm 또는 “Z”)입니다. 그렇게하면 현지 시간과 UTC 시간 사이를 안전하게 이동할 수 있습니다.
이것은 IE9 이후의 브라우저에서 작동합니다.
console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());
대부분의 최신 브라우저는 자주 사용되는 ‘1/1/1970′(M / D / YYYY) 및 ‘1/1/1970 00:00:00 AM'(M / D / YYYY hh)을 포함하여 다른 입력 형식을 동일하게 취급합니다. : mm : ss ap) 형식입니다. 다음 형식 (마지막 제외)은 모두 모든 브라우저에서 현지 시간 입력으로 처리됩니다. 이 코드의 출력은 내 시간대의 모든 브라우저에서 동일합니다. 오프셋은 타임 스탬프에 설정되어 있기 때문에 마지막 시간대는 호스트 시간대와 상관없이 -05 : 00으로 처리됩니다.
console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));
그러나 ECMA-262에 지정된 형식의 구문 분석도 일관되지 않으므로 내장 구문 분석기에 의존하지 말고 라이브러리를 사용하여 구문 분석기에 형식을 제공하는 등 항상 문자열을 수동으로 구문 분석하는 것이 좋습니다.
예를 들어 moment.js에서는 다음과 같이 작성할 수 있습니다.
let m = moment('1/1/1970', 'M/D/YYYY');
출력측
출력 측에서 모든 브라우저는 시간대를 동일한 방식으로 변환하지만 문자열 형식을 다르게 처리합니다. 다음은 toString
기능과 출력 내용입니다. 통지 toUTCString
및 toISOString
내 컴퓨터에 기능 출력 오전 5:00. 또한 시간대 이름은 약어 일 수 있으며 구현에 따라 다를 수 있습니다.
인쇄하기 전에 UTC에서 현지 시간으로 변환
- toString
- toDateString
- toTimeString
- toLocaleString
- toLocaleDateString
- toLocaleTimeString
저장된 UTC 시간을 직접 인쇄합니다
- toUTCString
- toISOString
Chrome에서
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString 1/1/1970 12:00:00 AM
toLocaleDateString 1/1/1970
toLocaleTimeString 00:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
Firefox에서
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString Thursday, January 01, 1970
toLocaleTimeString 12:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
나는 일반적으로 문자열 입력에 ISO 형식을 사용하지 않습니다. 해당 형식을 사용하는 것이 유익한 유일한 날짜는 날짜를 문자열로 정렬해야 할 때입니다. ISO 형식은있는 그대로 정렬 할 수 있지만 다른 형식은 정렬 할 수 없습니다. 브라우저 간 호환성이 필요한 경우 시간대를 지정하거나 호환 가능한 문자열 형식을 사용하십시오.
코드 new Date('12/4/2013').toString()
는 다음과 같은 내부 의사 변환을 거칩니다.
"12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"
이 답변이 도움이 되었기를 바랍니다.
답변
광기에 대한 몇 가지 방법이 있습니다. 일반적으로 브라우저가 날짜를 ISO-8601로 해석 할 수 있다면 그렇게됩니다. “2005-07-08″이이 캠프에 속하므로 UTC로 구문 분석됩니다. “2005 년 7 월 8 일”은 현지 시간으로 구문 분석 할 수 없습니다.
페이지의 자바 스크립트와 날짜, 무엇 엉망! 이상.
답변
다른 해결책은 날짜 형식으로 연관 배열을 작성한 다음 데이터를 다시 형식화하는 것입니다.
이 방법은 날짜가 비정상적인 방식으로 유용합니다.
예를 들면 :
mydate='01.02.12 10:20:43':
myformat='dd/mm/yy HH:MM:ss';
dtsplit=mydate.split(/[\/ .:]/);
dfsplit=myformat.split(/[\/ .:]/);
// creates assoc array for date
df = new Array();
for(dc=0;dc<6;dc++) {
df[dfsplit[dc]]=dtsplit[dc];
}
// uses assc array for standard mysql format
dstring[r] = '20'+df['yy']+'-'+df['mm']+'-'+df['dd'];
dstring[r] += ' '+df['HH']+':'+df['MM']+':'+df['ss'];
답변
moment.js 를 사용 하여 날짜를 구문 분석 하십시오 .
var caseOne = moment("Jul 8, 2005", "MMM D, YYYY", true).toDate();
var caseTwo = moment("2005-07-08", "YYYY-MM-DD", true).toDate();
세 번째 인수는 엄격한 구문 분석을 결정합니다 (2.3.0부터 사용 가능). 그것없이 moment.js는 또한 잘못된 결과를 줄 수 있습니다.
답변
http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html 에 따르면 “yyyy / mm / dd”형식은 일반적인 문제를 해결합니다. “언제나 가능하면 날짜 문자열을”YYYY / MM / DD “로 고정하십시오. 보편적으로 지원되며 모호하지 않습니다.이 형식으로 모든 시간은 현지 시간입니다.” 나는 일련의 테스트를했습니다 : http://jsfiddle.net/jlanus/ND2Qg/432/
이 형식 : +는 YMD 주문 및 4 자리 연도 +를 사용하여 월과 일 주문 모호성을 피할 UTC 대 지역 문제를하지 방지 dygraphs guy 인 슬래시 + danvk를 사용하여 ISO 형식을 준수 하면이 형식이 모든 브라우저에서 적합하다고 말합니다.
답변
하지만 CMS가 올바른지 구문 분석 방법으로 문자열을 전달하는 것은 일반적으로 안전하지 않은 것으로, 새로운 ECMA-262 5 판 섹션 15.9.4.2에서 (ES5 일명) 사양은 알 수 Date.parse()
실제로 ISO 형식의 날짜를 처리해야합니다. 구 사양은 그러한 주장을하지 않았다. 물론 이전 브라우저와 일부 최신 브라우저는 여전히이 ES5 기능을 제공하지 않습니다.
두 번째 예는 틀리지 않습니다. 에 의해 암시 된대로 UTC로 지정된 날짜 Date.prototype.toISOString()
이지만 현지 시간대로 표시됩니다.