시간대 자바 스크립트없이 날짜 구문 분석


147

JavaScript에서 시간대없이 날짜를 구문 분석하고 싶습니다. 나는 시도했다 :

new Date(Date.parse("2005-07-08T00:00:00+0000"));

반환 금요일 7 월 08 2005 02:00:00 GMT + 0200 (중부 유럽 일광 절약 시간)

new Date(Date.parse("2005-07-08 00:00:00 GMT+0000"));

동일한 결과를 반환

new Date(Date.parse("2005-07-08 00:00:00 GMT-0000"));

동일한 결과를 반환

시간을 파싱하고 싶습니다.

  1. 시간대가 없습니다.

  2. 생성자 Date.UTC 또는 new Date (년, 월, 일)를 호출하지 않습니다.

  3. 프로토 타입에 접근하지 않고 문자열을 Date 생성자에 간단하게 전달하십시오.

  4. 제품이 Date아닌 제품을 사용해야 합니다 String.


3
Date.parsebtw를 생략 하고 문자열을 Date생성자 에게 직접 전달할 수 있습니다 .
Bergi

1
왜 이것이 필요한지 잘 모르겠지만 Date에는 항상 사용자의 현지 시간대가 있습니다. JavaScript가 다른 시간대와 함께 작동하도록하려면 Date에 래퍼 객체를 사용해야 할 수도 있습니다. github.com/mde/timezone-js
HMR

1
불행히도, DateMongoDB의 날짜를 비교하기 위해 올바른 객체를 얻기 위해 객체 를 복사해야했습니다 .new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate())
Athlan

시간이없는 날짜를 구문 분석하려면 "2005-07-08"이 다른 시간대의 다른 것을 의미하므로 가정 할 시간대를 지정해야합니다. 2020 년 5 월 현재 MDN 설명서는 구현상의 차이로 인해 buit-in Date 구문 분석 기능에 대해 조언합니다. 그러나 Date.parse ( "2005-07-08")를 사용하면 아마도 00:00 UTC 시간을 반환 할 것입니다. 반면에 date-fns 구문 분석은 동일한 날짜 문자열을 구문 분석 할 때 현지 시간으로 00:00을 반환합니다.
Andy

답변:


106

날짜가 올바르게 구문 분석되었습니다. 현지 시간대로 변환하는 것은 toString입니다.

let s = "2005-07-08T11:22:33+0000";
let d = new Date(Date.parse(s));

// this logs for me 
// "Fri Jul 08 2005 13:22:33 GMT+0200 (Central European Summer Time)" 
// and something else for you

console.log(d.toString()) 

// this logs
// Fri, 08 Jul 2005 11:22:33 GMT
// for everyone

console.log(d.toUTCString())

Javascript Date 객체는 타임 스탬프입니다. 에포크 이후 몇 밀리 초 만 포함되어 있습니다. Date 객체에는 시간대 정보가 없습니다. 이 타임 스탬프가 나타내는 달력 날짜 (일, 분, 초)는 해석의 문제입니다.to...String 방법 ).

위의 예는 날짜가 올바르게 구문 분석되고 있음을 보여줍니다. 즉, 실제로는 GMT의 "2005-07-08T11 : 22 : 33"에 해당하는 양의 밀리 초를 포함합니다.


4
불행히도 String이 아닌 Date 객체를 생성해야합니다.
Athlan

@Athlan : 몇 가지 설명이 추가되었습니다.
georg

1
나는 그것을 확인했다. 구문 분석 된 날짜를 MongoDB query에 전달했으며 new Date(Date.parse("2005-07-08T11:22:33+0000"))생성자를 통해 복사 된 날짜 : new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate()). 두 솔루션, 다른 결과, 두 번째 올바른! 귀하의 회신은 hunlock.com/blogs/Javascript_Dates-The_Complete_Reference에 언급되어 유용 했습니다 . 쪽으로.
Athlan

나를 위해 완벽하게 작동했습니다. .toUTCString ()은 주어진 문자열에서 정확한 시간을 되돌려주는 티켓이었습니다. ie new Date ( "2016-08-22T19 : 45 : 00.0000000"). toUTCString ()
Michael Giovanni Pumo

38
JavaScript 날짜와 시간의 모든 악의 근원은 첫 번째 문장에 포함되어 있습니다. 현지 시간대로 변환하는 것은 toString입니다. 단일 책임은 어디에 있습니까? toString 메소드는 결과를 문자열 화하고 변환해서는 안됩니다. 날짜를 변환하려면 다른 방법을 사용해야합니다.
정박

109

나는 같은 문제가 있습니다. 날짜를 문자열로 가져옵니다 (예 : '2016-08-25T00 : 00 : 00').하지만 정확한 시간의 Date 객체가 필요합니다. String을 객체로 변환하려면 getTimezoneOffset을 사용하십시오.

var date = new Date('2016-08-25T00:00:00')
var userTimezoneOffset = date.getTimezoneOffset() * 60000;
new Date(date.getTime() - userTimezoneOffset);

getTimezoneOffset()에테르 음수 또는 양수 값을 반환합니다. 세계의 모든 위치에서 작동하려면이 값을 빼야합니다.


6
나는 같은 문제가 있으며 이것이 도움이되는 것으로 나타났습니다. 그러나 일광 절약 시간 제로 인해 시간대 오프셋을 처리하지 못한다는 것을 알았습니다. 예 : PST에 있으므로 GMT의 현재 오프셋 (3 월)은 -8 : 00이지만 5 월은 -7 : 00입니다. 내 솔루션은 계산했다var userTimezoneOffset = date.getTimezoneOffset()*60000;
mmh02

3
내가 바보가 아닌 한, 이것은 실제로 잘못된 시간을 돌려줍니다. getTimezoneOffset()생각하는 반대 방향으로 분 수를 반환합니다. 현재 시간대는 UTC-4이지만 getTimezoneOffset()양수 240을 반환합니다. 따라서을 userTimezoneOffset빼지 date.getTime()말고 빼 십시오.
vaindil

1
당신이 빼야하는 @vaindil에 동의합니다. wakwa의 솔루션은 그리니치의 올바른 측면에서만 작동합니다. Wakwas가 수정해야합니다.
Janne Harju

1
아! 너무 빨리 말했다. 대부분의 시간대에서는 작동하지 않습니다. GMT 시간으로 AEST & CEST 시간을 오프셋 할 때 날짜가 잘못 반환되었음을 확인할 수 있습니다.
saran3h

1
@ vaindil 이제 결과는 현지 시간이 시간 0:00으로 표시되도록 new Date('2016-08-25T00:00:00Z')조작하는 new Date('2016-08-25T00:00:00Z')것이 포인트라고 생각 하지만이 코드는 누락되었습니다.Z
barbsan

14

나는 같은 문제에 부딪 쳤고 내가 작업했던 레거시 프로젝트와 그들이이 문제를 어떻게 처리했는지에 대해 이상한 것을 기억했다. 나는 당시에 그것을 이해하지 못했고 문제를 직접 만날 때까지 실제로 신경 쓰지 않았습니다.

var date = '2014-01-02T00:00:00.000Z'
date = date.substring(0,10).split('-')
date = date[1] + '-' + date[2] + '-' + date[0]

new Date(date) #Thu Jan 02 2014 00:00:00 GMT-0600

어떤 이유로 든 '01 -02-2014 '로 날짜를 전달하면 시간대가 0으로 설정되고 사용자의 시간대는 무시됩니다. 이것은 Date 클래스의 우연 일 수 있지만 얼마 전에 존재했으며 오늘 존재합니다. 그리고 브라우저 간 작동하는 것 같습니다. 직접 해보십시오.

이 코드는 시간대가 중요하지만 날짜를보고있는 사람이 소개 된 정확한 순간에 관심이없는 글로벌 프로젝트에서 구현됩니다.


"Z"는 JS가 변환하는 UTC를 지정하기 때문에 의도적이라고 생각하지만 시간대가 없으면 변환 할 수 없으므로 본질적으로 사용자의 시간대를 가정합니다. 그래도 확인이나 더 나은 설명을 얻고 싶습니다.
dlsso

7
이상한 행동은 대시 때문입니다. 크롬, 파이어 폭스, 그리고 IE11은 모든 해석 2014/5/312014/05/31토 2014년 5월 31일 0시 0 분 0 초 GMT-0600 (산악 서머 타임) '(MDT되는 내 현재 시간대) 등. 대시를 사용하면 모든 브라우저 2014-05-31가 금 5 월 30 일 2014 18:00:00 GMT-0600 (Mountain Daylight Time)으로 해석 됩니다. 이상하게도 2014-5-31Chrome은 토요일을 반환하고 Firefox는 금요일을 반환하며 IE11은 날짜가 잘못되었다고 말합니다. date.replace('-','/')트릭을 수행하는 것처럼 보입니다 .
atheaos

6

Date객체 자체가 어쨌든 시간대가 포함되며, 반환 된 결과는 기본 방법으로 문자열로 변환하는 효과입니다. 즉, 시간대가 없으면 날짜 객체 만들 수 없습니다 . 그러나 당신이 할 수있는 일은 Date자신의 것을 만들어서 객체 의 행동을 모방하는 것입니다. 그러나 이것은 moment.js 와 같은 라이브러리로 넘겨주는 것이 좋습니다 .


2
불행히도 String이 아닌 Date 객체를 생성해야합니다.
Athlan

3

간단한 해결책

const handler1 = {
  construct(target, args) {
    let newDate = new target(...args);
    var tzDifference = newDate.getTimezoneOffset();
    return new target(newDate.getTime() + tzDifference * 60 * 1000);
  }
};

Date = new Proxy(Date, handler1);

3

자바 스크립트의 날짜는 내부를 단순하게 유지합니다. 날짜-시간 데이터는 UTC 유닉스 시대 (밀리 초 또는 ms)로 저장됩니다.

지구상의 어떤 시간대에서도 변경되지 않는 "고정 된"시간을 원한다면 UTC로 시간을 조정하여 현재 현지 시간대와 일치 시키십시오. 그리고 검색 할 때 현지 시간대에 상관없이 수정 한 UTC 시간을 저장 한 시간과 현지 시간대 오프셋을 추가하여 "고정 된"시간을 얻습니다.

날짜를 저장하려면 (ms)

toUTC(datetime) {
  const myDate = (typeof datetime === 'number')
    ? new Date(datetime)
    : datetime;

  if (!myDate || (typeof myDate.getTime !== 'function')) {
    return 0;
  }

  const getUTC = myDate.getTime();
  const offset = myDate.getTimezoneOffset() * 60000; // It's in minutes so convert to ms
  return getUTC - offset; // UTC - OFFSET
}

검색 / 표시 날짜 (ms)

fromUTC(datetime) {
  const myDate = (typeof datetime === 'number')
    ? new Date(datetime)
    : datetime;

  if (!myDate || (typeof myDate.getTime !== 'function')) {
    return 0;
  }

  const getUTC = myDate.getTime();
  const offset = myDate.getTimezoneOffset() * 60000; // It's in minutes so convert to ms
  return getUTC + offset; // UTC + OFFSET
}

그럼 당신은 할 수 있습니다 :

const saveTime = new Date(toUTC(Date.parse("2005-07-08T00:00:00+0000")));
// SEND TO DB....

// FROM DB...
const showTime = new Date(fromUTC(saveTime));

2

이 코드를 사용할 수 있습니다

var stringDate = "2005-07-08T00:00:00+0000";
var dTimezone = new Date();
var offset = dTimezone.getTimezoneOffset() / 60;
var date = new Date(Date.parse(stringDate));
date.setHours(date.getHours() + offset);

1
나는 이것이 일광 절약 시간제를 고려한다고 믿지 않는다
Daniel Thompson

2

날짜를 표시 할 때 실제로 서식 문제가되므로 (예 : 현지 시간으로 표시) new (ish) Intl.DateTimeFormat 객체를 사용하여 서식을보다 명확하고 더 많은 출력 옵션을 제공하여 서식을 수행하는 것이 좋습니다 .

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };

const dateFormatter = new Intl.DateTimeFormat('en-US', dateOptions);
const dateAsFormattedString = dateFormatter.format(new Date('2019-06-01T00:00:00.000+00:00'));

console.log(dateAsFormattedString) // "June 1, 2019"

표시된대로 timeZone을 'UTC'로 설정하면 로컬 변환이 수행되지 않습니다. 보너스로 더 세련된 출력을 만들 수도 있습니다. Mozilla 에서 Intl.DateTimeFormat 객체 에 대한 자세한 내용을 읽을 수 있습니다 -Intl.DateTimeFormat .

편집하다:

Intl.DateTimeFormat객체 를 만들지 않고도 동일한 기능을 수행 할 수 있습니다 . 로케일 및 날짜 옵션을 toLocaleDateString()함수에 직접 전달하면됩니다 .

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };
const myDate = new Date('2019-06-01T00:00:00.000+00:00');
today.toLocaleDateString('en-US', dateOptions); // "June 1, 2019"

1

일반적인 메모입니다. 유연성을 유지하는 방법.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

getMinutes ()를 사용할 수 있지만 처음 9 분 동안 하나의 숫자 만 반환합니다.

let epoch = new Date() // Or any unix timestamp

let za = new Date(epoch),
    zaR = za.getUTCFullYear(),
    zaMth = za.getUTCMonth(),
    zaDs = za.getUTCDate(),
    zaTm = za.toTimeString().substr(0,5);

console.log(zaR +"-" + zaMth + "-" + zaDs, zaTm)

Date.prototype.getDate()
    Returns the day of the month (1-31) for the specified date according to local time.
Date.prototype.getDay()
    Returns the day of the week (0-6) for the specified date according to local time.
Date.prototype.getFullYear()
    Returns the year (4 digits for 4-digit years) of the specified date according to local time.
Date.prototype.getHours()
    Returns the hour (0-23) in the specified date according to local time.
Date.prototype.getMilliseconds()
    Returns the milliseconds (0-999) in the specified date according to local time.
Date.prototype.getMinutes()
    Returns the minutes (0-59) in the specified date according to local time.
Date.prototype.getMonth()
    Returns the month (0-11) in the specified date according to local time.
Date.prototype.getSeconds()
    Returns the seconds (0-59) in the specified date according to local time.
Date.prototype.getTime()
    Returns the numeric value of the specified date as the number of milliseconds since January 1, 1970, 00:00:00 UTC (negative for prior times).
Date.prototype.getTimezoneOffset()
    Returns the time-zone offset in minutes for the current locale.
Date.prototype.getUTCDate()
    Returns the day (date) of the month (1-31) in the specified date according to universal time.
Date.prototype.getUTCDay()
    Returns the day of the week (0-6) in the specified date according to universal time.
Date.prototype.getUTCFullYear()
    Returns the year (4 digits for 4-digit years) in the specified date according to universal time.
Date.prototype.getUTCHours()
    Returns the hours (0-23) in the specified date according to universal time.
Date.prototype.getUTCMilliseconds()
    Returns the milliseconds (0-999) in the specified date according to universal time.
Date.prototype.getUTCMinutes()
    Returns the minutes (0-59) in the specified date according to universal time.
Date.prototype.getUTCMonth()
    Returns the month (0-11) in the specified date according to universal time.
Date.prototype.getUTCSeconds()
    Returns the seconds (0-59) in the specified date according to universal time.
Date.prototype.getYear()
    Returns the year (usually 2-3 digits) in the specified date according to local time. Use getFullYear() instead. 

-1

(new Date().toString()).replace(/ \w+-\d+ \(.*\)$/,"")

출력됩니다 : 화요일 Jul 10 2018 19:07:11

(new Date("2005-07-08T11:22:33+0000").toString()).replace(/ \w+-\d+ \(.*\)$/,"")

출력 : Fri Jul 08 2005 04:22:33

참고 : 반환 된 시간은 현지 시간대에 따라 다릅니다.


-1

이것이 나를 위해 일하는이 문제에 대해 생각해 낸 해결책입니다.


사용 된 라이브러리 : 일반 자바 스크립트 Date 클래스가있는 momentjs.

1 단계. String 날짜를 moment 객체로 변환합니다 (PS : moment는 toDate()메소드가 호출되지 않는 한 원래 날짜와 시간을 유지함 ).

const dateMoment = moment("2005-07-08T11:22:33+0000");

2. 추출 단계 hoursminutes이전에 만든 순간 개체에서 값을 :

  const hours = dateMoment.hours();
  const mins = dateMoment.minutes();

3 단계. 순간을 날짜로 변환 (PS : 브라우저 / 컴퓨터의 시간대에 따라 원래 날짜가 변경되지만 4 단계를 걱정하지 않아도됩니다.) :

  const dateObj = dateMoment.toDate();

4 단계. 2 단계에서 추출한 시간과 분을 수동으로 설정하십시오.

  dateObj.setHours(hours);
  dateObj.setMinutes(mins);

5 단계. dateObj 는 이제 시간대 차이없이 원래 날짜를 표시합니다. 원래 시간과 분을 수동으로 설정하므로 일광 절약 시간 변경조차도 날짜 개체에 영향을 미치지 않습니다.

도움이 되었기를 바랍니다.


-7

불행히도 기본적으로 제대로 해결되지 않은 날짜 구문 분석에는 몇 가지 고유 문제가 있습니다.

-인간이 읽을 수있는 날짜에는 암시 적 시간대가 있습니다
.-웹에는 모호한 많은 날짜 형식이 있습니다.

이러한 문제를 쉽고 깨끗하게 해결하려면 다음과 같은 기능이 필요합니다.

>parse(whateverDateTimeString,expectedDatePattern,timezone)
"unix time in milliseconds"

나는 이것을 찾았지만 그런 것을 발견하지 못했습니다!

그래서 나는 만들었습니다 : https://github.com/zsoltszabo/timestamp-grabber를

즐겨!

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