[javascript] “2016-02-16″이 “2016-02-16 00:00″과 같지 않은 이유는 무엇입니까?

두 날짜 문자열을 모두 new Date(t).

두 문자열이 같은 시간을 나타내기를 기대합니다. 결국 시간을 생략하면 그날 자정이 아니겠습니까?

하지만

new Date("2016-02-16 00:00")

예상대로 2016-02-16, 자정, 현지 시간을 반환합니다.

new Date("2016-02-16")

2016-02-16, 자정 UTC를 반환합니다. 이는 잘못되었거나 다른 문자열이 구문 분석하는 것을 고려할 때 내가 예상했던 것과는 다릅니다.

시간을 현지 시간으로 반환하든 UTC로 반환하든 둘 다 동일한 동작을한다면 이해할 수 있지만, 이와 같이 다른 것을 반환하는 이유는 매우 일관성이 없어 보입니다.

해결 방법으로 해당하는 타임 스탬프가없는 날짜를 발견 할 때마다 “00:00″을 추가하여 일관된 동작을 얻을 수 있지만 이것은 다소 취약한 것처럼 보입니다.

‘datetime-local’유형의 INPUT 요소에서이 값을 얻고 있으므로 페이지 요소에서 반환 된 값을 처리해야하는 것이 특히 일치하지 않는 것 같습니다.

내가 뭘 잘못하고있는 건가요, 아니면 다르게해야할까요?



답변

그것은 무엇 ES5.1 사양 할 말합니다 :

없는 시간대 오프셋 값은 “Z”입니다.

또한 다음과 같이 말합니다.

이 함수는 먼저 날짜 시간 문자열 형식 (15.9.1.15)에서 호출 된 규칙에 따라 문자열의 형식을 구문 분석하려고합니다. 문자열이 해당 형식을 따르지 않는 경우 함수는 구현 별 휴리스틱 또는 구현 별 날짜 형식으로 대체 될 수 있습니다.

형식에는 T날짜와 시간 사이 에 구분자가 필요하므로 유효한 시간은 UTC로 이동합니다.

> new Date("2016-02-16T00:00:00")
Tue Feb 16 2016 01:00:00 GMT+0100 (CET)
> new Date("2016-02-16")
Tue Feb 16 2016 01:00:00 GMT+0100 (CET)

… node.js에서 유효하지 않은 시간 (T 구분 기호 없음)은 구현 특정 현지 시간으로 이동하는 것 같습니다.

> new Date("2016-02-16 00:00:00")
Tue Feb 16 2016 00:00:00 GMT+0100 (CET)

ES6 이것을 변경 했으며 , 문서 의 같은 부분 에서 다음과 같이 변경되었습니다.

시간대 오프셋이 없으면 날짜-시간이 현지 시간으로 해석됩니다.

깨는 기쁨이 합니다.

편집하다

TC39 에 따르면 이 사양은 시간대가없는 날짜 및 시간 문자열 (예 : “2016-02-16T00 : 00 : 00”)은 로컬 (ISO 8601에 따라)로 처리되지만 날짜 만 문자열 (예 : “2016-02-16”)을 UTC (ISO 8601과 일치하지 않음)로 지정합니다.


답변

사양 에 따르면 :

이 함수는 먼저 날짜 시간 문자열 형식 (15.9.1.15)에서 호출 된 규칙에 따라 문자열의 형식을 구문 분석하려고합니다. 문자열이 해당 형식을 따르지 않는 경우 함수는 구현 별 휴리스틱 또는 구현 별 날짜 형식으로 대체 될 수 있습니다.

그리고 날짜 시간 문자열 형식은 동의를 2016-02-16유효한 날짜로

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

YYYY
YYYY-MM
YYYY-MM-DD

[…] HH, mm, ss 필드가 없으면 “00”이 값으로 사용되고 sss 필드가없는 값은 “000”입니다. 없는 시간대 오프셋 값은 “Z”입니다.

따라서 2016-02-16번역한다 2016-02-16T00:00:00.000Z.

다른 날짜 2016-02-16 00:00는 형식을 따르지 않으므로 구문 분석은 구현에 따라 다릅니다. 분명히 이러한 날짜는 현지 시간대가있는 것으로 처리되며 예제 날짜는 시간대에 따라 다른 값을 반환합니다.

/* tz = +05:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-15T19:00:00.000Z
/* tz = -08:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-16T08:00:00.000Z

요약:

  • 일치하는 날짜 시간 형식의 경우 동작이 잘 정의되어 있습니다. 시간대 오프셋이없는 경우 날짜 문자열은 UTC (ES5) 또는 로컬 (ES6)로 처리됩니다.
  • 일치하지 않는 날짜 시간 형식의 경우 동작은 구현에 따라 다릅니다. 표준 시간대 오프셋이없는 경우 일반적인 동작은 날짜를 로컬로 처리하는 것입니다.
  • 사실 구현 시 부적합 날짜를 구문 분석 하는NaN 대신 반환하도록 선택할 수 있습니다 . Internet Explorer 11에서 코드를 테스트하십시오.)

답변

ES5, ES6 구현과 예상 결과 사이에 차이가있을 수 있습니다. 당 다음 Date.parse MDN에서 2015년 10월 12일 12시 0분 0초는 “NaN의 UTC 또는 로컬 시간대로 해석 할 수있다” “특히 같은 문자열이 다른 ECMAScript를 구현에서”중요하다.

Firefox 44와 IE 11의 추가 테스트에서는 둘 다에 대한 날짜 개체를 반환하는 것으로 나타났습니다 new Date("2016-02-16 00:00").이 개체는 날짜 구성 요소 값을 가져 오려고 할 때 NaN을 반환하고 toString 값이 “Invalid Date”( “NaN”아님)입니다. 따라서 “일관된 동작을 얻기 위해 00:00″을 추가하면 다른 브라우저에서 쉽게 중단 될 수 있습니다.

다른 답변에서 언급했듯이 new Date("2016-02-16")기본적으로 0의 시간대 오프셋을 사용하여 로컬 대신 자정 UTC를 생성합니다.


답변

DateParser::Parse()Chrome 용 V8 소스 코드 당 .

ES5 ISO 8601 날짜 :

[('-'|'+')yy]yyyy[-MM[-DD]][THH:mm[:ss[.sss]][Z|(+|-)hh:mm]]

부호없는 숫자 뒤에 ‘:’이 오는 것은 시간 값이며 TimeComposer에 추가됩니다.

시간대가 없으면 Z가 기본값입니다.

> new Date("2016-02-16 00:00")
  Tue Feb 16 2016 00:00:00 GMT+0800 (China Standard Time)

두 형식 (예 1970-01-01🙂 과 일치하는 문자열 은 ES5 날짜-시간 문자열로 구문 분석됩니다. 즉, 기본값은 UTC time-zone입니다. ES5 사양을 따르면 불가피합니다.

> new Date("2016-02-16")
Tue Feb 16 2016 08:00:00 GMT+0800 (China Standard Time)


답변

2016-02-16, 자정 UTC를 반환합니다. 이는 잘못되었거나 다른 문자열이 구문 분석하는 것을 고려할 때 내가 예상했던 것과는 다릅니다.

시간대 오프셋을 00:00

new Date("2016-02-16") 출력 Tue Feb 16 2016 05:30:00 GMT+0530 (India Standard Time)

내 시간대는 오프셋 값 (분)이있는 IST +330이므로 330 분을 00:00에 추가했습니다.

ECMA-262, 섹션 20.3.3.2 다음 Date.parse (문자열)

ToString 결과 갑작스러운 완료가 발생하면 완료 레코드가 즉시 반환됩니다. 그렇지 않으면 구문 분석은 결과 문자열을 날짜 및 시간으로 해석합니다. 날짜와 시간에 해당하는 UTC 시간 값인 숫자를 반환합니다. 문자열은 문자열의 내용에 따라 현지 시간, UTC 시간 또는 다른 시간대의 시간으로 해석 될 수 있습니다.

시간 단위 를 명시 적으로 설정 하면 다음 과 new Date("2016-02-16 00:00")같이 설정합니다 .hoursminutes

그렇지 않으면 여기 2 0.3.1.16에 명시된대로

시간대 오프셋이 없으면 날짜-시간이 현지 시간으로 해석됩니다.


답변