精华内容
下载资源
问答
  • 我们有时候会遇到这样的问题:看到一个日期想知道这一天是星期几,甚至看到一个历史日期或纪念日,我们想快速的知道这一天是星期几。对于这个问题,如果用编程的方式,应该怎么实现呢?你可能已经有思路了,比如你...

    0. 本文的初衷及蔡勒公式的用处

    前一段时间,我在准备北邮计算机考研复试的时候,做了几道与日期计算相关的题目,在这个过程中我接触到了蔡勒公式。先简单的介绍一下蔡勒公式是干什么用的。

    我们有时候会遇到这样的问题:看到一个日期想知道这一天是星期几,甚至看到一个历史日期或纪念日,我们想快速的知道这一天是星期几。对于这个问题,如果用编程的方式,应该怎么实现呢?你可能已经有思路了,比如你知道某个日期是星期几,把这个日期作为原点,然后计算目标日期和这个原点之间相差多少天,再除以 7 求余数,最后通过余数判断目标日期的星期数。通过这样的过程,你确实可以得到正确的结果,但这不够快速也不够优雅。对于这个问题,如果你懂得蔡勒公式,那就变得异常简单了,你只需要将年月日等数据代入公式,然后计算出结果,这一结果就是目标日期对应的星期数。

    当我知道蔡勒公式之后,我觉得它非常有趣也很酷,所以我不仅希望掌握公式的使用,也希望可以掌握公式背后的推导过程。然而,当我在网上搜索相关的文章时,我发现几乎所有向我展示的博客(从零几年到最近的 19 年)大多是转载、复制于这篇文章(链接):

    星期制度是一种有古老传统的制度。据说因为《圣经·创世纪》中规定上帝用了六天时间创世纪,第七天休息,所以人们也就以七天为一个周期来安排自己的工作和生活,而星期日是休息日……

    这篇文章质量很不错,讲解过程自然流畅,但是在一些细节上存在错误,有些推导步骤让人感到困惑。因此,当我掌握蔡勒公式后,很希望可以将我的理解输出出来,让想要学习蔡勒公式推导过程的人看到一些新的材料。好了,废话少说,我们开始吧。

    1. 蔡勒公式的形式

    如果你对公式的推导过程不感兴趣,只是希望使用蔡勒公式,那么只看此小节即可。蔡勒公式的形式如下:
    D=[c4]2c+y+[y4]+[13(m+1)5]+d1W=D mod 7 \begin{aligned} D &= \left[ \frac{c}{4} \right] - 2c + y + \left[ \frac{y}{4} \right] + \left[ \frac{13(m+1)}{5} \right] + d - 1 \\[2ex] W &= D \bmod 7 \end{aligned}

    其中:

    • W 是星期数。
    • c 是世纪数减一,也就是年份的前两位。
    • y 是年份的后两位。
    • m 是月份。m 的取值范围是 3 至 14,因为某年的 1、2 月要看作上一年的 13、14月,比如 2019 年的 1 月 1 日要看作 2018 年的 13 月 1 日来计算。
    • d 是日数。
    • [] 是取整运算。
    • mod 是求余运算。

    注意:这些符号在后面的推导中还会使用。举一个实际的计算例子:计算 1994 年 12 月 13 日是星期几。显然 c = 19,y = 94,m = 12,d = 13,带入公式:
    D=[194]2×19+94+[944]+[13×(12+1)5]+131=438+94+23+33+131=128W=128 mod 7=2 \begin{aligned} D &= \left[ \frac{19}{4} \right] - 2 \times 19 + 94 + \left[ \frac{94}{4} \right] + \left[ \frac{13 \times (12 + 1)}{5} \right] + 13 - 1 \\[2ex] &= 4 - 38 + 94 + 23 + 33 + 13 - 1 \\[2ex] &= 128 \\[2ex] W &= 128 \bmod 7 = 2 \end{aligned}
    由此可得 1994 年 12 月 13 日是星期二,通过查询日历可以验证正确性。

    最后关于蔡勒公式,还需要做两点补充说明:

    1. 在计算机编程中,W 的计算结果有可能是负数。我们需要注意,数学中的求余运算和编程中的求余运算不是完全相同的,数学上余数不能是负数,而编程中余数可以是负数。因此,在计算机中 W 是负数时,我们需要进行修正。修正方法十分简单:让 W 加上一个足够大的 7 的整数倍,使其成为正数,得到的结果再对 7 取余即可。比如 -15,我可以让其加上 70,得到 55,再除以 7 余 6,通过余数可知这一天是星期六。
    2. 此公式只适用于格里高利历(也就是现在的公历)。关于历法的问题,大家有兴趣可以自行查阅。

    下面是公式的推导。

    2. 推导过程

    推导蔡勒公式之前,我们先思考一下,如果我们不知道这一公式,我们如何将一个日期转化为星期数呢?

    我们可能会很自然地想到:先找到一个知道是星期几的日子,把这个日期作为“原点”,然后计算目标日期和这个原点相差几天,将相差的天数对 7 取余,再根据余数判断星期数。举一个实际例子,比如我们知道 2019 年 5 月 1 日是星期三,把这一天当作原点,现在我们想知道 2019 年 5 月 17 日是星期几,显然这两个日期之间相差 16 天,用 16 除 7 余 2,因为原点是星期三,加上作为偏移量的余数 2,可知 2019 年 5 月 17 日是星期五。

    从这个思路出发,经过优化扩展,我们就可以得到神奇的蔡勒公式了。首先,如果我们仔细观察一下可以发现,这个思路中比较麻烦的是计算相差天数(设为 DD),我们可以把 DD 的计算过程分解成三部分:

    1. D1D_1:从原点到原点所在年份末尾的天数。
    2. D2D_2:原点所在年份和目标日期所在年份之间所有年份的天数和。
    3. D3D_3:目标日期所在年份的第一天到目标日期的天数。

    在这里插入图片描述

    显然,D=D1+D2+D3D = D_1 + D_2 + D_3。如果我们把原点选择在某一年的 12 月 31 日,那么就可以省去 D1D_1 的计算了,因为原点恰好就是所在年份的最后一天。现在,D=D2+D3D = D_2 + D_3

    我们再去观察上述思路中的实际例子,可以发现,因为原点是星期三,所以得到余数后,我们需要加上 3 才是正确的星期数。这启示我们可以把原点选定在星期日,这样算出来的余数是几就是星期几(余数 0 代表星期日)。

    经过这样的分析。我们希望可以优化原点的日期,使其满足下面两个条件:

    1. 是某一年的 12 月 31 日。
    2. 是星期日。

    我们按照现在使用的公历的规则逆推,可以发现公元元年的前一年的 12 月 31 日恰好是星期日,满足我们想要的两个条件,是一个完美的原点。

    现在假设目标日期是 y 年 m 月 d 日,我们已经可以很容易的计算 D2D_2 了:
    D2=(y1)×365+[y14][y1100]+[y1400] D_2 = (y-1) \times 365 + \left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right]
    简单的解释一下。因为一年最少有 365 天,所以 D2D_2 至少是 (y1)×365(y-1) \times 365。此外,因为闰年比平年多一天,我们还需要加上这些年份中闰年的数量。按照闰年的规则:每 4 年一闰,但每 100 年不闰,每 400 年又闰。可知闰年的数量为 [y14][y1100]+[y1400]\left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right]

    现在,我们需要得到 D3D_3 的计算公式,这块要复杂一些。首先,不考虑闰年的话,每年中 2 月份天数最少,为 28 天。因此,我们不妨把每个月的天数看作 “28 + Excess”的模式,m 月之前所有月份的 Excess 之和为 Accum(m),则 D3=28×(m1)+Accum(m)+dD_3 = 28 \times (m-1) + Accum(m) + d,并且我们可以得到这样一张表格:

    月份 1 2 3 4 5 6 7 8 9 10 11 12
    天数 31 28 31 30 31 30 31 31 30 31 30 31
    Excess 3 0 3 2 3 2 3 3 2 3 2 3
    Accum 0 3 3 6 8 11 13 16 19 21 24 26

    仔细观察,可以发现 Excess 从 3 月份开始是 3、2、3、2、3 的循环,因此,当 m3m\geq 3 时,Accum(m)Accum(m) 的值的增幅也是 3、2、3、2、3 的循环。因为每 5 个月增加 13,所以把 135\frac{13}{5} 作为系数;因为 Accum(m)Accum(m) 的值是离散的(都是整数),所以我们用取整运算符,得到:
    f(x)=[135x] f(x) = \left[ \frac{13}{5}x \right]

    我们将 xx 的值取 1,2,3……,然后观察 f(x)f(x) 的值,可得下面这张表格:

    x 4 5 6 7 8 9 10 11 12 13 14
    f(x) 10 13 15 18 20 23 26 28 31 33 36

    我们可以发现,当 x4x \geq 4 时,f(x)f(x) 的值的增幅也是 3,2,3,2,3 的循环。也就是说 f(x)f(x) 的值的增幅(x4x \geq 4)与 Accum(m)Accum(m) 的值的增幅(m3m \geq 3)相同,这意味着 f(x)f(x)Accum(m)Accum(m) 之间相差一个常数,我们随便带入一个具体的值计算:
    f(4)Accum(3)=103=7 f(4) - Accum(3) = 10 - 3 = 7
    可知相差的常数为 7。由此可得,当 m3m \geq 3 时,Accum(m)Accum(m) 的值的序列,等于当 x4x \geq 4 时,f(x)7f(x) - 7 的值的序列。这样我们就得到了 Accum(m),m3Accum(m), m \geq 3 的函数形式:
    Accum(m)=f(m+1)7=[13(m+1)5]7 \begin{aligned} Accum(m) &= f(m+1) - 7 \\[2ex] &= \left [ \frac{13(m+1)}{5} \right ] - 7 \end{aligned}

    这里多说两句,实际上,Accum(m)Accum(m) 的函数形式是不唯一的,使用其他的构造方法,可以得到形式不同的 Auccm(m)Auccm(m),只要符合要求即可。

    进一步,我们可以得到 D3D_3 的函数形式:
    D3={d,m=131+d,m=2(m1)×28+[13(m+1)5]7+d+i,m3 D_3 = \begin{cases} d, &m = 1 \\[2ex] 31 + d, &m = 2 \\[2ex] (m-1) \times 28 + \left[ \frac{13(m+1)}{5} \right] - 7 + d + i, &m \geq 3 \end{cases}
    其中,平年时,i=0i = 0;闰年时,i=1i = 1。这还不是 D3D_3 最完美的形式。我们继续分析,从 3 月份到 12 月份的 Excess 正好是两个 3、2、3、2、3 的循环,那么假如有第 13 月,想要继续保持这种循环规律,13 月的 Excess 值应该是 3。而 1 月份的 Excess 的值恰好是 3,所以我们不妨变通一下,把每年的 1 月、2月当作上一年的 13月、14 月。这样不仅仍然符合公式,而且 2 月份变成了上一年的最后一个月,也就是公式中 dd 的部分,于是平闰年的影响也去掉了,D3D_3 的公式简化成了:

    D3=(m1)×28+[13(m+1)5]7+d,3m14 D_3 = (m-1) \times 28 + \left[ \frac{13(m+1)}{5} \right] - 7 + d, \quad 3 \leq m \leq 14
    现在,我们已经得到了 D2D_2D3D_3 的计算函数,由 D=D2+D3D = D_2 + D_3,可知:
    D=(y1)×365+[y14][y1100]+[y1400]+(m1)×28+[13(m+1)5]7+d,3m14 D = (y-1) \times 365 + \left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right] + (m-1) \times 28 + \left[ \frac{13(m+1)}{5} \right] - 7 + d, \quad 3 \leq m \leq 14
    **注意!这个公式离正确形式还差一小步。**因为在当前的公式中,每年的 1 月和 2 月被当作上一年的 13 月和 14 月计算,因此当前公式中计算闰日的部分([y14][y1100]+[y1400]\left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right])存在错误。举一个具体的例子,比如计算公元 4 年(闰年)3 月 1 日的星期数。在当前公式中,公元 4 年的 2 月被算作了公元 3 年的 14 月(换句话说公元 3 年变成了闰年),而公式中计算闰日的部分没有考虑这点,依然将公元 3 年当成平年计算,因此少算了一天。因此,计算闰日的部分应当改进,公式如下:
    (1)D=(y1)×365+[y4][y100]+[y400]+(m1)×28+[13(m+1)5]7+d,3m14 D = (y-1) \times 365 + \left[ \frac{y}{4} \right] - \left[ \frac{y}{100} \right] + \left[ \frac{y}{400} \right] + (m-1) \times 28 + \left[ \frac{13(m+1)}{5} \right] - 7 + d, \quad 3 \leq m \leq 14 \tag{1}
    计算出 D 的值后,对 7 取模即可得到星期数。

    根据同余定理,D 除以 7 所得的余数等于 D 式的各项分别除以 7 所得余数之和(余数之和大于等于 7 时,再对 7 取余),因此可以消去 D 式中能被 7 整除的项,进行化简:
    (2)D=(y1)×365+[y4][y100]+[y400]+(m1)×28+[13(m+1)5]7+d=(y1)×(364+1)+[y4][y100]+[y400]+[13(m+1)5]+d=(y1)+[y4][y100]+[y400]+[13(m+1)5]+d \begin{aligned} D &= (y-1) \times 365 + \left[ \frac{y}{4} \right] - \left[ \frac{y}{100} \right] + \left[ \frac{y}{400} \right] + (m-1) \times 28 + \left[ \frac{13(m+1)}{5} \right] - 7 + d \\[2ex] &= (y-1) \times (364+1) + \left[ \frac{y}{4} \right] - \left[ \frac{y}{100} \right] + \left[ \frac{y}{400} \right] + \left[ \frac{13(m+1)}{5} \right] + d \\[2ex] &= (y-1) + \left[ \frac{y}{4} \right] - \left[ \frac{y}{100} \right] + \left[ \frac{y}{400} \right] + \left[ \frac{13(m+1)}{5} \right] + d \tag{2} \end{aligned}
    简单说明一下:
    (y1)×365=(y1)×(364+1)=(y1)×364+(y1)=(y1)×52×7+(y1) \begin{aligned} (y-1) \times 365 &= (y-1) \times (364+1) \\[2ex] &= (y-1) \times 364 + (y-1) \\[2ex] &= (y-1) \times 52 \times 7 + (y-1) \end{aligned}
    显然,结果中的第一项是 7 的倍数,除以 7 余数为 0,因此 (y1)×365(y-1) \times 365 除以 7 的余数其实就等于 (y1)(y-1) 除以 7 的余数,我们只保留 (y1)(y-1)就够了。化简过程中,其他被销去的项同理。

    公式(2)还不是最简练的形式,我们还可以对年份进行处理。我们现在用公式(2)计算出每个世纪第一年 3 月 1 日的星期数,得到如下结果:

    年份: 1, 401, 801, … , 2001 101, 501, 901, … , 2101 201, 601, 1001, … , 2201 301, 701, 1101, … ,2301
    星期: 4 2 0 5

    可以发现,每隔 4 个世纪,星期数就会重复一次。因为在数学上,-2 和 5 除以 7 的余数相同,所以我们不妨把这个重复序列中的 5 改为 -2。这样,4、2、0、-2 恰好构成了一个等差数列。利用等差公式,我们可以得到计算每个世纪第一年的 3 月 1 日星期数的公式:
    (3)W=42(c mod 4) W = 4 - 2(c \bmod 4) \tag{3}
    其中,cc 是世纪数减一。我们把公式(2)和公式(3)联立,代入特定的日期——3 月 1 日,可以得到:
    ((y1)+[y14][y1100]+[y1400]+11) mod 7=42(c mod 4) ((y-1) + \left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right] + 11) \bmod 7 = 4 - 2(c \bmod 4)
    利用同余定理,经过变换得到:
    (4)(y1)+[y14][y1100]+[y1400]2(c mod 4)( mod 7) (y-1) + \left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right] \equiv -2(c \bmod 4) \quad (\bmod 7) \tag{4}
    其中,\equiv 是表示同余的符号,括号中  mod 7\bmod 7 的意思是指 \equiv 两边的数除以 7 得到的余数相同。根据公式(4),我们可以知道在每个世纪的第一年,(y1)+[y14][y1100]+[y1400](y-1) + \left[ \frac{y-1}{4} \right] - \left[ \frac{y-1}{100} \right] + \left[ \frac{y-1}{400} \right] 可以被 2(c mod 4)-2(c \bmod 4) 同余替换。进而计算 DD 的公式得到如下形式:
    (5)D=2(c mod 4)+[13(m+1)5]+d D = -2(c \bmod 4) + \left[ \frac{13(m+1)}{5} \right] + d \tag{5}
    **注意!现在的计算公式只能适用于每个世纪的第一年。**但是,有个这个公式,再加上计算一个世纪中闰日的部分,我们就可以很容易地得到计算这个世纪其他年份的日期的星期数的公式了。令 c 等于世纪数减一,y 等于世纪中的年份数(如 1994 年,则 c = 19,y = 94)。因为一个世纪中只有一百年,所以不用考虑“四百年又闰”的情况;因为每百年,即每个世纪最后一年的 y = 00,而 [y4]y=0=0\left[ \frac{y}{4} \right]_{y=0} = 0,所以 [y4]\left[ \frac{y}{4} \right] 既可以计算四年一闰的情况,又满足百年不闰的要求 。综合这些情况,与得到公式(2)的过程类似,我们可以得到:
    (6)D=2(c mod 4)+(y1)+[y4]+[13(m+1)5]+d D = -2(c \bmod 4) + (y-1) + \left[ \frac{y}{4} \right] + \left[ \frac{13(m+1)}{5} \right] + d \tag{6}
    在公式(6)中,yy 是年份的后两位。

    最后,我们来把公式中的取模运算改成四则运算。设商为 qq,余数为 rr,则:
    4q+r=c 4q + r = c
    又因为,
    q=[c4]r=c mod 4 \begin{aligned} q &= \left[ \frac{c}{4} \right] \\[2ex] r &= c \bmod 4 \end{aligned}
    可得:
    c mod 4=c4×[c4] c \bmod 4 = c - 4 \times \left[ \frac{c}{4} \right]
    代入公式(6)可得:
    (7)D=[c4]2c+y1+[y14]+[13(m+1)5]+d D = \left[ \frac{c}{4} \right] - 2c + y - 1 + \left[ \frac{y-1}{4} \right] + \left[ \frac{13(m+1)}{5} \right] + d \tag{7}

    至此,我们就得到了蔡勒公式的最终形式。

    展开全文
  • 已知日期字符串:,日期字符串转换为日期对象 2.(1)中的日期对象转换为日历类的对象 3.根据日期对象获取改日期星期几,以及这一年的第几天 4.通过键盘录入日期字符串,格式(2015-10-20) 如输入:2015-10-20, ...

    Java基础 api中日期方法案例

    分析以下需求,并用代码实现 1.已知日期字符串:,将该日期字符串转换为日期对象 2.将(1)中的日期对象转换为日历类的对象 3.根据日期对象获取改日期是星期几,以及这一年的第几天 4.通过键盘录入日期字符串,格式(2015-10-20) 如输入:2015-10-20, 输出"2015年-10月-20日 是 星期二,是2015年的第 293 天

    package homework;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Scanner;
    
    public class Two {
        public static void main(String[] args) throws ParseException {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入日期字符串(格式:2015-10-20)");
            String s=sc.nextLine();//键盘录入
    
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            Date date=sdf.parse(s);//把字符串转换为日期格式
    
            Calendar cal=Calendar.getInstance();
            cal.setTime(date);//日期类型为键盘录入的日期,不再是当前系统日期
    
            int year=cal.get(Calendar.YEAR);//年份
            int month=cal.get(Calendar.MONTH)+1;//月份
            int dayofMonth=cal.get(Calendar.DAY_OF_MONTH);//这个月的第几天
            int dayyear=cal.get(Calendar.DAY_OF_YEAR);//这一年的第几天
            int weekday=cal.get(Calendar.DAY_OF_WEEK);//这周的第几天
            String w=getweek(weekday);//调用getweek方法,使显示这周第几天格式改为星期~
    
            //输出:2015年-10月-20日 是 星期日二,是2015年的第 293 天
            System.out.println(year+"年-"+month+"月-"+dayofMonth+"日"+" 是 "+w+",是"+year+"年的第 "+dayyear+" 天");
    
    
        }
        public static String getweek(int week) {                             //定义方法
            String[] weeks={"","星期日","星期一","星期日二","星期三","星期四","星期五","星期六"};
            return weeks[week];
        }
    
    
    
    
    
    展开全文
  • //若结束时间早于上午上班时间,日期向前推一天,并时间设置下午下班时间 if(t.getHours()){ t.setTime(t.getTime()-milsecPerDay); t.setHours(peh); t.setMinutes(pem); } } ...
  • 下面介绍了如何在不使用任何库函数的情况下Unix epoch时间转换为(UTC)Gregorian日期。下面的代码只导入time,以验证计算的日期是否与time.gmtime返回的日期相同。在请注意,在2038年1月19日(星期二)UTC 03:14:08,...

    下面介绍了如何在不使用任何库函数的情况下将Unix epoch时间转换为(UTC)Gregorian日期。下面的代码只导入time,以验证计算的日期是否与time.gmtime返回的日期相同。在

    请注意,在2038年1月19日(星期二)UTC 03:14:08,32位版本的Unix时间戳将停止工作,因为它将溢出32位数字中可以保存的最大值。因此,在32位系统上,不要尝试调用time.gmtime来获取此类时间戳。当然,下面使用的算法不受这些限制。在#!/usr/bin/env python

    ''' Convert Unix Epoch seconds to (proleptic) Gregorian date

    Algorithm by E. G. Richards, https://en.wikipedia.org/wiki/Julian_day

    See http://stackoverflow.com/q/35796786/4014959

    Python implementation by PM 2Ring 2016.03.07

    '''

    from time import gmtime

    def epoch_seconds_to_gregorian_date(eseconds):

    # Algorithm parameters for Gregorian calendar

    y = 4716; j = 1401; m = 2; n = 12; r = 4; p = 1461

    v = 3; u = 5; s = 153; w = 2; B = 274277; C = -38

    #Julian day, rounded

    J = int(0.5 + eseconds / 86400.0 + 2440587.5)

    f = J + j + (((4 * J + B) // 146097) * 3) // 4 + C

    e = r * f + v

    g = (e % p) // r

    h = u * g + w

    D = (h % s) // u + 1

    M = (h // s + m) % n + 1

    Y = (e // p) - y + (n + m - M) // n

    return Y, M, D

    # Tests

    def test(s):

    t = gmtime(s)

    gmdate = t.tm_year, t.tm_mon, t.tm_mday

    e2gdate = epoch_seconds_to_gregorian_date(s)

    assert gmdate == e2gdate, (t, gmdate, e2gdate)

    return '%d.%d.%d' % e2gdate

    print 'hours'

    for i in xrange(25):

    s = 3600 * i

    print i, test(s)

    print '\ndays'

    for i in xrange(32):

    s = 86400 * i

    print i, test(s)

    print '\n2 days by seconds...'

    for s in xrange(86400 * 2):

    test(s)

    n = 50

    print '\n%d years by days...' % n

    for i in xrange(365 * n):

    s = 86400 * i

    test(s)

    print 'Ok'

    输出

    ^{pr2}$

    这是一个改进的版本,它还返回小时、分钟和秒。这段代码处理分数秒,但是time.struct_time的字段都是整数,因此我的test函数不能与分数秒一起使用。在#!/usr/bin/env python

    ''' Convert Unix Epoch seconds to (proleptic) Gregorian date

    Algorithm by E. G. Richards, https://en.wikipedia.org/wiki/Julian_day

    See http://stackoverflow.com/q/35796786/4014959

    Python implementation by PM 2Ring 2016.03.07

    '''

    from time import time, gmtime

    from random import randint

    import sys

    def epoch_seconds_to_gregorian_date(eseconds):

    # Algorithm parameters for Gregorian calendar

    y = 4716; j = 1401; m = 2; n = 12; r = 4; p = 1461

    v = 3; u = 5; s = 153; w = 2; B = 274277; C = -38

    #Julian day, rounded

    J = int(0.5 + eseconds / 86400.0 + 2440587.5)

    #Date calculation

    f = J + j + (((4 * J + B) // 146097) * 3) // 4 + C

    e = r * f + v

    g = (e % p) // r

    h = u * g + w

    D = (h % s) // u + 1

    M = (h // s + m) % n + 1

    Y = (e // p) - y + (n + m - M) // n

    #Time calculation

    seconds = eseconds % 86400

    t = int(seconds)

    hr, t = divmod(t, 3600)

    mn = t // 60

    seconds -= 3600 * hr + 60 * mn

    return Y, M, D, hr, mn, seconds

    # Tests

    def test(s):

    t = gmtime(s)

    gmdate = t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec

    e2gdate = epoch_seconds_to_gregorian_date(s)

    assert gmdate == e2gdate, (s, gmdate, e2gdate)

    return '%d.%02d.%02d %02d:%02d:%06.3f' % e2gdate

    print 'now'

    s = time()

    print s, epoch_seconds_to_gregorian_date(s), gmtime(s)

    print '\nhours'

    for i in xrange(25):

    s = 3600 * i

    print i, test(s)

    print '\ndays'

    for i in xrange(32):

    s = 86400 * i

    print i, test(s)

    print '\n2 days by seconds...'

    for i in xrange(86400 * 2):

    test(i)

    if i % 10000 == 0:

    sys.stderr.write('.')

    sys.stderr.write('\n')

    n = 50

    print '\n%d years by days...' % n

    for i in xrange(365 * n):

    s = 86400 * i

    test(s)

    n = 500000

    print '\nRandom seconds'

    for i in xrange(n):

    s = randint(0, 2147483647)

    test(s)

    if i % 10000 == 0:

    sys.stderr.write('.')

    sys.stderr.write('\n')

    print 'Ok'

    输出now

    1457355412.48 (2016, 3, 7, 12, 56, 52.476011991500854) time.struct_time(tm_year=2016, tm_mon=3, tm_mday=7, tm_hour=12, tm_min=56, tm_sec=52, tm_wday=0, tm_yday=67, tm_isdst=0)

    hours

    0 1970.01.01 00:00:00.000

    1 1970.01.01 01:00:00.000

    2 1970.01.01 02:00:00.000

    3 1970.01.01 03:00:00.000

    4 1970.01.01 04:00:00.000

    5 1970.01.01 05:00:00.000

    6 1970.01.01 06:00:00.000

    7 1970.01.01 07:00:00.000

    8 1970.01.01 08:00:00.000

    9 1970.01.01 09:00:00.000

    10 1970.01.01 10:00:00.000

    11 1970.01.01 11:00:00.000

    12 1970.01.01 12:00:00.000

    13 1970.01.01 13:00:00.000

    14 1970.01.01 14:00:00.000

    15 1970.01.01 15:00:00.000

    16 1970.01.01 16:00:00.000

    17 1970.01.01 17:00:00.000

    18 1970.01.01 18:00:00.000

    19 1970.01.01 19:00:00.000

    20 1970.01.01 20:00:00.000

    21 1970.01.01 21:00:00.000

    22 1970.01.01 22:00:00.000

    23 1970.01.01 23:00:00.000

    24 1970.01.02 00:00:00.000

    days

    0 1970.01.01 00:00:00.000

    1 1970.01.02 00:00:00.000

    2 1970.01.03 00:00:00.000

    3 1970.01.04 00:00:00.000

    4 1970.01.05 00:00:00.000

    5 1970.01.06 00:00:00.000

    6 1970.01.07 00:00:00.000

    7 1970.01.08 00:00:00.000

    8 1970.01.09 00:00:00.000

    9 1970.01.10 00:00:00.000

    10 1970.01.11 00:00:00.000

    11 1970.01.12 00:00:00.000

    12 1970.01.13 00:00:00.000

    13 1970.01.14 00:00:00.000

    14 1970.01.15 00:00:00.000

    15 1970.01.16 00:00:00.000

    16 1970.01.17 00:00:00.000

    17 1970.01.18 00:00:00.000

    18 1970.01.19 00:00:00.000

    19 1970.01.20 00:00:00.000

    20 1970.01.21 00:00:00.000

    21 1970.01.22 00:00:00.000

    22 1970.01.23 00:00:00.000

    23 1970.01.24 00:00:00.000

    24 1970.01.25 00:00:00.000

    25 1970.01.26 00:00:00.000

    26 1970.01.27 00:00:00.000

    27 1970.01.28 00:00:00.000

    28 1970.01.29 00:00:00.000

    29 1970.01.30 00:00:00.000

    30 1970.01.31 00:00:00.000

    31 1970.02.01 00:00:00.000

    2 days by seconds...

    ..................

    50 years by days...

    Random seconds

    ..................................................

    Ok

    展开全文
  • text函数在Excel中的应用很广,在办公中起到重要作用,今天用五个例子教会你text函数的...2、转换为星期单元格中只显示日期,要转换成日期怎么做呢?输入公式:=TEXT(A2,"aaaa"),就能实现目标单元格转换成日期...

    text函数在Excel中的应用很广,在办公中起到重要作用,今天用五个例子教会你text函数的使用技巧。

    1、转换日期格式

    通过text函数可以将单元格的日期转换成文本格式的日期,公式:=TEXT(A2,"yyyy年mm月dd日"),就能将对应的单元格转换成其他的日期格式。

    b7c7acbeaa2f54449d4d1556fc07fdc5.gif

    2、转换为星期

    单元格中只显示日期,要转换成日期怎么做呢?输入公式:=TEXT(A2,"aaaa"),就能实现将目标单元格转换成日期格式。

    70b0bbe19d3f00ac1d1928b060372523.gif

    3、计算时间差

    通过上下班时间计算工作时间,在目标单元格上输入公式:=TEXT(H2-C2,"H小时MM分钟")。

    03b5a0dbac2c0ed4d73d345c0ce5771c.gif

    4、划分等级

    根据已知的业绩,划分该数据是否合格,在目标单元格输入公式:=TEXT(B2,"[<5000]不合格;[>=5000]合格"),就能自动将小于5000的数据分类为不合格,大于等于5000的数据标记为合格。

    6fa813a7d1284d2385aa361dc2e73ed0.gif

    5、盈亏标记

    操作方法是在单元格中输入公式=TEXT(B2,"盈利;亏本;持平")。

    340951eea1ef0dbcb8d7b5594ef5ac9c.gif
    展开全文
  • Python学习

    2020-08-07 21:46:02
    **1.**假设你获取了用户输入的日期和时间如 2020-1-21 9:01:30 ,以及一个时区信息如 UTC+5:00 ,均是 str ,请 编写一个函数转换为timestamp。 **2.**编写Python程序以选择指定年份的所有星期日。 ...
  • //每行转换为单个T对象 for (int i = 1; i ; i++) { IRow row = sheet.GetRow(i); var obj = new T(); for (int j = 0; j ; j++) { //没有数据的单元格都默认是null ICell cell = row.GetCell(j); ...
  • task8

    2021-02-02 23:10:20
    1、假设你获取了用户输入的日期和时间如2020-1-21 9:01:30,以及一个时区信息如UTC+5:00,均是str,请编写一个函数转换为timestamp: 2、编写Python程序以选择指定年份的所有星期日。 ...
  • 有何办法实现一张表中的数据由元的单位转换为万元 常用的自定义格式 自定义格式 怎样定义格式 在工具按钮之间设置分隔线 自定义区域为每一页的标题 一个单元格内格式问题 定制单元格数字显示格式 巧用定位选条件...
  • EXCEL函数公式集

    热门讨论 2010-03-16 03:26:38
    有何办法实现一张表中的数据由元的单位转换为万元 常用的自定义格式 自定义格式 怎样定义格式 在工具按钮之间设置分隔线 自定义区域为每一页的标题 一个单元格内格式问题 定制单元格数字显示格式 巧用定位选条件...
  • java常用工具类的使用

    热门讨论 2012-03-19 20:11:37
    代码演示:SimpleDateFormat进行日期转换 import java.text.SimpleDateFormat; import java.util.Date; public class Demo4 { public static void main(String[] args) { Date today = new Date(); ...
  • 如果我指针值设为0,编译器可能会自动转换为非零的空指针内部表示。 5.20运行时的“nullpointerassignment”错误是什么意思?应该怎样捕捉它? 第6章 数组和指针 数组和指针的基本关系 6.1 我在一个源文件中...
  • 如果我指针值设为0,编译器可能会自动转换为非零的空指针内部表示。 62  5.20 运行时的“null pointer assignment”错误是什么意思?应该怎样捕捉它? 62 第6章 数组和指针 63 数组和指针的基本关系 ...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    内容简介 《你必须知道的495个C语言问题》以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个...5.18 运行时的整数值0转换为指针以后一定是空指针吗? 61 5.19...
  • 实物LCD1602显示温度0,其他信息正常显示,仿真一切正常,若显示温度的函数单独提取成文件,则正常显示温度,不知道怎么改 PS只需看主函数,LCD1602.h和temp.h就行 ``` #include"key.h" #include"lcd1602.h...
  • asp.net知识库

    2015-06-18 08:45:45
    在C#里把ArrayList转换为Array 或 把Array转换为ArrayList C# 2.0 在.NET 2.0中,让你的组件也可以绑定 .NET20 一种简单的窗口控件UI状态控制方法 翻译MSDN文章 —— 泛型FAQ:最佳实践 Visual C# 3.0 新特性概览 C#...
  • javascript函数的解释

    2011-02-26 11:03:52
    置年,dateObj.setMonth(val)设置月,dateObj.setDate(val)设置日,dateObj.setDay(val)设 置星期几,dateObj.setHours设置小时,dateObj.setMinutes(val)设置分,dateObj.setSeconds (val)设置秒 [注意:此日期时间从0开始...
  • Visual Studio程序员箴言--详细书签版

    热门讨论 2012-10-16 20:37:39
    技巧2.9 空格转换为制表符和制表符转换为空格 30 技巧2.10 从文本编辑器工具栏上增加或减少行缩进 31 技巧2.11 智能缩进与块缩进之间有什么区别 32 2.1.4 大纲显示 32 技巧2.12 折叠和展开代码 32 ...
  • %~tI - %I 扩充到文件的日期/时间 %~zI - %I 扩充到文件的大小 %~$PATH:I - 查找列在路径环境变量的目录,并 %I 扩充 到找到的第一个完全合格的名称。如果环境变量 未被定义,或者没有找到文件,此组合...

空空如也

空空如也

1 2
收藏数 21
精华内容 8
关键字:

怎么将日期转换为星期