DST (일광 절약 시간)가 적용되는지 확인하는 방법과 그렇다면 오프셋?


154

이것은 이것이 필요한 내 JS 코드입니다.

var secDiff = Math.abs(Math.round((utc_date-this.premiere_date)/1000));
this.years = this.calculateUnit(secDiff,(86400*365));
this.days = this.calculateUnit(secDiff-(this.years*(86400*365)),86400);
this.hours = this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)),3600);
this.minutes = this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)),60);
this.seconds = this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)-(this.minutes*60)),1);

"ago"로 날짜 시간을 가져오고 싶지만 DST를 사용중인 경우 날짜가 1 시간 늦습니다. DST가 유효한지 확인하는 방법을 모르겠습니다.

일광 절약 시간 제가 시작되고 끝나는시기를 어떻게 알 수 있습니까?

답변:


313

이 코드는 표준 시간 대 일광 절약 시간 (DST) 동안 더 큰 값 을 getTimezoneOffset반환하는 사실을 사용합니다 . 따라서 표준 시간 동안의 예상 출력을 결정하고 주어진 날짜의 출력이 동일한 지 (표준) 또는 이하 (DST)인지 비교합니다.

참고 getTimezoneOffset반환 긍정적 인 영역에 대한 분의 숫자 서쪽 일반적으로 명시되어 UTC의, 음의 시간 (그들이있는 거 UTC "뒤에"이후). 예를 들어 로스 앤젤레스는 UTC-8h 표준, UTC-7h DST입니다. getTimezoneOffset480아닌 12 월 (겨울, 표준시)에 (양수 480 분)을 반환합니다 -480. 동반구의 경우 음수 를 리턴합니다 (예 -600: 겨울철 시드니에서는 "앞서"( UTC + 10h ) 임에도 불구하고 ).

Date.prototype.stdTimezoneOffset = function () {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}

Date.prototype.isDstObserved = function () {
    return this.getTimezoneOffset() < this.stdTimezoneOffset();
}

var today = new Date();
if (today.isDstObserved()) { 
    alert ("Daylight saving time!");
}

28
이것이 국제적으로 작동하는지 확인할 수 있습니다. 1 월 1 일과 7 월 1 일이 모두 DST 기간에 있거나 둘 다에있는 DST 형식을 사용하는 시간대는 현재 없습니다. 또한 TZDB의 모든 시간대에서 ( 한 가지 예외는 있지만 ) 두 오프셋 중 더 큰 것은 DST 오프셋입니다. 자바 스크립트의 이후 getTimezoneOffset반환 역수 값, 다음 Math.max실제로 반환 표준 오프셋. 코드가 맞습니다.
Matt Johnson-Pint

7
그러나 1 월 1 일과 7 월 1 일이 모두 DST에 있거나 DST에 있지 않고 (그리고 DST에도 적용됨) 시간대가 정의를 변경하면 이 코드는 해당 영역에서 작동하지 않습니다.
Matt Johnson-Pint

9
이것은 일반적으로 작동하지 않습니다. 예를 들어 특정 연도에 DST를 관찰하지 않은 국가가 있고 일부 국가는 라마단 중에 DST를 되돌립니다. 그 다음으로 Date에 대한 ECMAScript 정의가 손상되고 일부 구현에서 TZ 환경 변수 처리가 중단됩니다. 이 모든 것이 결합되어이 방법을 신뢰할 수 없게 만듭니다. Date를 사용하지 않는 라이브러리를 사용하는 것이 좋습니다. 예 : 시간대 완료
rogierschouten

5
이 코드는 남아프리카 공화국이나 아이슬란드와 같이 DST를 준수하지 않는 국가에서는 작동하지 않습니다. 즉, 해당 국가의 다른 시간대와 비교하는 데 사용하면 올바른 시간이 표시되지 않습니다. UTC 사용을 제안하고 시간이 특정 DST 범위 내에 있는지 수동으로 확인하십시오. 그런 다음 DST를 얻기 위해 표준 시간 UTC 오프셋을 +1로 변경하면됩니다.
Kebman

1
어떻게이 문제를 해결할 수 있습니까? 예를 들어 독일은 2016-10-30에 DST에 진입 한 반면 미국은 2016-11-06에 1 주일 후에 진입했습니다. 이 같은 나쁜 정보는 이런 일이 발생하는 원인입니다 : macworld.co.uk/news/apple/…
Daniel F

22

6 월과 1 월의 두 날짜를 만듭니다. getTimezoneOffset () 값을 비교하십시오.

  • 1 월 오프셋> 6 월 오프셋 인 경우 클라이언트는 북반구에 있습니다
  • 1 월 오프셋 <6 월 오프셋 인 경우 클라이언트는 남반구에 있습니다
  • 차이가 없으면 클라이언트 시간대는 DST를 준수하지 않습니다.

이제 현재 날짜의 getTimezoneOffset ()을 확인하십시오.

  • 북반구 인 6 월과 같으면 현재 시간대는 DST (+1 시간)입니다.
  • 남반구 1 월과 같으면 현재 시간대는 DST (+1 시간)입니다.

왜 반구가 필요한가요? 현재 날짜의 getTimezoneOffset ()이 두 getTimezoneOffset () 중 작은 것과 동일하면 DST라고 말하는 것으로 충분하지 않습니까? [와 오프셋은 두 사이의 차이?]
epeleg

허용 대답은 명확하게 :) 보여줍니다 같이 반구가 필요하지 않습니다
존 나이 랜델

작동하지 않습니다. 가장 좋은 방법은 UTC 시간을 사용하고 원하는 지역의 오프셋을 수동으로 설정하는 것입니다. 그런 다음 동일한 지역 (있는 경우)의 DST 시작 및 완료를 수동으로 찾으십시오. 그런 다음 해당 지역의 시간이 DST 범위 내에 있는지 확인한 다음 해당 오프셋을 +1로 업데이트하십시오. 이를 통해 DST를 준수하는 국가와 그렇지 않은 국가를 비교할 수 있습니다.
Kebman

문제는 날짜를 표시하는 방법이 아니라 클라이언트 시스템 Kebman의 시간대에 DST가 현재 유효한지 여부를 결정하는 방법이며 웹 클라이언트가 이미이를 처리합니다.
Jon Nylander

1 월과 7 월 사이 (또는 2 월과 8 월, 3 월과 9 월 등)는 6 개월 간격으로 확인해야합니다.
kpull1

17

이 답변은 허용되는 답변과 매우 유사하지만 Date프로토 타입을 재정의하지는 않으며 하나의 함수 호출 만 사용하여 일광 절약 시간이 2 개가 아닌 유효한지 확인합니다.


아이디어는 7 개월 동안 지속되는 DST를 관찰하는 국가가 없기 때문에 [1] DST를 관찰하는 지역에서는 1 월 UTC 시간으로부터의 오프셋이 7 월의 오프셋과 다를 것입니다.

일광 절약 시간 제가 시계를 앞으로 이동하는 동안 JavaScript는 항상 표준 시간 동안 더 큰 값을 . 따라서 1 월과 7 월 사이의 최소 오프셋을 얻는 것은 DST 중에 시간대 오프셋을 가져옵니다.

그런 다음 날짜 시간대가 해당 최소값과 같은지 확인합니다. 그렇다면 DST에 있습니다. 그렇지 않으면 우리는 그렇지 않습니다.

다음 함수는이 알고리즘을 사용합니다. 이 날짜 객체, 소요 d, 반환을 true일광 절약 시간이 해당 날짜에 유효한 경우와 false그렇지 않은 경우 :

function isDST(d) {
    let jan = new Date(d.getFullYear(), 0, 1).getTimezoneOffset();
    let jul = new Date(d.getFullYear(), 6, 1).getTimezoneOffset();
    return Math.max(jan, jul) != d.getTimezoneOffset(); 
}

1
이것은 작동하지만 현재 TimeZone에 DST가 없으면 true도 발생하므로 올바르지 않습니다. 로 전환 Math.max(...) != d.get...()하면 지정된 시간대에서 DST가 발견되고 날짜가 현재 DST 인 경우 true를 반환합니다. DST를 준수하지 않거나 날짜가 표준 오프셋과 일치하면 false를 반환합니다.
GreySage 2016 년

12

나는 오늘도 같은 문제에 직면했지만 일광 절약은 미국과는 다른 시간에 시작하고 멈춘 이후 (적어도 나의 이해에서) 약간 다른 경로를 사용했습니다.

var arr = [];
for (var i = 0; i < 365; i++) {
 var d = new Date();
 d.setDate(i);
 newoffset = d.getTimezoneOffset();
 arr.push(newoffset);
}
DST = Math.min.apply(null, arr);
nonDST = Math.max.apply(null, arr);

그런 다음 현재 시간대 오프셋을 DST 및 비 DST와 비교하여 어떤 것이 일치하는지 확인하십시오.


이것이 우리가하는 방법입니다. 즉, 대상 시간대에서 DST가 변경되는 연도의 시간을 파악하고 현재 날짜와 가장 최근의 변경 날짜에 대한 오프셋을 계산하십시오. 시간이 다르거 나 같을 것입니다 (해당 시간대가 시간 오프셋 인 경우).
Heather

365 값을 만들 필요가 없습니다. 일광 절약 시간이 적용되지 않는 경우에도 오프셋 변경이 결정되는 즉시 중지되는 이진 검색 방법이 훨씬 더 효율적이어야합니다. 이 모든 접근 방식은 매년 일광 절약 시간을 준수한다고 가정하지만 반드시 그런 것은 아닙니다. 장소는 때때로 일광 절약 시간제를 채택하고 포기합니다 (ECMAScript는 지역에 상관없이 항상 적용되는 현재 규칙을 가정하지만).
RobG

2
롭 - 당신이 이진 검색을 통해 할 수있는 방법은 검색 위치를 모르는 경우 (즉, 당신이 위 또는 아래 찾고있는 곳이 테스트 포인트를 r에입니까?)
epeleg

9

Sheldon Griffin이 제공 한 솔루션에 대한 Matt Johanson의 의견을 바탕으로 다음 코드를 작성했습니다.

    Date.prototype.stdTimezoneOffset = function() {
        var fy=this.getFullYear();
        if (!Date.prototype.stdTimezoneOffset.cache.hasOwnProperty(fy)) {

            var maxOffset = new Date(fy, 0, 1).getTimezoneOffset();
            var monthsTestOrder=[6,7,5,8,4,9,3,10,2,11,1];

            for(var mi=0;mi<12;mi++) {
                var offset=new Date(fy, monthsTestOrder[mi], 1).getTimezoneOffset();
                if (offset!=maxOffset) { 
                    maxOffset=Math.max(maxOffset,offset);
                    break;
                }
            }
            Date.prototype.stdTimezoneOffset.cache[fy]=maxOffset;
        }
        return Date.prototype.stdTimezoneOffset.cache[fy];
    };

    Date.prototype.stdTimezoneOffset.cache={};

    Date.prototype.isDST = function() {
        return this.getTimezoneOffset() < this.stdTimezoneOffset(); 
    };

모든 의견과 이전에 제안 된 답변과 구체적으로 고려하여 모든 세계 최고를 얻으려고합니다.

1) 연간 stdTimezoneOffset에 대한 결과를 캐시하여 같은 연도에 여러 날짜를 테스트 할 때 다시 계산할 필요가 없습니다.

2) DST (존재하는 경우)가 반드시 7 월이라고 가정하지 않으며 어떤 시점에서 어떤 장소가 어떤 달이든 상관없이 작동합니다. 그러나 성능 측면에서 실제로 7 월 (또는 몇 개월)이 실제로 DST이면 더 빠르게 작동합니다.

3) 최악의 경우 매월 첫 번째의 getTimezoneOffset을 비교합니다. [시험 연도 당 1 회].

DST 기간이있는 경우 한 달보다 큰 것으로 가정합니다.

만약 누군가 그 가정을 제거하고 싶다면 Aaron Cole이 제공하는 용질의 것과 비슷한 것으로 루프를 바꿀 수 있습니다.하지만 반년이 더 걸렸고 두 개의 다른 오프셋이 발견되면 루프에서 벗어날 것입니다.]


4

moment.js의 라이브러리가 제공하는 .isDst()그 시간 객체에 대한 방법을.

moment # isDST는 현재 순간이 일광 절약 시간인지 확인합니다.

moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST
moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST

나는 var moment = require ( 'moment')를 시도했다. this.logger.info (moment ([2011, 2, 12]). isDST ()); this.logger.info (moment ([2011, 2, 14]). isDST ()); 둘 다 거짓
Logan_B

DST 변경 날짜 는 같은 국가의 국가 (예 : 애리조나 주)에 따라 국가 마다 다릅니다 . 미국에서는 2011-03-13, 독일에서는 2011-03-31에있었습니다. 따라서 결과는 어떤 시간대 moment.js가 작동하도록 구성되어 있는지에 따라 달라집니다.
Daniel F

1
심지어 애리조나의 상태에서 변화 timeanddate.com/time/us/arizona-no-dst.html
다니엘 F에게

3

getTimezoneOffset()자바 스크립트의 방법은, 브라우저에서, 00:00 시간대 오프셋 (분)을 반환합니다. 예를 들어 일광 절약 시간제 (DST)의 America / New_York 시간대는 숫자 300을 반환합니다. 300 분은 0에서 5 시간의 차이입니다. 300 분을 60 분으로 나눈 값은 5 시간입니다. 모든 시간대는 0 시간대 +00 : 00 / 기타 / GMT / 그리니치 시간과 비교됩니다.

MDN 웹 문서

다음으로 알아야 할 것은 오프셋에 실제 시간대의 반대 부호가 있다는 것입니다.

표준 시간대에 대한 정보는 인터넷 할당 번호 기관 (iana)에서 관리합니다.

iana 시간대

멋진 형식의 시간대 표는 joda.org에서 제공합니다.

joda- 시간대

+00 : 00 또는 기타 / GMT는 그리니치 시간입니다

모든 시간대는 +00 : 00 / "Etc / GMT"/ 그리니치 시간에서 오프셋됩니다.

일광 절약 시간은 항상 여름의 "일반"시간보다 빠릅니다. 가을 시즌에 시계를 다시 설정합니다. (무엇을해야하는지 기억하기위한 "폴백"슬로건)

따라서 일광 절약 시간제 (겨울)의 America / New_York 시간은 정규 시간 1 시간 전입니다. 예를 들어, 여름에 뉴욕시에서 오후 5시 (일반적으로 오후 5시)는 일광 절약 시간으로 오후 4시 (미국 / 뉴욕)입니다. "America / New_York"시간은 "Long Format"시간대 이름입니다. 미국 동부 해안은 일반적으로 시간대를 동부 표준시 (EST)라고합니다.

오늘 시간대 오프셋을 다른 날짜의 시간대 오프셋과 비교하려면 시간대 오프셋의 수학 부호 (+/- "양수 / 음수")가 시간대와 반대라는 것을 알아야합니다.

joda.org의 시간대 표를보고 "America / New_York"의 시간대를 찾으십시오. 표준 오프셋 앞에 음의 부호가 있습니다.

지구는 축의 시계 반대 방향으로 회전합니다. 그리니치에서 일출을 보는 사람은 뉴욕시의 누군가가 일출을 볼 수 있기 5 시간 전에 일출을 봅니다. 미국 서해안의 누군가가 일출을 본 후 미국 동부 해안의 누군가가 일출을 볼 수 있습니다.

이 모든 것을 알아야하는 이유가 있습니다. 따라서 연중 다른 시간대에 모든 시간대를 테스트 할 필요없이 일부 JavaScript 코드가 DST 상태를 올바르게 가져 오는지 여부를 논리적으로 확인할 수 있습니다.

뉴욕시에서 11 월에 시계가 한 시간 뒤로 설정되었다고 상상해보십시오. 뉴욕시의 여름에는 오프셋이 240 분 또는 4 시간입니다.

7 월에 날짜를 만든 다음 오프셋을 가져 와서이를 테스트 할 수 있습니다.

var July_Date = new Date(2017, 6, 1);
var july_Timezone_OffSet = July_Date.getTimezoneOffset();

console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)

브라우저의 개발자 도구 콘솔 로그에 무엇을 인쇄합니까?

답은 : 240

이제 1 월에 날짜를 만들고 겨울철 시간대 오프셋에 대해 브라우저가 반환하는 내용을 확인할 수 있습니다.

var Jan_Date = new Date(2017, 0, 1);//Month is zero indexed - Jan is zero
var jan_Timezone_OffSet = Jan_Date.getTimezoneOffset();

console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet)

답은 : 300

분명히 300은 240보다 큽니다. 이것이 무엇을 의미합니까? 겨울 오프셋이 여름 오프셋보다 큰지 테스트하는 코드를 작성해야합니까? 아니면 여름 오프셋이 겨울 오프셋보다 작습니까? 여름 시간대와 겨울 시간대 오프셋이 다른 경우이 시간대에 DST가 사용되고 있다고 가정 할 수 있습니다. 그러나 오늘날 브라우저 시간대에 DST를 사용하고 있는지 여부 는 알 수 없습니다 . 따라서 오늘의 시간대 오프셋을 가져와야합니다.

var today = new Date();
var todaysTimeZone = today.getTimezoneOffset();

console.log('todaysTimeZone : ' + todaysTimeZone)

답은? -시간에 따라 다름

오늘의 시간대 오프셋 및 오프셋 여름 시간대가 동일 경우 여름과 겨울 시간대 오프셋은 논리적 추론에 의해 다음, 다른, 오늘 DST에 있지해야합니다.

여름 및 겨울 시간대 오프셋 비교 (이 시간대에 DST가 사용되는지 알기 위해)를 생략하고 오늘 시간대 오프셋을 여름 TZ 오프셋과 비교하고 항상 정답을 얻을 수 있습니까?

today's TZ Offset !== Summer TZ Offset

오늘 겨울이나 여름에 있습니까? 알고 있다면 다음 논리를 적용 할 수 있습니다.

if ( it_is_winter && ( todays_TZ_Offset !== summer_TZ_Offset) {
  var are_We_In_DST = true;
}

그러나 문제는 오늘 날짜가 겨울인지 여름인지 알 수 없다는 것입니다. 모든 표준 시간대에는 DST가 시작 및 중지되는시기에 대한 자체 규칙이있을 수 있습니다. 세계의 모든 시간대에 대한 모든 시간대 규칙을 추적해야합니다. 따라서 더 좋고 쉬운 방법이 있다면 더 좋고 쉬운 방법도 있습니다.

우리가 남긴 것은이 표준 시간대가 DST를 사용하는지 알고 오늘의 표준 시간대 오프셋과 서머 표준 시간대 오프셋을 비교해야한다는 것입니다. 그것은 항상 당신에게 신뢰할만한 대답을 줄 것입니다.

최종 논리는 다음과 같습니다.

if ( DST_Is_Used_In_This_Time_Zone && ( todays_TZ_Offset !== summer_TZ_Offset) {
  var are_We_In_DST = true;
}

브라우저의 시간대가 DST를 사용하는지 판별하는 기능 :

function is_DST_Used_In_This_TimeZone() {
  var Jan_Date, jan_Timezone_OffSet, July_Date, july_Timezone_OffSet 
      offsetsNotEqual, thisYear, today;

  today = new Date();//Create a date object that is now
  thisYear = today.getFullYear();//Get the year as a number

  Jan_Date = new Date(thisYear, 0, 1);//Month is zero indexed - Jan is zero
  jan_Timezone_OffSet = Jan_Date.getTimezoneOffset();

  console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet)

  July_Date = new Date(thisYear, 6, 1);
  july_Timezone_OffSet = July_Date.getTimezoneOffset();

  console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)

  offsetsNotEqual = july_Timezone_OffSet !== jan_Timezone_OffSet;//True if not equal

  console.log('offsetsNotEqual: ' + offsetsNotEqual);

  return offsetsNotEqual;//If the offsets are not equal for summer and
       //winter then the only possible reason is that DST is used for
       //this time zone
}

dateandtime.com에 따르면 DST는 2019 년 3 월 10 일에 시작되어 겨울이 아닌 여름에 시작되며 뉴욕의 DST 오프셋은 -5가 아닌 -4입니다.
jk7

답변을 개선하거나 수정해야 할 경우 수정하고 검토하십시오.
Alan Wells

2

Moment.js 사용 ( https://momentjs.com/ )

moment().isDST(); 일광 절약이 관찰되면

또한 상대 시간을 계산하는 도우미 기능이 있습니다. 수동 계산을 수행 할 필요가 없습니다. 예 :moment("20200105", "YYYYMMDD").fromNow();


1

당신은 가까이 있지만 조금 떨어져 있습니다. 자신의 시계의 결과이기 때문에 자신의 시간을 계산할 필요가 없습니다. 현재 위치에서 일광 절약 시간제를 사용하고 있지만 오프셋으로 생성 된 원격 위치에는 일광 절약 시간을 사용하고 있는지 감지 할 수 있습니다.

newDateWithOffset = new Date(utc + (3600000*(offset)));

그들이 DST에 있다면 이것은 여전히 ​​잘못되어 있고 한 시간이 지날 것입니다. 현재 DST 내부에 있거나없는 경우 원격 시간 계정이 필요하며 그에 따라 조정합니다. 이것을 계산하고 시계를 다음과 같이 변경하십시오-2/1/2015를 말하고 DST 외부와 같이 한 시간 뒤로 시계를 재설정하십시오. 그런 다음 여전히 2 시간이 지난 장소에 대한 오프셋을 계산하십시오. 두 시간 창보다 한 시간 앞서 표시됩니다. 여전히 시간을 설명하고 조정해야합니다. 나는 NY와 Denver를 위해 그것을했고 항상 Denver에서 잘못된 (시간 앞서)갑니다.


1

Moment.js 를 사용하는 것을 발견했습니다.여기에 설명 된 몇 가지 개념 (1 월과 6 월 비교)과 함께 라이브러리 습니다.

이 간단한 함수는 사용자의 시간대가 일광 절약 시간을 준수하는지 여부를 반환합니다.

function HasDST() {
    return moment([2017, 1, 1]).isDST() != moment([2017, 6, 1]).isDST();
}

Windows에서이 기능이 작동하는지 확인하는 간단한 방법은 시간대를 DST가 아닌 시간대로 변경하는 것입니다. 예를 들어 Arizona는 false를 반환하고 EST 또는 PST는 true를 반환합니다.

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


1

모든 시간대에서 작동하는 미래 보장 솔루션

  1. 하자 x일광 절약에 인수없이 관심의 년에 밀리 세컨드의 예상 숫자.
  2. 하자 y이후의 밀리 초 수있을 신기원 관심있는 날짜의 연도의 시작부터.
  3. 하자 z이후의 밀리 초 수를 수 신기원 전체 날짜와 관심의 시간
  4. 하자 t모두의 뺄셈 수 xy에서 z: z - y - x. 이것은 DST로 인한 오프셋을 산출합니다.
  5. 경우 t제로, 다음 DST이 적용되지 않습니다. 경우 t0이 아닌, 다음 DST이 적용됩니다.

(function(){"use strict";
function dstOffsetAtDate(dateInput) {
    var fullYear = dateInput.getFullYear()|0;
	// "Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc)
 	//   except if it can be exactly divided by 100, then it isn't (2100,2200,etc)
 	//	  except if it can be exactly divided by 400, then it is (2000, 2400)"
	// (https://www.mathsisfun.com/leap-years.html).
    var isLeapYear = ((fullYear & 3) | (fullYear/100 & 3)) === 0 ? 1 : 0;
	// (fullYear & 3) = (fullYear % 4), but faster
    //Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0
    var fullMonth = dateInput.getMonth()|0;
    return (
        // 1. We know what the time since the Epoch really is
        (+dateInput) // same as the dateInput.getTime() method
        // 2. We know what the time since the Epoch at the start of the year is
        - (+new Date(fullYear, 0, 0)) // day defaults to 1 if not explicitly zeroed
        // 3. Now, subtract what we would expect the time to be if daylight savings
        //      did not exist. This yields the time-offset due to daylight savings.
        - ((
            ((
                // Calculate the day of the year in the Gregorian calendar
                // The code below works based upon the facts of signed right shifts
                //    • (x) >> n: shifts n and fills in the n highest bits with 0s 
                //    • (-x) >> n: shifts n and fills in the n highest bits with 1s
                // (This assumes that x is a positive integer)
                (31 & ((-fullMonth) >> 4)) + // January // (-11)>>4 = -1
                ((28 + isLeapYear) & ((1-fullMonth) >> 4)) + // February
                (31 & ((2-fullMonth) >> 4)) + // March
                (30 & ((3-fullMonth) >> 4)) + // April
                (31 & ((4-fullMonth) >> 4)) + // May
                (30 & ((5-fullMonth) >> 4)) + // June
                (31 & ((6-fullMonth) >> 4)) + // July
                (31 & ((7-fullMonth) >> 4)) + // August
                (30 & ((8-fullMonth) >> 4)) + // September
                (31 & ((9-fullMonth) >> 4)) + // October
                (30 & ((10-fullMonth) >> 4)) + // November
                // There are no months past December: the year rolls into the next.
                // Thus, fullMonth is 0-based, so it will never be 12 in Javascript
                
                (dateInput.getDate()|0) // get day of the month
				
            )&0xffff) * 24 * 60 // 24 hours in a day, 60 minutes in an hour
            + (dateInput.getHours()&0xff) * 60 // 60 minutes in an hour
            + (dateInput.getMinutes()&0xff)
        )|0) * 60 * 1000 // 60 seconds in a minute * 1000 milliseconds in a second
        - (dateInput.getSeconds()&0xff) * 1000 // 1000 milliseconds in a second
        - dateInput.getMilliseconds()
    );
}

// Demonstration:
var date = new Date(2100, 0, 1)
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
    console.log(date.getMonth()+":\t"+dstOffsetAtDate(date)/60/60/1000+"h\t"+date);
date = new Date(1900, 0, 1);
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
    console.log(date.getMonth()+":\t"+dstOffsetAtDate(date)/60/60/1000+"h\t"+date);

// Performance Benchmark:
console.time("Speed of processing 16384 dates");
for (var i=0,month=date.getMonth()|0; i<16384; i=i+1|0)
    date.setMonth(month=month+1+(dstOffsetAtDate(date)|0)|0);
console.timeEnd("Speed of processing 16384 dates");
})();

위의 코드 스 니펫은 여러 가지 이유로 여기에 게시 된 다른 모든 답변보다 우수하다고 생각합니다.

  • 이 답변은 모든 시간대, 심지어 남극 대륙 / 카시 에서도 작동합니다 .
  • 일광 절약 시간은 크게 변경 될 수 있습니다. 20 년이 지난 지금, 일부 국가는 정상 2 대신 3 개의 DST 기간을 가질 수 있습니다.이 코드는 DST의 효과 여부에 관계없이 DST 오프셋을 밀리 초 단위로 반환하여이 경우를 처리합니다.
  • 한 달의 크기와 윤년이 작동하는 방식은 태양과의 시간을 맞추는 데 완벽하게 적합합니다. 도대체 완벽하게 작동하기 때문에 여기 저기 몇 초만 조정하면 됩니다. 현재의 윤년 시스템은 1582 년 2 월 24 일 부터 시행되었으며, 가까운 미래에도 계속 유효 할 것입니다.
  • 이 코드는 DST를 사용하지 않는 시간대에서 작동합니다.
  • 이 코드는 DST가 구현되기 전 (1900 년대와 같은) 역사적인시기에 작동합니다.
  • 이 코드는 최대 정수로 최적화되어 있으며 타이트한 루프에서 호출되는 경우 아무런 문제가 없습니다. 위의 코드 스 니펫을 실행 한 후 출력 하단으로 스크롤하여 성능 벤치 마크를 확인하십시오. 내 컴퓨터는 Chrome에서 ~ 97ms로 16384 개의 날짜를 처리 할 수 ​​있습니다.

그러나 2 개 이상의 DST 기간을 준비하지 않는 경우 아래 코드를 사용하여 DST가 부울로 적용되는지 여부를 확인할 수 있습니다.

function isDaylightSavingsInEffect(dateInput) {
    // To satisfy the original question
    return dstOffsetAtDate(dateInput) !== 0;
}

0

나는 최근에 UTC와 DST로 날짜 문자열을 만들어야했고 Sheldon의 대답에 따라 이것을 함께 정리했습니다.

Date.prototype.getTimezone = function(showDST) {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);

    var utcOffset = new Date().getTimezoneOffset() / 60 * -1;
    var dstOffset = (jan.getTimezoneOffset() - jul.getTimezoneOffset()) / 60;

    var utc = "UTC" + utcOffset.getSign() + (utcOffset * 100).preFixed(1000);
    var dst = "DST" + dstOffset.getSign() + (dstOffset * 100).preFixed(1000);

    if (showDST) {
        return utc + " (" + dst + ")";
    }

    return utc;
}
Number.prototype.preFixed = function (preCeiling) {
    var num = parseInt(this, 10);
    if (preCeiling && num < preCeiling) {
        num = Math.abs(num);
        var numLength		 = num.toString().length;
        var preCeilingLength = preCeiling.toString().length;
        var preOffset		 = preCeilingLength - numLength;
        for (var i = 0; i < preOffset; i++) {
            num = "0" + num;
        }
    }
    return num;
}
Number.prototype.getSign = function () {
    var num	 = parseInt(this, 10);
    var sign = "+";
    if (num < 0) {
        sign = "-";
    }
    return sign;
}

document.body.innerHTML += new Date().getTimezone() + "<br>";
document.body.innerHTML += new Date().getTimezone(true);
<p>Output for Turkey (UTC+0200) and currently in DST: &nbsp; UTC+0300 (DST+0100)</p>
<hr>


0

를 사용하는 데 문제가 있습니까? Date.toString().indexOf('Daylight Time') > -1

"" + new Date()

토 1월 1일 100050 0시 0 분 0 초 GMT-0500 (동부 표준 시간)

"" + new Date(...)

5 월 01 일 100033 00:00:00 GMT-0400 (동부 일광 절약 시간)

이것은 모든 브라우저와 호환되는 것 같습니다.


예, 전 세계에서 작동하지 않습니다. 유럽의 여름에는"Thu Jul 02 2020 14:07:01 GMT+0200 (Central European Summer Time)"
Tadej Krevh

0

ES6 스타일

Math.min(...[0, 6].map(v => new Date(95, v, 1).getTimezoneOffset() * -1));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.