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\n", day_diff(2015, 1, 1, 2015, 1, 8));
    printf("%d\n", 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日的间隔天数。

测试运行结果:

 

通过日期得到与第一天相差的天数   代码如下:

#include "stdafx.h"
void ComputingTime(int dayNumber,int * data)
{
    int i       = 0;
    int days    = 0;
    int days2   = 0;
    int year    = 1972;
    int supDay  = 0;
    int today   = 0;
    int day1[]  = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int day2[]  = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int month[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    
    days += (dayNumber + 1);

    while (1)
    {
        if (days <= 366)
        {
            break;
        }

        if ((i+1972) % 400 == 0 || ((i+1972) % 4 == 0 && (i+1972) % 100 != 0))
        {
            days -= 366;
        }
        else
        {
            days -= 365;
        }

        i++;
    }

    if ((!((i + 1972) % 400 == 0 || ((i + 1972) % 4 == 0 && (i + 1972) % 100 != 0))) && (days == 366))
    {
        year += (i + 1);
        data[0] = year;
        days = 1;
    }
    else 
    {
        year += i;
        data[0] = year;
    }

    for (i = 0; i < 12; i++) {
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
        {
            if (days <= day2[i])
            {
                data[1] = month[i];
                data[2] = days;
                break;
            }
            days = days - day2[i];
        }
        else
        {
            if (days <= day1[i])
            {
                data[1] = month[i];
                data[2] = days;
                break;
            }
            days = days - day1[i];
        }
    }

    days2 = dayNumber;
    today = (days2 + 6) % 7;
    if (today == 0)
    {
        data[3] = 7;
    }
    else
    {
        data[3] = today;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值