Javascript 날짜 개체가 항상 하루입니까?


238

Java Script 앱에서 날짜는 다음과 같은 형식으로 저장됩니다.

2011-09-24

이제 위의 값을 사용하여 새 Date 객체를 만들려고하면 (다른 형식으로 날짜를 검색 할 수 있음) 날짜는 항상 하루가 지났습니다. 아래를보십시오 :

var doo = new Date("2011-09-24");
console.log(doo);

로그 :

Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)

11
Javascript의 Date 클래스는 날짜를 나타내지 않으며 타임 스탬프 (Java와 동일)를 나타냅니다. 날짜를 지정하려면 시간대를 사용하므로 문제의 원인입니다. 이는 GMT / UTC 시간대 (2,011 구월 24 그것을 파싱 00 : 00 UTC)와 4 시간 SEP (23 2011의 다른 시간대로 출력 20 : 00 GMT-0400).
Codo

2
"잘못된 날짜"가 나타납니다. '-'문자를 '/'문자로 바꾸고 다시 시도하십시오. 또는 날짜를 비트로 나누고 구성 요소를 개별적으로 설정하십시오 (그렇다면 월 번호에서 1을 빼십시오).
RobG

@ 코도-네, 좋은 답변. ECMA-262 15.9.1.15가 적용됩니다. OP는 "2011-09-24T20 : 00 : 00-04 : 00"또는 이와 유사한 것을 사용해야합니다.
RobG

1
"Sep 24 2011"형식이 올바른 날짜를 반환한다는 것을 알았습니다. 설명은 여기를 참조하십시오 : stackoverflow.com/questions/2587345/javascript-date-parse
christurnerio

답변:


98

동부 일광 절약 시간은 동부 표준시 기준이며 -4 hours돌아 오는 날짜의 시간은 20입니다.

20h + 4h = 24h

2011-09-24의 자정입니다. 시간대 표시기가없는 날짜 전용 문자열을 제공했기 때문에 날짜가 UTC (GMT) 로 구문 분석 되었습니다. 대신 표시기없이 날짜 / 시간 문자열을 제공 한 경우 ( new Date("2011-09-24T00:00:00")) 현지 시간대로 구문 분석 된 것입니다. (역사적으로 사양이 두 번 이상 변경 되었기 때문에 불일치가 있었지만 최신 브라우저는 괜찮거나 항상 시간대 표시기를 포함 할 수 있습니다.)

올바른 날짜를 얻었으므로 올바른 시간대를 지정하지 않았습니다.

날짜 값에 액세스 해야하는 경우 getUTCDate()또는 다른 getUTC*()기능을 사용할 수 있습니다 .

var d,
    days;
d = new Date('2011-09-24');
days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
console.log(days[d.getUTCDay()]);

24
"올바른 시간대를 어떻게 지정합니까?" 날짜 생성자는 항상 날짜 문자열을 UTC로 해석하지만 시간대를 조정합니다. `new Date ( '2012-01-02 EDT')조차도 일광 절약 시간제에 대한 오프셋을 적용하여 여전히 전날로 다시 이동할 수 있습니다. EDT의 현재 현지 시간대 인 경우 추가 오프셋을 적용하지 마십시오. 시간대는 EDT라고 말했지만 여전히 하루를 다시 이동 시키는 추가 오프셋을 적용합니다 .
AaronLS

1
@AaronLS EDT일광 절약 시간 (서머 타임이라고도 함) 이며 EST1 월에 적용되는 시간대입니다.
zzzzBov

1
문자열에서 UTC로만 만드는 것이 내가하고 싶은 일이므로 "정확한 시간대를 어떻게 지정합니까?" "정확한 시간대를 지정하지 않았습니다." 내가 new Date('2012-01-01 GMT')여전히 사용자의 현지 날짜 시간으로 변환 할 때 오프셋을 적용합니다.
AaronLS

7
@AaronLS, get*메소드 를 사용해야하고 알 수없는 시간대 오프셋을 포함하여 올바른 날짜 / 시간을 반환 해야하는 경우 알 수없는 시간대 오프셋을 추가하십시오. d = new Date('2013-01-08 GMT'); d.setMinutes(d.getMinutes() + d.getTimezoneOffset());이는 사용자의 로케일로 날짜를 정규화하여 .get*메소드가 기대 값 .getUTC*방법은 정확하지 않을 수 있으므로주의해야합니다.
zzzzBov

1
구현자가 무언가를 올바르게 구현하지 못한 경우 참조를 제공하기 위해 동작을 정의하고이를 이스케이프로 사용하는 것에는 차이가 있습니다. 그리고 그건 하지 데이터가 기대에 일치하지 않는 경우 같은 표현입니다.
Dissident Rage

252

있다 몇몇 미친 JS에 일어날 일 날짜 로 변환 문자열, 예를 들어 사용자가 제공 한 다음 날짜를 고려하는 것이 목적

참고 : 다음 예제 또는하지 않을 수 있습니다 OFF ONE DAY 에 따라 당신의 시간대와 현재 시간.

new Date("2011-09-24"); // Year-Month-Day
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.

그러나 문자열 형식을 Month-Day-Year 로 재 배열하면 ...

new Date("09-24-2011");
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

또 다른 이상한 것

new Date("2011-09-24");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF AS BEFORE.

new Date("2011/09/24"); // change from "-" to "/".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

새로운 날짜를 만들 때 날짜 '2011-09-24' 에서 하이픈을 쉽게 변경할 수 있습니다.

new Date("2011-09-24".replace(/-/g, '\/')); // => "2011/09/24".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

"2011-09-24T00 : 00 : 00" 과 같은 날짜 문자열이 있으면 어떻게됩니까?

new Date("2011-09-24T00:00:00");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.

이전과 같이 하이픈슬래시 로 변경하십시오 . 무슨 일이야?

new Date("2011/09/24T00:00:00");
// => Invalid Date

나는 일반적으로 날짜 형식 2011-09-24T00 : 00 : 00 을 관리해야 하므로 이것이 내가하는 일입니다.

new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, ''));
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

최신 정보

Date 생성자에 별도의 인수를 제공하면 아래 설명과 같이 다른 유용한 출력을 얻을 수 있습니다

참고 : 인수는 숫자 또는 문자열 유형일 수 있습니다. 값이 혼합 된 예를 보여 드리겠습니다.

주어진 해의 첫 달과 일을 얻으십시오

new Date(2011, 0); // Normal behavior as months in this case are zero based.
=> // Sat Jan 01 2011 00:00:00 GMT-0700 (MST)

마지막 달과 일을 가져옵니다

new Date((2011 + 1), 0, 0); // The second zero roles back one day into the previous month's last day.
=> // Sat Dec 31 2011 00:00:00 GMT-0700 (MST)

숫자, 문자열 인수의 예 0부터 시작하는 달이 다시 표시되므로 월은 3 월입니다.

new Date(2011, "02"); 
=> // Tue Mar 01 2011 00:00:00 GMT-0700 (MST)

우리가 똑같은 일을하지만 제로의 날을 가지면 우리는 다른 것을 얻습니다.

new Date(2011, "02", 0); // again the zero roles back from March to the last day of February.
=> // Mon Feb 28 2011 00:00:00 GMT-0700 (MST)

연도 및 월 인수에 0을 추가하면 이전 달의 마지막 날이 표시됩니다. 음수를 계속하면 하루 더 계속 롤백 할 수 있습니다

new Date(2011, "02", -1);
=> // Sun Feb 27 2011 00:00:00 GMT-0700 (MST)

12
이것은 실제로 나에게 가장 도움이되었습니다. 방금 새 날짜를 만들 때 데이터 끝에 .replace (/-/ g, '\ /'). replace (/ T. + /, '')를 추가했습니다. 아주 쉬워요!
Devin Prejean

64
와우-자바 스크립트가 일관되지 않습니다.
psparrow

2
.replace () 호출은 오늘 저녁에 정말 도움이되었습니다.
폐기하십시오

2
예,이 모든 것을 테스트했으며 정말 이상합니다.
chintan adatiya 2016 년

27
이 모든 것은 ISO 8601을 따르려는 기본 Date.parse ()의 동작으로 인한 것입니다. 날짜 문자열이 yyyy-mm-dd 형식을 따르는 경우 암시 적 UTC 00:00의 ISO 8601로 가정합니다. 문자열이 형식을 벗어나면 (예 : 하이픈 대신 mm-dd-yyyy 또는 슬래시) 시간대가없는 경우 현지 시간을 사용하는 RFC 2822에 따라 느슨한 구문 분석기로 되돌아갑니다. 틀림없이, 이것은 보통 사람에게는 모두 매우 희박 할 것입니다.
Mizstik

71

날짜를 정규화하고 원하지 않는 오프셋을 제거하려면 ( https://jsfiddle.net/7xp1xL5m/ ) :

var doo = new Date("2011-09-24");
console.log(  new Date( doo.getTime() + Math.abs(doo.getTimezoneOffset()*60000) )  );
// Output: Sat Sep 24 2011 00:00:00 GMT-0400 (Eastern Daylight Time)

이것은 또한 @tpartee와 동일하고 신용을 얻습니다 ( https://jsfiddle.net/7xp1xL5m/1/ ).

var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 )  );

이것은 나를 위해했습니다-API의 날짜로 작업 한 다음 정렬 / 비교해야했기 때문에 시간대 오프셋을 추가하는 것이 가장 좋습니다.
chakeda

이것은 내가 추가하지 않고 timeZoneOffset을 빼야한다는 것을 제외하고는 나를 위해 일했다
ErikAGriffin

@ErikAGriffin 당신은 GMT-0X00 대신에 GMT + 0X00 IE 시간대에 있습니까?
AaronLS

나는 비슷한 일을했다 :doo.setMinutes(doo.getMinutes() + doo.getTimezoneOffset())
반란 분노

2
@AaronLS 당신은 올바른 길을 가고 있었지만 약간 잘못된 논리였습니다. TZ 오프셋을 보상하기 위해 올바른 논리는 다음과 같습니다. console.log (new Date (doo.getTime ()-doo.getTimezoneOffset () * -60000)); -오프셋의 부호는 중요하며 절대로 빼낼 수 없지만 보정을 위해 역 부호도 필요하므로 역 부호를 적용하려면 오프셋에 -60000을 곱합니다.
tpartee

28

현지 시간대로 일부 날짜의 시간 0을 얻으려면 개별 날짜 부분을 Date생성자에 전달하십시오 .

new Date(2011,08,24); // month value is 0 based, others are 1 based.

26

문자열 끝에 공백을 추가하면 UTC가 생성에 사용된다는 것을 추가하고 싶습니다.

new Date("2016-07-06")
> Tue Jul 05 2016 17:00:00 GMT-0700 (Pacific Daylight Time)

new Date("2016-07-06 ")
> Wed Jul 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time)

편집 : 이것은 권장되는 솔루션이 아니며 대안적인 답변입니다. 무슨 일이 일어나고 있는지 명확하지 않기 때문에이 방법을 사용하지 마십시오. 누군가 실수로 버그를 일으켜 리팩터링하는 방법에는 여러 가지가 있습니다.


끝에 공백이있는 예제의 경우 콘솔은 "잘못된 날짜 = $ 2"를 반환합니다
Brian Risk

1
잘 작동합니다! new Date (data.Date + "") .toLocaleDateString ( "en-US")
Nakres

공평하게, 이것은 대안적인 대안 일 뿐이며 권장되는 해결책이 아닙니다.
Kyle Shrader

25

시간대 조정과 관련이 있다고 생각합니다. 생성 한 날짜는 GMT이고 기본 시간은 자정이지만 시간대는 EDT이므로 4 시간을 뺍니다. 이것을 확인하여보십시오 :

var doo = new Date("2011-09-25 EDT");

3
이것이 가장 좋은 대답입니다. 프로그래밍 방식으로 변환하는 대신 내장 시간대 현지화 문자열을 사용하는 경우 +1 백만
blearn

2
이것은 도움이됩니다. $ scope.dat = new Date (datestring + 'EDT')와 같이 작동합니다. :하지만 EDT와 EST의 차이 참고 링크
웨이 후이시 구오

나는 무대 뒤에서 무슨 일이 일어나고 있는지 모르지만 완벽하게 작동합니다.
the_haystacker

이것이 내가 말한 것 중 가장 단순한 답변이며 코드 재 포맷이 적습니다.
Michael

고마워, 나에게 가장 좋은 방법을 고려하십시오.
Janderson Constantino 2016

11

문제는 구체적으로 시간대와 관련이 있습니다. 참고 부분 GMT-0400-GMT보다 4 시간 늦습니다. 표시된 날짜 / 시간에 4 시간을 추가하면 정확히 2011/09/24 자정이됩니다. toUTCString()GMT 문자열을 얻으려면 대신 메소드를 사용하십시오 .

var doo = new Date("2011-09-24");
console.log(doo.toUTCString());

7

이것은 아마도 좋은 대답은 아니지만이 문제에 대한 경험을 공유하고 싶습니다.

내 응용 프로그램은 전 세계적으로 'YYYY-MM-DD'형식의 utc 날짜를 사용하지만 datepicker 플러그인은 js 날짜 만 허용하지만 utc와 js를 모두 고려하기는 어렵습니다. 따라서 'YYYY-MM-DD'형식의 날짜를 내 날짜 선택기에 전달하려면 먼저 moment.js 또는 원하는 것을 사용하여 'MM / DD / YYYY'형식으로 변환하면 날짜 선택기에 날짜가 표시됩니다. 옳은. 당신의 예를 들어

var d = new Date('2011-09-24'); // d will be 'Fri Sep 23 2011 20:00:00 GMT-0400 (EDT)' for my lacale
var d1 = new Date('09/24/2011'); // d1 will be 'Sat Sep 24 2011 00:00:00 GMT-0400 (EDT)' for my lacale

분명히 d1은 내가 원하는 것입니다. 이것이 일부 사람들에게 도움이되기를 바랍니다.


1
당신이했던 것처럼 형식을 바꾸는 것만으로도 나에게 똑같이 일했습니다. 그래서 이상한.
jAC

5

zzzBov의 답변에 +1 루프가 있습니다. UTC 메소드를 사용하여 나를 위해 일한 날짜의 전체 변환은 다음과 같습니다.

//myMeeting.MeetingDate = '2015-01-30T00:00:00'

var myDate = new Date(myMeeting.MeetingDate);
//convert to JavaScript date format
//returns date of 'Thu Jan 29 2015 19:00:00 GMT-0500 (Eastern Standard Time)' <-- One Day Off!

myDate = new Date(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate());
//returns date of 'Fri Jan 30 2015 00:00:00 GMT-0500 (Eastern Standard Time)' <-- Correct Date!

4

그것은 의미 2011-09-24 00:00:00 GMT, 당신은에있어 이후 GMT -4, 그것은 것입니다 20:00전날.

2011-09-24 02:00:00살고 있기 때문에 개인적으로을받습니다 GMT +2.


3

OP의 경우 시간대는 EDT이지만 스크립트를 실행하는 사용자가 EDT 시간대에 있다고 보장하지는 않으므로 오프셋 하드 코딩이 반드시 작동하지는 않습니다. 내가 찾은 솔루션은 날짜 문자열을 분할하고 Date 생성자에서 별도의 값을 사용합니다.

var dateString = "2011-09-24";
var dateParts = dateString.split("-");
var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);

JS 이상한 점을 고려해야합니다. 월은 0부터 시작합니다.


2

내 고객이 대서양 표준시에 있었던 정확한 문제가 발생했습니다. 클라이언트가 검색 한 날짜 값은 "2018-11-23" 이며 코드 new Date("2018-11-23")가 클라이언트의 출력 으로 전달했을 때 전날이었습니다. 스 니펫에 표시된대로 날짜를 정규화하여 클라이언트에 예상 날짜를 제공하는 유틸리티 함수를 작성했습니다.

date.setMinutes(date.getMinutes() + date.getTimezoneOffset());

var normalizeDate = function(date) {
  date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
  return date;
};

var date = new Date("2018-11-23");

document.getElementById("default").textContent = date;
document.getElementById("normalized").textContent = normalizeDate(date);
<h2>Calling new Date("2018-11-23")</h2>
<div>
  <label><b>Default</b> : </label>
  <span id="default"></span>
</div>
<hr>
<div>
  <label><b>Normalized</b> : </label>
  <span id="normalized"></span>
</div>


2

날짜의 개별 부분을 표시 목적으로 동일하게 유지하려는 경우 *이 시간대를 변경하더라도 작동합니다.

var doo = new Date("2011-09-24 00:00:00")

거기에 0을 추가하십시오.

내 코드에서 나는 이것을한다 :

let dateForDisplayToUser = 
  new Date( `${YYYYMMDDdateStringSeparatedByHyphensFromAPI} 00:00:00` )
  .toLocaleDateString( 
    'en-GB', 
    { day: 'numeric', month: 'short', year: 'numeric' }
  )

그리고 내 컴퓨터에서 시간대를 전환하고 날짜는 API에서 얻은 yyyy-mm-dd 날짜 문자열과 동일하게 유지됩니다.

그러나 나는 뭔가를 놓치고 있습니까 / 이것이 나쁜 생각입니까?

* 최소한 크롬. Safari에서는 작동하지 않습니다! 이 글을 쓰는 시점에서


당신이 할 때 .toISOString(), 그것은 하루 전으로 간다.
vivek_23 '12

new Date('2019/11/18 05:30:00').toISOString();나를 위해 일했다
vivek_23

1

더 많은 변환 방법을 사용하지 않고이를 처리하는 가장 좋은 방법은,

 var mydate='2016,3,3';
 var utcDate = Date.parse(mydate);
 console.log(" You're getting back are 20.  20h + 4h = 24h :: "+utcDate);

이제 날짜에 GMT를 추가하거나 추가 할 수 있습니다.

 var  mydateNew='2016,3,3'+ 'GMT';
 var utcDateNew = Date.parse(mydateNew);
 console.log("the right time that you want:"+utcDateNew)

라이브 : https://jsfiddle.net/gajender/2kop9vrk/1/


1

나는 이와 같은 문제에 직면했다. 그러나 내 문제는 데이터베이스에서 날짜를 가져 오는 동안 시작되었습니다.

이것은 데이터베이스에 쓰이고 UTC 형식입니다.

2019-03-29 19 : 00 : 00.0000000 +00 : 00

그래서 데이터베이스에서 가져 와서 날짜를 확인하면 오프셋이 추가되고 자바 스크립트로 다시 전송됩니다.

여기에 이미지 설명을 입력하십시오

이것이 내 서버 시간대이므로 +05 : 00을 추가하고 있습니다. 내 고객이 다른 시간대 +07 : 00에 있습니다.

2019-03-28T19 : 00 : 00 + 05 : 00 // 이것이 자바 스크립트에서 얻는 것입니다.

그래서 여기에 내가이 문제를 해결하는 방법이 있습니다.

var dates = price.deliveryDate.split(/-|T|:/);
var expDate = new Date(dates[0], dates[1] - 1, dates[2], dates[3], dates[4]);
var expirationDate = new Date(expDate);

따라서 날짜가 서버에서 왔을 때 서버 오프셋이 있으므로 날짜를 분할하고 서버 오프셋을 제거한 다음 날짜로 변환하십시오. 내 문제를 해결합니다.



0

이 페이지 에 따라 UTC 시간대를 사용하여 날짜를 구성 하는 ISO 날짜 문자열 형식을 사용하고 있습니다.

참고 : Date 생성자와 Date.parse와 동등한 날짜 문자열을 구문 분석하는 것은 브라우저 차이와 불일치로 인해 권장하지 않습니다. RFC 2822 형식 문자열에 대한 지원은 규칙에 따릅니다. ISO 8601 형식 지원은 날짜 전용 문자열 (예 : "1970-01-01")이 로컬이 아닌 UTC로 처리된다는 점에서 다릅니다.

과 같이 텍스트를 다르게 포맷하면 "Jan 01 1970"(적어도 내 컴퓨터에서는) 현지 시간대를 사용합니다.


0

이 스레드에 내 2 센트를 추가하려고합니다 (@ paul-wintz 답변을 자세히 설명).

Date 생성자가 ISO 8601 형식의 첫 번째 부분 (날짜 부분)과 일치하는 문자열을 수신하면 UTC 표준 시간대에서 0으로 정확한 날짜 변환을 수행합니다. 해당 날짜가 현지 시간으로 변환 될 때 UTC 자정이 현지 시간대의 이전 날짜 인 경우 날짜 이동이 발생할 수 있습니다.

new Date('2020-05-07')
Wed May 06 2020 20:00:00 GMT-0400 (Eastern Daylight Time)

날짜 문자열이 다른 "looser"형식 인 경우 ( "/"를 사용하거나 날짜 / 월이 0으로 채워지지 않음) 현지 시간대로 날짜를 작성하므로 날짜 이동 문제가 없습니다.

new Date('2020/05/07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-05-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)

따라서 위에서 언급 한 것처럼 빠른 수정 방법 중 하나는 ISO 형식의 Date only 문자열에서 "-"를 "/"로 바꾸는 것입니다.

new Date('2020-05-07'.replace('-','/'))
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)

0

yyyy-mm-ddMySql 날짜 형식으로 저장 하려면 다음을 수행해야합니다.

const newDate = new Date( yourDate.getTime() + Math.abs(yourDate.getTimezoneOffset()*60000) );
console.log(newDate.toJSON().slice(0, 10)); // yyyy-mm-dd

-1

로그는 시간대를 지정하기 위해 GMT를 출력합니다.

var doo = new Date("2011-09-24 EST");

3
이 질문에는 이미 많은 답변이 있습니다. 어쨌든 질문에 대답하고 싶다면 다른 답변이 대답하지 않은 새로운 것을 언급해야합니다. 상단 답변은 이미 시간대 관련 문제를 훨씬 더 자세히 설명합니다.
Calvin Godfrey

이 답변은 거의 정확히 동일하다 stackoverflow.com/a/7556642/8828658
돌은 거미류

그의 설명이 더 깊이 있는지 누가 신경 쓰나요? 그의 코드는 여전히 내 것과 다릅니다. 내 것이 훨씬 간단합니다. 그리고 네, 돌 거미류는 당신이 맞습니다. 내 잘못이야.
bmacx7

-3

신경 쓰지 마라, GMT -0400을 알지 못했다.

기본 "시간"을 12:00:00으로 설정하십시오.


그래, 나는 내 대답에 약간 빠르다. 죄송합니다. 내 대답을 수정했습니다.
ChrisH

-3

다음은 나를 위해 일했습니다.

    var doo = new Date("2011-09-24").format("m/d/yyyy");

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