是我算错了,还是蔡勒(Zeller)公式有问题!

吉吉义义 2010-10-26 06:34:37
历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和一些分段计算公式),其中最著名的是蔡勒(Zeller)公式。即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

公式中的符号含义如下,w:星期;c:世纪;y:年(两位数);m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算);d:日;[ ]代表取整,即只要整数部分。


我今天用这个公式算星期几时,发现,2010年10月1号以前算出来的都是正确的,但是从2010年10月1号以后就多了一个星期,如下面所示:

JS 代码:

//2005年10月1日
var a = 5+ 5/4 + 20/4-2*20+(26*(10+1)/10)+1-1;
a = parseInt(a);
a = a%7
alert(a);
//得出的结果是6,星期六是对的

//2010年9月30日
var a = 10+ 10/4 + 20/4-2*20+(26*(9+1)/10)+30-1;
a = parseInt(a);
a = a%7
alert(a);
//得出的结果是4,星期四是对的

//2010年10月1日
var a = 10+ 10/4 + 20/4-2*20+(26*(10+1)/10)+1-1;
a = parseInt(a);
a = a%7
alert(a);
//得出的结果是6,星期六不对,实际是星期五

//2010年10月25日
var a = 10+ 10/4 + 20/4-2*20+(26*(10+1)/10)+25-1;
a = parseInt(a);
a = a%7
alert(a);
//得出的结果是2,星期二不对,实际是星期一



到2010年10月1号后每个算出来的就总多了一天。



后来经过仔细观察对比测试以后发现了问题的所以,把代码改成如下就正确了

//2010年10月1日
var a = 10+ parseInt(10/4) + parseInt(20/4)-2*20+parseInt((26*(10+1)/10))+1-1;
a = a%7
alert(a);
//得出的结果是5,星期五是对的!


后来发现因为公式里面有相除的操作,有的数为能整除,在再运算时可能会进位就出现刚才的多了一天的情况,在公式只要有相除操作的,在相除以后直接取整(直接舍掉小数部分),然后再运算就不会出错了!


自己发现的一个小问题,也许大家有的很早以前就知道这个问题,但是我是第一次遇到并解决了,给没有遇到过这个问题的朋友一个借鉴!



...全文
916 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
personball 2010-11-04
  • 打赏
  • 举报
回复
-,- 公历要是查以前的话,要注意,有那么十几天是不存在的。。
吉吉义义 2010-10-30
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 hch126163 的回复:]
js 日期函数本来就有获取星期几的
alert(new Date().getDay());
[/Quote]

你说的这个只能获取当天是星期几,蔡勒(Zeller)公式是可以计算指写的哪一年的哪一天是星期几!
hch126163 2010-10-30
  • 打赏
  • 举报
回复
js 日期函数本来就有获取星期几的
alert(new Date().getDay());
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 gougoubuku 的回复:]
这两天在写一个类似GOOGLE日历的程序,用到了这个,但是在用的时候总是出错,不过慢慢的都自己解决了,就把碰到的问题写出来大家共享一下,也许高手会觉得这没什么,早就知道了,但是像我一样的朋友也许对大家有点帮助!
[/Quote]
从你的正文和这个回复,都很自然地表明你是很适合做这行的.
吉吉义义 2010-10-27
  • 打赏
  • 举报
回复
这两天在写一个类似GOOGLE日历的程序,用到了这个,但是在用的时候总是出错,不过慢慢的都自己解决了,就把碰到的问题写出来大家共享一下,也许高手会觉得这没什么,早就知道了,但是像我一样的朋友也许对大家有点帮助!
hoojo 2010-10-27
  • 打赏
  • 举报
回复
lz研究的蛮深的
  • 打赏
  • 举报
回复
楼主这个问题,挺有用。叙述得也很清楚。是个好帖。
Mr-Jee 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gougoubuku 的回复:]

引用 2 楼 cj205 的回复:
我测试了下 并没有什么问题~
但是纠正一个小问题。就是lz的c应该是年份的前2位而非世纪数吧
因为2010算21世纪了

HTML code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-t……
[/Quote]
你木有错~~~只是表述错了 呵呵
吉吉义义 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cj205 的回复:]
我测试了下 并没有什么问题~
但是纠正一个小问题。就是lz的c应该是年份的前2位而非世纪数吧
因为2010算21世纪了

HTML code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<……
[/Quote]
我把C换成21就不对了,你那里是对的吗?你再试试!
ajccom 2010-10-26
  • 打赏
  • 举报
回复
原来还有公式的 哎 数学太差了 都忘记了

Mr-Jee 2010-10-26
  • 打赏
  • 举报
回复
我测试了下 并没有什么问题~
但是纠正一个小问题。就是lz的c应该是年份的前2位而非世纪数吧
因为2010算21世纪了
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>

<script type="text/javascript" language="javascript">
function setDate() {
var date = document.getElementById("beg").value;
date = date.split("-");
var cen,year,month,day;
if (parseInt(date[1]) < 3) {
date[0] = (parseInt(date[0]) - 1).toString();
date[1] = (parseInt(date[1]) + 12).toString();
}
cen = parseInt(date[0].substr(0,2));
year = parseInt(date[0].substr(2,2));
month = parseInt(date[1]);
day = parseInt(date[2]);
var week = year + Math.floor(year / 4) + Math.floor(cen / 4) - 2 * cen + Math.floor(26 * (month + 1) / 10) + day - 1;
alert(week);
}
</script>

</head>
<body>
<input type="text" id="beg" onchange="setDate()" />

</body>
</html>
BooJS 2010-10-26
  • 打赏
  • 举报
回复
多谢分享.顶起.

87,989

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧