브라우저에서 클라이언트 시간대 가져 오기


139

클라이언트 브라우저에서 시간대를 얻는 신뢰할 수있는 방법이 있습니까? 다음 링크를 보았지만 더 강력한 솔루션을 원합니다.

JavaScript로 시간대 자동 감지

자바 스크립트에서 시간대 감지



8
나는 당신이 위의 링크에 jsTimezoneDetect를 썼고, 상황에 대한 취지는 순수한 크로스 브라우저 자바 스크립트 (지리 위치 및 IP 조회없이)와 얻을 수있는 한 가깝다는 것입니다.
Jon Nylander

답변:


87

이 저장소 페이지를 보면 도움이됩니다

jstz.min.js를 다운로드하고 HTML 페이지에 기능을 추가하십시오

<script language="javascript">
    function getTimezoneName() {
        timezone = jstz.determine()
        return timezone.name();
    }
</script>

표시 태그에서이 함수를 호출하십시오.


13
TL; DR 이제 Intl.DateTimeFormat().resolvedOptions().timeZoneWallace가 제안한대로 IE11을 사용할 수 없습니다.
Code4R7

195

반년 후에 우리는 그것을위한 내장 된 방법을 가지고 있습니다! 최신 브라우저의 경우 다음을 사용합니다.

const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tz);

이것은 IANA 시간대 문자열을 반환하지만 offset 은 반환하지 않습니다 . MDN 참조 에서 자세히 알아보십시오 .

호환성 표 -2019 년 3 월 기준, 전 세계적으로 사용중인 브라우저의 90 %에서 작동합니다. Internet Explorer에서 작동하지 않습니다 .


4
파이어 폭스에서 작동하지 않습니다 : Intl.DateTimeFormat().resolvedOptions().timeZone->undefined
Tomas Tomecek

3
Firefox와 IE는이 속성을 지원하지 않는 것 같습니다 : ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Wallace

5
Intl.DateTimeFormat().resolvedOptions().timeZoneFirefox 52부터 시작하여 예상 값을 반환합니다. kangax.github.io/compat-table/esintl/…
julen

이 양식을 어떻게 사용합니까? 숨겨진 값에 따라 제안 developer.mozilla.org/en-US/docs/Web/HTML/Element/input/... ?
hendry

4
Firefox에서 작동
Dustin Michels

76

사람들이 "시간대"를 찾을 때 종종 "UTC 오프셋"만으로 충분합니다. 예를 들어, 서버는 UTC + 5이고 클라이언트가 UTC-8에서 실행되고 있음을 알고 싶어합니다 .


평범한 오래된 자바 스크립트에서 (new Date()).getTimezoneOffset()/60 는 UTC에서 현재 시간 오프셋을 반환합니다.

(MDN 문서에서)getTimezoneOffset() 반환 값 의 부호에 가능한 "gotcha"에 주목할 가치가 있습니다 .

시간대 오프셋은 UTC와 로컬 시간의 차이 (분)입니다. 이는 현지 시간대가 UTC보다 뒤에 있으면 오프셋이 양수이고, 앞에 있으면 네거티브임을 의미합니다. 예를 들어 UTC + 10 : 00 시간대 (오스트레일리아 동부 표준시, 블라디보스토크 시간, 차모로 표준시)의 경우 -600이 반환됩니다.


그러나 날짜 / 시간 관련 Javascript 코드 에는 day.js 를 사용하는 것이 좋습니다 . 이 경우 다음을 실행하여 ISO 8601 형식의 UTC 오프셋을 얻을 수 있습니다.

> dayjs().format("Z")
"-08:00"

클라이언트가이 정보를 쉽게 위조 할 수 있다고 언급 할 수 있습니다.

(참고 :이 답변은 원래 https://momentjs.com/을 권장 했지만 dayjs는 더 현대적이고 작은 대안입니다.)


30
오프셋과 시간대가 반드시 같은 것은 아니라는 점에 주목할 가치가 있습니다.
Dex

9
오프셋만으로 DST를 어떻게 적용 하시겠습니까? 이 지역에서는 상반기가 잘못되었습니다. IMO 시간대가 더 정확합니다.
Savageman

4
DST는 주어진 시간에 오프셋의 일부입니다. 겨울의 중부 유럽 시간은 UTC + 01 : 00입니다. 그러나 DST가 적용될 때 CET은 UTC + 02 : 00입니다.
Gert Sønderby

1
그렇기 때문에 getTimezoneOffset ()이 작동해야하는 날짜가 필요한 이유는 DST에 추가 될 것입니다.
OsamaBinLogin

2
일광 절약 시간제를 고려할 때 오프셋이 정확하지 않습니다.
Greg L.

48

현재로서는 가장 좋은 방법은 mbayloon의 답변 에서 제안 된 것처럼 jstz 일 것 입니다.

완성도를 높이기 위해 Intl 이라는 표준이 있다고 언급해야합니다 . 이미 Chrome에서 이것을 볼 수 있습니다.

> Intl.DateTimeFormat().resolvedOptions().timeZone
"America/Los_Angeles"

(이것은 실제로 표준을 따르지 않으므로 라이브러리를 고수 해야하는 또 하나의 이유입니다)


1
Intl은 Safari 이외의 모든 환경에서 안정적으로 보입니다. caniuse.com/#feat=internationalization
Michael Cole

2
@MichaelCole 스펙에 준거의 구현은의 Intl반환 해야하는 undefined을 위해 timeZone수동으로 구축에 시간대를 지정하지 않은 경우 재산 DateTimeFormat. Chrome은 대신 시스템 시간대를 반환하여 표준에서 벗어납니다. 그것이 Johannes의 답변이 악용 한 것이기도하지만 "실제로 표준을 따르지 않았다"고 말한 이유입니다.
Chris Jester-Young

20
참고-표준은 이제 Intl.DateTimeFormat (). resolvedOptions (). timeZone
Nederby


4

여기 jsfiddle이 있습니다

현재 사용자 시간대의 약어를 제공합니다.

다음은 코드 샘플입니다

var tz = jstz.determine();
console.log(tz.name());
console.log(moment.tz.zone(tz.name()).abbr(new Date().getTime()));

1
May 22 2015 03:45 PM CDT 내가 사용한 날짜를 표시하려면 console.log(moment(now).format('MMM DD YYYY hh:mm A') + ' ' + moment.tz.zone(tz.name()).abbr(now.getTime()));
αβjiβ

5
바이올린이 더 이상 작동하지 않고 콘솔에 오류가 발생했습니다.
Saumil

2

Josh Fraser가 취한 것과 비슷한 접근 방식을 사용하여 UTC에서 브라우저 시간 오프셋과 DST를 인식하는지 여부를 결정합니다 (그러나 코드에서 다소 단순화 됨).

var ClientTZ = {
    UTCoffset:  0,          // Browser time offset from UTC in minutes
    UTCoffsetT: '+0000S',   // Browser time offset from UTC in '±hhmmD' form
    hasDST:     false,      // Browser time observes DST

    // Determine browser's timezone and DST
    getBrowserTZ: function () {
        var self = ClientTZ;

        // Determine UTC time offset
        var now = new Date();
        var date1 = new Date(now.getFullYear(), 1-1, 1, 0, 0, 0, 0);    // Jan
        var diff1 = -date1.getTimezoneOffset();
        self.UTCoffset = diff1;

        // Determine DST use
        var date2 = new Date(now.getFullYear(), 6-1, 1, 0, 0, 0, 0);    // Jun
        var diff2 = -date2.getTimezoneOffset();
        if (diff1 != diff2) {
            self.hasDST = true;
            if (diff1 - diff2 >= 0)
                self.UTCoffset = diff2;     // East of GMT
        }

        // Convert UTC offset to ±hhmmD form
        diff2 = (diff1 < 0 ? -diff1 : diff1) / 60;
        var hr = Math.floor(diff2);
        var min = diff2 - hr;
        diff2 = hr * 100 + min * 60;
        self.UTCoffsetT = (diff1 < 0 ? '-' : '+') + (hr < 10 ? '0' : '') + diff2.toString() + (self.hasDST ? 'D' : 'S');

        return self.UTCoffset;
    }
};

// Onload
ClientTZ.getBrowserTZ();

로드시 ClientTZ.getBrowserTZ()함수가 실행되어 다음을 설정합니다.

  • ClientTZ.UTCoffset UTC에서 브라우저 시간 오프셋 (분) (예 : CST는 -360 분, UTC에서 -6.0 시간)입니다.
  • ClientTZ.UTCoffsetT접미어가 DST 및 표준 (비 DST) 인 형식 '±hhmmD'(예 :)의 오프셋으로 ;'-0600D'DS
  • ClientTZ.hasDST (참 또는 거짓).

ClientTZ.UTCoffset일부 시간대가 분수 시간당 오프셋 (예, 0415)을 가지고 있기 때문에, 대신에 시간의 분에 제공됩니다.

배후의 의도 ClientTZ.UTCoffsetT는 드롭 다운 <select>목록 과 같이 시간대 테이블 (여기에 제공되지 않음)의 키로 사용하는 것 입니다.


일광 절약 시간이 준수되면 항상 'D'를 반환하는 것 같습니다. 왜 5 개월 만 차이가 나는가? 확실히 1 월과 7 월이 더 안정적으로 작동할까요?
Matt

@Matt-예, 7-16 월 대신 7 월에 사용할 수 있습니다 . 6 월을 포함하지 않는 지역 DST 체계가 있는지 의심하기 때문에 실제로 차이가 있는지 확실하지 않습니다.
David R Tribble

-13

아니요. 신뢰할 수있는 방법은 없으며 결코 없을 것입니다. 당신은 정말 당신이 클라이언트를 신뢰할 수 있다고 생각 했습니까?


23
명확히하기 위해 : 클라이언트의 시계가 올바르게 설정되지 않았거나 악의적으로 사용자가 실제 시간대와 다른 시간대에 있다고 생각하도록 속일 수 있습니다. 고객의 시간대를 사용하려는 경우 중요한 작업을 수행하지 마십시오.
Ryan Kinal

7
-1 오해의 소지가있는 답변을 제공하고 명확하지 않은 경우
Doug S

6
예, 내 응용 프로그램에서 클라이언트를 신뢰할 수 있습니다. 클라이언트가 잘못 구성되었거나 버그가있는 경우 이는 내 사용자에게 있습니다.
Michael Cole

3
나는 실제로 Florian에 동의합니다. 확실한 방법? 거의. 신뢰할 수있는 데이터? 확실히 아닙니다.
Rob

4
이 질문은 데이터가 어떻게 사용될 것인지를 말하지 않습니다. 예를 들어 감지 된 시간대가 서버에 제출 될 것이라고는 말하지 않습니다. 따라서 데이터가 순전히 로컬로 사용되는 경우 신뢰에 대한 언급은 관련이 없습니다.
고인돌
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.