How to check if DST (Daylight Saving Time) is in effect, and if so, the offset?

This is a bit of my JS code for which this is needed:

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);

I want to get the datetime in “ago”, but if the DST is in use then the dates are off by 1 hour. I don’t know how to check if the DST is in effect or not.

How can I know when the daylight saving starts and ends?

10 thoughts on “How to check if DST (Daylight Saving Time) is in effect, and if so, the offset?”

  1. Create two dates: one in June, one in January. Compare their getTimezoneOffset() values.

    • if January offset > June offset, client is in northern hemisphere
    • if January offset < June offset, client is in southern hemisphere
    • if no difference, client timezone does not observe DST

    Now check getTimezoneOffset() of the current date.

    • if equal to June, northern hemisphere, then current time zone is DST (+1 hour)
    • if equal to January, southern hemisphere, then current time zone is DST (+1 hour)
    Reply
  2. Your’re close but a little off. You never need to calculate your own time as it is a result of your own clock. It can detect if you are using daylight saving time in your location but not for a remote location produced by the offset:

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

    This will still be wrong and off an hour if they are in DST. You need for a remote time account if they are currently inside their DST or not and adjust accordingly. try calculating this and change your clock to – lets say 2/1/2015 and reset the clock back an hour as if outside DST. Then calculate for an offset for a place that should still be 2 hours behind. It will show an hour ahead of the two hour window. You would still need to account for the hour and adjust. I did it for NY and Denver and always go the incorrect (hour ahead) in Denver.

    Reply
  3. I was faced with this same problem today but since our daylight saving starts and stops at differing times from the USA (at least from my understanding), I used a slightly different route..

    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);
    

    Then you simply compare the current timezone offset with DST and nonDST to see which one matches.

    Reply
  4. This answer is quite similar to the accepted answer, but doesn’t override the Date prototype, and only uses one function call to check if Daylight Savings Time is in effect, rather than two.


    The idea is that, since no country observes DST that lasts for 7 months[1], in an area that observes DST the offset from UTC time in January will be different to the one in July.

    While Daylight Savings Time moves clocks forwards, JavaScript always returns a greater value during Standard Time. Therefore, getting the minimum offset between January and July will get the timezone offset during DST.

    We then check if the dates timezone is equal to that minimum value. If it is, then we are in DST; otherwise we are not.

    The following function uses this algorithm. It takes a date object, d, and returns true if daylight savings time is in effect for that date, and false if it is not:

    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(); 
    }
    
    Reply
  5. This code uses the fact that getTimezoneOffset returns a greater value during Standard Time versus Daylight Saving Time (DST). Thus it determines the expected output during Standard Time, and it compares whether the output of the given date the same (Standard) or less (DST).

    Note that getTimezoneOffset returns positive numbers of minutes for zones west of UTC, which are usually stated as negative hours (since they’re “behind” UTC). For example, Los Angeles is UTC–8h Standard, UTC-7h DST. getTimezoneOffset returns 480 (positive 480 minutes) in December (winter, Standard Time), rather than -480. It returns negative numbers for the Eastern Hemisphere (such -600 for Sydney in winter, despite this being “ahead” (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!");
    }
    
    Reply
  6. I recently needed to create a date string with UTC and DST, and based on Sheldon’s answer I put this together:

    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>
    Reply
  7. Is there an issue using the Date.toString().indexOf('Daylight Time') > -1

    "" + new Date()

    Sat Jan 01 100050 00:00:00 GMT-0500 (Eastern Standard Time)

    "" + new Date(...)

    Sun May 01 100033 00:00:00 GMT-0400 (Eastern Daylight Time)

    This seems compatible with all browsers.

    Reply
  8. Based on Matt Johanson’s comment on the solution provided by Sheldon Griffin I created the following code:

        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(); 
        };
    

    It tries to get the best of all worlds taking into account all the comments and previously suggested answers and specifically it:

    1) Caches the result for per year stdTimezoneOffset so that you don’t need to recalculate it when testing multiple dates in the same year.

    2) It does not assume that DST (if it exists at all) is necessarily in July,
    and will work even if it will at some point and some place be any month.
    However Performance-wise it will work faster if indeed July (or near by months) are indeed DST.

    3) Worse case it will compare the getTimezoneOffset of the first of each month. [and do that Once per tested year].

    The assumption it does still makes is that the if there is DST period is larger then a single month.

    If someone wants to remove that assumption he can change loop into something more like whats in the solutin provided by Aaron Cole – but I would still jump half a year ahead and break out of the loop when two different offsets are found]

    Reply
  9. Use Moment.js (https://momentjs.com/)

    moment().isDST(); will give you if Day light savings is observed.

    Also it has helper function to calculate relative time for you. You don’t need to do manual calculations
    e.g moment("20200105", "YYYYMMDD").fromNow();

    Reply

Leave a Comment