所以我知道之前已经讨论过这个问题,但我真的想要一些有用的输入。我正在写一个日历,需要添加日期,我遇到了一个早期的帖子(Add days to JavaScript Date),但它提出了更多的排队而不是答案。所以我去了自己的代码,我很亲密。这就是我所拥有的:
Date.prototype.add = function(period, value, ignoreDaylightSaving)
{
var Day = this.getDate();
var Month = this.getMonth();
var Year = this.getFullYear();
var Hours = this.getHours();
var Mins = this.getMinutes();
var Secs = this.getSeconds();
var MilliSecs = this.getMilliseconds();
var TestDate;
var IgnoreDS = false;
var TZOffset1 = 0;
var TZOffset2 = 0;
if (typeof(ignoreDaylightSaving) == "boolen")
{
IgnoreDS = ignoreDaylightSaving;
}
switch (period.toUpperCase())
{
case "D":
Day += value;
break;
case "M":
Month += value;
break;
case "Y":
Year += value;
break;
case "H":
Hours += value;
break;
case "N":
Mins += value;
break;
case "S":
Secs += value;
break;
case "MS":
MilliSecs += value;
}
// Standardise Daylight Saving cut off.
if (IgnoreDS == false)
{
TestDate = new Date(Year, Month, Day, Hours, Mins, Secs, MilliSecs);
TZOffset1 = this.getTimezoneOffset();
TZOffset2 = TestDate.getTimezoneOffset();
if (value > 0)
{
if (this > TestDate)
{
if (TZOffset1 == TZOffset2)
{
Hours += 1;
}
}
} else {
if (this < TestDate)
{
if (TZOffset1 == TZOffset2)
{
Hours -= 1;
}
}
}
}
return(new Date(Year, Month, Day, Hours, Mins, Secs, MilliSecs));
}
它依赖于Javascript来为我做计算。在内部,日期和时间只是数字,所以如果你传递一组值,无论它们是否在范围内,javascript只是将它们全部乘以得到内部数字。只有当您将日期函数应用于该数字时,它才会转换为我们识别的日期。
所以我的逻辑:
* split down the Date into its components
* add the value you want to one of the components
* create a new date from the components.
我已经用IE和Chrome的闰年进行了测试。
夏令时是另一回事。在英国,英国夏令时开始于2014年3月30日凌晨1点30分。如果我设定日期为2014年3月30日00:59:00并添加2分钟,Chrome会给我'2014年3月30日00:01:00'(格林威治标准时间标准时间) ,但IE给了我'2014年3月30日02:01:00'(GMT夏令时)。
两个浏览器都有效地说“你不能在2014年3月30日上午01:01因为它不存在”。 IE进入下一次(实际上是调整时钟),而Chrome只会让你退回一小时,让你保持GMT标准时间。当夏令时结束时,他们以相反的方式做到这一点 - IE让你在夏令时,Chrome会为你调整时钟。我编写了这个代码,用于从GMT Standard到GMT Summertime(请参阅标准化夏令时中的区块)。
很难对GMT Summertime转为GMT标准的不一致进行编码。我甚至写了一些javascript,通过每个月,然后是一天一小时来查找日期的变化。但IE给Chrome提供了不同的时间。代码:
Date.prototype.getDaylightSavingDate = function(year)
{
var DSStart = new Date();
var DSEnd = new Date();
var MonthLoop;
var d1 = new Date();
var d2 = new Date();
var ThreshholdTZOffsets = new Array();
var ThreshholdMonths = new Array();
var ThreshholdDays = new Array();
var ThreshholdHours = new Array();
var ThisTZOffset;
var PrevTZOffset;
var THCount;
THCount = 0;
for (DateLoop=0; DateLoop < 12; DateLoop++)
{
d1 = new Date(year, DateLoop, 1);
ThisTZOffset = d1.getTimezoneOffset();
d2 = new Date(year, DateLoop-1, 1)
PrevTZOffset = d2.getTimezoneOffset();
if (PrevTZOffset != ThisTZOffset)
{
ThreshholdMonths[THCount] = DateLoop-1;
ThreshholdTZOffsets[THCount] = ThisTZOffset;
THCount += 1;
}
PrevTZOffset = ThisTZOffset
}
for (DateLoop=0; DateLoop<ThreshholdMonths.length; DateLoop++)
{
for (DayLoop=1; DayLoop < 32; DayLoop++)
{
d1 = new Date(year, ThreshholdMonths[DateLoop], DayLoop);
ThisTZOffset = d1.getTimezoneOffset();
d2 = new Date(year, ThreshholdMonths[DateLoop], DayLoop-1);
PrevTZOffset = d2.getTimezoneOffset();
if (PrevTZOffset != ThisTZOffset)
{
ThreshholdDays[DateLoop] = DayLoop-1;
}
PrevTZOffset = ThisTZOffset
}
}
for (DateLoop=0; DateLoop<ThreshholdMonths.length; DateLoop++)
{
for (HourLoop=0; HourLoop < 23; HourLoop++)
{
d1 = new Date(year, ThreshholdMonths[DateLoop], ThreshholdDays[DateLoop], HourLoop, 0, 0);
ThisTZOffset = d1.getTimezoneOffset();
d2 = new Date(year, ThreshholdMonths[DateLoop], ThreshholdDays[DateLoop], HourLoop-1, 0, 0);
PrevTZOffset = d2.getTimezoneOffset();
if (PrevTZOffset != ThisTZOffset)
{
ThreshholdHours[DateLoop] = HourLoop;
}
PrevTZOffset = ThisTZOffset
}
}
if (ThreshholdHours.length == 2)
{
DSStart = new Date(year, ThreshholdMonths[0], ThreshholdDays[0], ThreshholdHours[0],0,0,0);
DSEnd = new Date(year, ThreshholdMonths[1], ThreshholdDays[1], ThreshholdHours[1],0,0,0);
return({start:DSStart,end:DSEnd})
}
}
如果在 IE 中调用此例程并调试它ThreshholdDays [0] = 1,并且ThreshholdDays [1] = 2。在 Chrome 中,反之亦然:ThreshholdDays [0] = 2,ThreshholdDays [1] = 1。
我的HTML用于调用例程:
<!DOCTYPE HTML>
<html dir="ltr" lang="en-gb" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Dates</title>
<script language="javascript" type="text/javascript" src="LIBS/general.js"></script>
</head>
<body>
<div>
<script language="javascript" type="text/javascript">
var d1 = new Date(2014, 9, 26, 2,1,0);
var d2 = d1.add("n", -2, true);
var ds1 = d1.getDaylightSavingDate(2014);
alert(ds1.start + ", " + ds1.end);
alert(d1 + ", " + d2 + ", " + (d2-d1));
</script>
</div>
</body>
</html>
有人在没有明确编写每个浏览器的情况下想到另一种方法吗?
答案 0 :(得分:0)
如果将6月份日期的本地时区偏移量与1月份的日期进行比较,则可以判断DST是否适用。
在赤道以南,使用夏令时,1月总是在夏令时,赤道以北,6月总是在夏令时。
您可以依次将Date对象推进到月,日,小时和分钟,查看时区偏移的差异,从而找到DST和标准时间开始的月,日,小时和分钟。 这是一个繁忙的功能,但只需要在日历应用程序中执行一年。
函数getDST返回一个数组,其中Date对象代表给定年份的标准时间的第一分钟, 该年度夏令时的第一分钟,以及以分钟为单位的抵消差异。
(第二个函数返回日期和日历中该日期显示的消息)
测试此类功能的最佳方法是使用dst启用计算机中的时区,以获得尽可能多的时区。
function getDST(y){
y= y || new Date().getFullYear();
var D1= new Date(y, 0, 1), D2= new Date(y, 5, 1),
off1= D1.getTimezoneOffset(), off2= D2.getTimezoneOffset(),
diff= off2-off1;
if(diff=== 0) return ;
var stdTime= D1, dstTime= D2,
std1= 11, dst1= 5,
stdOffset= off1, dstOffset= off2,
isDst, isStd, one= 1;
if(diff>0){
diff*= -1;
stdOffset= off2;
dstOffset= off1;
std1= 5;
dst1= 11;
}
function isDst(D){
return D.getTimezoneOffset()=== dstOffset;
}
function isStd(D){
return D.getTimezoneOffset()=== stdOffset;
}
function edgeTz(D, m, check){
D.setMonth(m);
while(check(D)) D.setMonth(m--);
D.setMonth(D.getMonth()+1);
while(check(D)) D.setDate(D.getDate()-1);
one= 1;
while(!check(D)) D.setHours(one++);
D.setHours(D.getHours()-1);
one= 1;
while(!check(D)) D.setMinutes(one++);
return D;
}
stdTime= edgeTz(stdTime, std1, isStd);
dstTime= edgeTz(dstTime, dst1, isDst);
return [stdTime, dstTime, diff];
}
//标准和dst的本地开始时间: 的 getDST(2014)。加入( '\ n'); 强>
//result for EST
Sun Nov 02 2014 02: 00: 00 GMT-0500(Eastern Daylight Time)
Sun Mar 09 2014 03: 00: 00 GMT-0400(Eastern Standard Time)
-60
//日历备注:
function tzReport(y){
var z= getDST(y);
var dstMsg, stdMsg, changeStd, changeDst,
stdTime= z[0], dstTime= z[1], diff= z[2];
changeStd= new Date(stdTime);
changeStd.setDate(changeStd.getDate()+1);
changeStd.setMinutes(changeStd.getMinutes()-diff);
stdMsg= 'Standard Time begins. At '+
changeStd.timeString()+', clocks return to '+stdTime.timeString()+'.';
changeDst= new Date(dstTime);
changeDst.setDate(changeDst.getDate()+1);
changeDst.setMinutes(changeDst.getMinutes()+diff);
dstMsg= 'DST begins. At '+changeDst.timeString()+
', clocks advance to '+dstTime.timeString()+'.';
return [[stdTime.toLocaleDateString(), stdMsg],
[dstTime.toLocaleDateString(), dstMsg]];
}
//日历通知: tzReport(2014).join('\ n');
Sunday, November 02, 2014,
Standard Time begins.
At 3: 00 am, clocks return to 2: 00 am.
Sunday, March 09, 2014, DST begins.
At 2: 00 am, clocks advance to 3: 00 am.