programing tip

"2016-02-16"이 "2016-02-16 00:00"과 같지 않은 이유는 무엇입니까?

itbloger 2020. 8. 24. 07:53
반응형

"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에서 코드를 테스트하십시오.)

You are perhaps running into a differences between ES5, ES6 implementations and your expected result. Per Date.parse at MDN, "especially across different ECMAScript implementations where strings like "2015-10-12 12:00:00" may be parsed to as NaN, UTC or local timezone" is significant.

Additional testing in Firefox 44 and IE 11 revealed they both return a date object for new Date("2016-02-16 00:00"), which object returns NaN when atttempting to get a date component value, and whose toString value is "Invalid Date" (not "NaN"). Hence appending " 00:00 to get consistent behavior" can easily break in different browsers.

As noted in other answers new Date("2016-02-16") uses a timezone offset of zero by default, producing midnight UTC instead of local.


Per DateParser::Parse() of V8 source codes for Chrome.

ES5 ISO 8601 dates:

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

An unsigned number followed by ':' is a time value, and is added to the TimeComposer.

timezone defaults to Z if missing

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

A string that matches both formats (e.g. 1970-01-01) will be parsed as an ES5 date-time string - which means it will default to UTC time-zone. That's unavoidable if following the ES5 specification.

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

returns 2016-02-16, midnight UTC, which is wrong, or at least not what I expected given what the other string parses as.

It adds the timezone offset to the 00:00

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

My timezone being IST with an offset value (in minutes) +330, so it added 330 minutes to 00:00.

As per ecma-262, section 20.3.3.2 Date.parse ( string )

If ToString results in an abrupt completion the Completion Record is immediately returned. Otherwise, parse interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time. The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String.

When you explicitly set the time-units new Date("2016-02-16 00:00") it wll use set that as hours and minutes,

Otherwise as stated here in 20.3.1.16

If the time zone offset is absent, the date-time is interpreted as a local time.

참고URL : https://stackoverflow.com/questions/35448343/why-isnt-2016-02-16-equal-to-2016-02-16-0000

반응형