zoukankan      html  css  js  c++  java
  • C语言计算日期间隔天数的经典算法解析

    #include <stdio.h>
    #include <stdlib.h>

    int day_diff(int year_start, int month_start, int day_start
       , int year_end, int month_end, int day_end)
    {
     int y2, m2, d2;
     int y1, m1, d1;
     
     m1 = (month_start + 9) % 12;
     y1 = year_start - m1/10;
     d1 = 365*y1 + y1/4 - y1/100 + y1/400 + (m1*306 + 5)/10 + (day_start - 1);

     m2 = (month_end + 9) % 12;
     y2 = year_end - m2/10;
     d2 = 365*y2 + y2/4 - y2/100 + y2/400 + (m2*306 + 5)/10 + (day_end - 1);
     
     return (d2 - d1);
    }

    int main(void)
    {
     printf("%d ", day_diff(2015, 1, 1, 2015, 1, 8));
     printf("%d ", day_diff(2015, 1, 29, 2015, 2, 9));
     
     return 0;
    }

    算法解析

    该算法总体思想是计算给定日期到 0年3月1日的天数,然后相减,获取天数的间隔。

    m1 = (month_start + 9) % 12; 用于判断日期是否大于3月(2月是判断闰年的标识),还用于纪录到3月的间隔月数。

    y1 = year_start - m1/10; 如果是1月和2月,则不包括当前年(因为是计算到0年3月1日的天数)。

    d1 = 365*y1 + y1/4 - y1/100 + y1/400 + (m1*306 + 5)/10 + (day_start - 1);

        其中 365*y1 是不算闰年多出那一天的天数,

        y1/4 - y1/100 + y1/400  是加所有闰年多出的那一天,

    (m2*306 + 5)/10 用于计算到当前月到3月1日间的天数,306=365-31-28(1月和2月),5是全年中不是31天月份的个数

    (day_start - 1) 用于计算当前日到1日的间隔天数。

    测试运行结果:

    7

    11


    稍微改进一下,让其变得更好用一点:

    #include <stdio.h>
    #include <stdlib.h>

    // 将日期转换为天数后作差即为两日期相距天数
    int day_diff(int *pDate1, int *pDate2)
    {
    int y2, m2, d2;
    int y1, m1, d1;

    m1 = (pDate1[1] + 9) % 12;
    y1 = pDate1[0] - m1/10;
    d1 = 365*y1 + y1/4 - y1/100 + y1/400 + (m1*306 + 5)/10 + (pDate1[2] - 1);

    m2 = (pDate2[1] + 9) % 12;
    y2 = pDate2[0] - m2/10;
    d2 = 365*y2 + y2/4 - y2/100 + y2/400 + (m2*306 + 5)/10 + (pDate2[2] - 1);

    return (d2 - d1);
    }


    // 将字符串日期转换为整数
    void datetointeger(char *pDate, int *pInteger)
    {
    char *pYear = &pDate[0];
    char *pMonth = &pDate[5];
    char *pDay = &pDate[8];
        
    pInteger[0] = atoi(pYear);
    pInteger[1] = atoi(pMonth);
    pInteger[2] = atoi(pDay);
    }


    int main(void)
    {
    char date1[] = "2013-09-16";
    char date2[] = "2014-09-16";
    int arr1[3] = {0};
    int arr2[3] = {0};

    datetointeger(date1, arr1);
    datetointeger(date2, arr2);

    printf("pYear1:%d, pMonth1:%d, pDay1:%d ", arr1[0], arr1[1], arr1[2]);
    printf("pYear2:%d, pMonth2:%d, pDay2:%d ", arr2[0], arr2[1], arr2[2]);

    printf("date2 - date1 = %d天 ", day_diff(arr1, arr2));

    return 0;
    }

    输出结果如下:
    pYear1:2013, pMonth1:9, pDay1:16
    pYear2:2014, pMonth2:9, pDay2:16
    date2 - date1 = 365天

  • 相关阅读:
    直接初始化和复制初始化
    C++ 内连接与外连接 (转)
    mysql-Innodb事务隔离级别-repeatable read详解(转)
    Linux操作系统多线程信号总结
    Keil MDK 5.14 仿真时System Viewer菜单显示空白和Peripherals菜单无外设寄存器
    转载傅里叶级数和傅里叶变换的理解 https://www.cnblogs.com/h2zZhou/p/8405717.html
    SPI总线的原理与Verilog实现
    SD 模拟sip 读写子程序
    SD卡 模拟SPI总线控制流程
    SD卡spi读写流程
  • 原文地址:https://www.cnblogs.com/alan666/p/8311973.html
Copyright © 2011-2022 走看看