In a previous question I wrote about a javascript date function that was mysteriously stopping on 11/07/101. Thanks to the stackoverflow users I was told my problem is Dayl
I was in a situation where I needed the date in the local time zone, i was doing a lot of adding and subtracting days via time stamps, some time later DST gave me issues, I made a function to add days to a time stamp and check if the time zone changed cause of DST
Heres is my scratchpad test:
function timeToHuman(stamp) {
var monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"],
date = new Date(stamp*1000),
month = monthNames[date.getMonth()],
day = date.getDate(),
year = date.getFullYear(),
hour = date.getHours(),
min = date.getMinutes(),
amp;
if(hour>11){
hour -= 12;
amp = "PM";
}
else
amp="AM";
hour = hour==0?12:hour;
min = min<10?"0"+min:min;
return month + " " + day + ", " + year + " @ " + hour + ":" + min + " " + amp +// Month/Day /Year
" || "+year+"/"+(date.getMonth()+1)+"/"+day+ " @ " + date.getHours() + ":" + min;// Year/Month/Day
}
function addDays(stamp,days){//stamp = new Date().getTime()/1000
var sec=days*86400,
B4=new Date(stamp*1000).getTimezoneOffset(),
A=new Date((stamp+sec)*1000).getTimezoneOffset();
if(B4!=A){// DST correction
A=(A-B4)*60;
console.log('DST adjust by:',A,'seconds');
sec+=A;
}
return stamp+sec;
}
var sample=[
Math.floor(new Date('Sun Mar 10 2018 11:38:59 GMT-0500 (EDT)').getTime()/1000),// day before DST change
Math.floor(new Date('Sun Mar 11 2018 11:38:59 GMT-0400 (EDT)').getTime()/1000),// day after DST change
Math.floor(new Date('Sun Nov 3 2018 11:38:59 GMT-0400 (EDT)').getTime()/1000),// day before DST change
Math.floor(new Date('Sun Nov 4 2018 11:38:59 GMT-0500 (EDT)').getTime()/1000)// day after DST change
]
date=[];
for(i in sample){
i=parseInt(i,10);
date.push('Without DST Detection, Part '+(i+1));
date.push('\t'+timeToHuman(sample[i]+2*86400));
date.push('\t'+timeToHuman(sample[i]+1*86400));
date.push('\t'+timeToHuman(sample[i]));
date.push('\t'+timeToHuman(sample[i]+-1*86400));
date.push('\t'+timeToHuman(sample[i]+-2*86400));
date.push('\t'+timeToHuman(sample[i]+-3*86400));
date.push('With DST Detection, Part '+(i+1));
date.push('\t'+timeToHuman(addDays(sample[i],2)));
date.push('\t'+timeToHuman(addDays(sample[i],1)));
date.push('\t'+timeToHuman(sample[i]));
date.push('\t'+timeToHuman(addDays(sample[i],-1)));
date.push('\t'+timeToHuman(addDays(sample[i],-2)));
date.push('\t'+timeToHuman(addDays(sample[i],-3)));
}
date.join('\n');
/*
Without DST Detection, Part 1
March 12, 2018 @ 12:38 PM || 2018/3/12 @ 12:38
March 11, 2018 @ 12:38 PM || 2018/3/11 @ 12:38
March 10, 2018 @ 11:38 AM || 2018/3/10 @ 11:38
March 9, 2018 @ 11:38 AM || 2018/3/9 @ 11:38
March 8, 2018 @ 11:38 AM || 2018/3/8 @ 11:38
March 7, 2018 @ 11:38 AM || 2018/3/7 @ 11:38
With DST Detection, Part 1
March 12, 2018 @ 11:38 AM || 2018/3/12 @ 11:38
March 11, 2018 @ 11:38 AM || 2018/3/11 @ 11:38
March 10, 2018 @ 11:38 AM || 2018/3/10 @ 11:38
March 9, 2018 @ 11:38 AM || 2018/3/9 @ 11:38
March 8, 2018 @ 11:38 AM || 2018/3/8 @ 11:38
March 7, 2018 @ 11:38 AM || 2018/3/7 @ 11:38
Without DST Detection, Part 2
March 13, 2018 @ 11:38 AM || 2018/3/13 @ 11:38
March 12, 2018 @ 11:38 AM || 2018/3/12 @ 11:38
March 11, 2018 @ 11:38 AM || 2018/3/11 @ 11:38
March 10, 2018 @ 10:38 AM || 2018/3/10 @ 10:38
March 9, 2018 @ 10:38 AM || 2018/3/9 @ 10:38
March 8, 2018 @ 10:38 AM || 2018/3/8 @ 10:38
With DST Detection, Part 2
March 13, 2018 @ 11:38 AM || 2018/3/13 @ 11:38
March 12, 2018 @ 11:38 AM || 2018/3/12 @ 11:38
March 11, 2018 @ 11:38 AM || 2018/3/11 @ 11:38
March 10, 2018 @ 11:38 AM || 2018/3/10 @ 11:38
March 9, 2018 @ 11:38 AM || 2018/3/9 @ 11:38
March 8, 2018 @ 11:38 AM || 2018/3/8 @ 11:38
Without DST Detection, Part 3
November 5, 2018 @ 10:38 AM || 2018/11/5 @ 10:38
November 4, 2018 @ 10:38 AM || 2018/11/4 @ 10:38
November 3, 2018 @ 11:38 AM || 2018/11/3 @ 11:38
November 2, 2018 @ 11:38 AM || 2018/11/2 @ 11:38
November 1, 2018 @ 11:38 AM || 2018/11/1 @ 11:38
October 31, 2018 @ 11:38 AM || 2018/10/31 @ 11:38
With DST Detection, Part 3
November 5, 2018 @ 11:38 AM || 2018/11/5 @ 11:38
November 4, 2018 @ 11:38 AM || 2018/11/4 @ 11:38
November 3, 2018 @ 11:38 AM || 2018/11/3 @ 11:38
November 2, 2018 @ 11:38 AM || 2018/11/2 @ 11:38
November 1, 2018 @ 11:38 AM || 2018/11/1 @ 11:38
October 31, 2018 @ 11:38 AM || 2018/10/31 @ 11:38
Without DST Detection, Part 4
November 6, 2018 @ 11:38 AM || 2018/11/6 @ 11:38
November 5, 2018 @ 11:38 AM || 2018/11/5 @ 11:38
November 4, 2018 @ 11:38 AM || 2018/11/4 @ 11:38
November 3, 2018 @ 12:38 PM || 2018/11/3 @ 12:38
November 2, 2018 @ 12:38 PM || 2018/11/2 @ 12:38
November 1, 2018 @ 12:38 PM || 2018/11/1 @ 12:38
With DST Detection, Part 4
November 6, 2018 @ 11:38 AM || 2018/11/6 @ 11:38
November 5, 2018 @ 11:38 AM || 2018/11/5 @ 11:38
November 4, 2018 @ 11:38 AM || 2018/11/4 @ 11:38
November 3, 2018 @ 11:38 AM || 2018/11/3 @ 11:38
November 2, 2018 @ 11:38 AM || 2018/11/2 @ 11:38
November 1, 2018 @ 11:38 AM || 2018/11/1 @ 11:38
*/
Use Date.setHours(hour,min,sec,millisec)
to set the hour default to noon:
Date.setHours(11);
(view reference)
24 hours after noon on a day is guaranteed to be the next day, though on daylight savings time days it will be one hour off (which doesn't change the result in your script at all).
The best way is not to deal with DST. Use the UTC methods and you won't have to worry about crossing a DST boundary, or any other timezone discontinuity (locale timezone rules can change for more reasons than just DST).
var timestamp= Date.UTC(2010, 10-1, 31, 0, 0, 0); // zero-based month: 9->october
var nextday= new Date(timestamp+86400000); // add one day
var ymd= [
nextday.getUTCFullYear(),
nextday.getUTCMonth()+1, // zero-based month
nextday.getUTCDate()
].join('-');
alert(ymd); // 2010-11-1
If the above had been done with new Date(2010, ...)
and getDate()
etc, it'd return 2010-10-31
, the day add failing due to the DST change (in my region, anyway).
It is a pity that the ‘default’ most-obvious methods in Date
are about local time, especially since JavaScript provides so very little context to scripts on what ‘local time’ actually is. UTC is a more stable proposition.