获取日历、日期信息

第一题

题目描述:输入年月日,判断是该年第几天?

#include <stdio.h>

int leap_year(int n)
{
    if(n%400==0||(n%4==0 && n%100!=0))
        return 1;
    else
        return 0;
}
int main()
{
    int year,month,day;
    int dayCount=0,i;
    int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	printf("请输入当前的年,月,日: ");
    scanf("%d-%d-%d",&year,&month,&day);
    for(i=1;i<month;i++)
        dayCount+=mon[i];
    if(month>2)
        dayCount+=day+leap_year(year);
    else
        dayCount+=day;
	printf("该日是该年的第几天: %d\n",dayCount);
    return 0;
}

第二题

题目描述:给定年、月、日,计算该日是该年的第几天,并且计算该日是星期几。

#include <stdio.h>

int leap_year(int n)
{
    if(n%400==0||(n%4==0 && n%100!=0))
        return 1;
    else
        return 0;
}

int cal_dayCount(int year,int month,int day)
{
    int i,sum;
	int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    for(i=1,sum=0;i<month;i++)
        sum+=mon[i];
    if(month>2)
        sum+=day+leap_year(year);
    else
        sum+=day;
    return sum;
}

int cal_weekday(int year,int month,int day)
{
    /**
    蔡勒(Zeller)公式 
    历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和
    一些分段计算公式),其中最著名的是蔡勒(Zeller)公式。
    即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 
    公式中的符号含义如下,
     w:星期;
     c:年的高两位,即(世纪-1)
     y:年的低两位;
     m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,
          比如2003年1月1日要看作2002年的13月1日来计算);
     d:日;
     [ ]代表取整,即只要整数部分。

    算出来的W除以7,余数是几就是星期几。如果余数是0,则为星期日。 
    如果结果是负数,负数求余数则需要特殊处理:
    负数不能按习惯的余数的概念求余数,只能按数论中的余数的定义求余。为了方便 
    计算,我们可以给它加上一个7的整数倍,使它变为一个正数,然后再求余数    

    以2049年10月1日(100周年国庆)为例,用蔡勒(Zeller)公式进行计算,过程如下: 
    蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 
    =49+[49/4]+[20/4]-2×20+[26× (10+1)/10]+1-1 
    =49+[12.25]+5-40+[28.6] 
    =49+12+5-40+28 
    =54 (除以7余5) 
    即2049年10月1日(100周年国庆)是星期5。
    */
    int y, c, m, d;
    int w;

    if (month >= 3)
    {
        m = month;        
        y = year % 100;
        c = year / 100;
        d = day;
    }
    else    /* 某年的1、2月要看作上一年的13、14月来计算 */
    {
        m = month + 12;
        y = (year - 1) % 100;
        c = (year - 1) / 100;
        d = day;
    }
    w = y + y / 4 +  c / 4 - 2 * c + (26*(m+1))/10 + d - 1;
    
    if (w < 0)    /* 如果w是负数,则计算余数方式不同 */
    {
        w = 7 - (-w) % 7;
    }
    else
    {
        w = w % 7;  //如果w等于0,表示为星期天
    }
    return w;
}

int main()
{
    int year,month,day;
    int dayCount=0,i;
    printf("请输入当前的年,月,日: ");
    scanf("%d-%d-%d",&year,&month,&day);
    printf("该日是该年的第几天: %d\n",cal_dayCount(year,month,day));
    printf("该日是星期几: %d\n",cal_weekday(year,month,day));
    return 0;
}

第三题

题目描述:现在已知2000年1月1日是星期六,给定一个正整数n,求出2000年1月1日之后n天的日期和星期。

#include <stdio.h>
#include <string.h>

#define STR_LEN 12

//获取某一年的天数
int YearDays(int year)
{
    if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) {
        return 366;
    } else {
        return 365;
    }
}

//获取某一月的天数
int MonthDays(int year, int month)
{
    int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (YearDays(year) == 366) { //如果该年是闰年,则2月份为29天
        months[2] = 29;
    }
    return months[month];
}

//获取星期几字符串信息
void GetWeekdayInfo(int n, char *weekday)
{
    char weekdays[][STR_LEN] = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
    int index = n % 7;
    strncat(weekday, weekdays[index], STR_LEN);
}

//计算n天后的年月日星期信息
void CalDateInfo(int n, int *year, int *month, int *day, char *weekday)
{
    GetWeekdayInfo(n, weekday);
    *year = 2000;
    while (n >= YearDays(*year)) {
        n -= YearDays(*year);
        (*year)++;
    }
    *month = 1;
    while (n >= MonthDays(*year, *month)) {
        n -= MonthDays(*year, *month);
        (*month)++;
    }
    *day = n + 1; //加1是因为每月的第一天是从1号开始的
}

int main()
{
    int n;
    int year, month, day;
    char weekday[STR_LEN] = {0};
    while (scanf("%d", &n) != EOF) {
        CalDateInfo(n, &year, &month, &day, weekday);
        printf("%d-%d-%d %s\n", year, month, day, weekday);
    }
    return 0;
}

第四题

题目描述:输入一个年月日星期几,计算N天后是哪年哪月哪日星期几,考虑平闰年及各种输入错误情况。

#include <stdio.h>

typedef struct {
    int year;
    int month;
    int day;
} Date;

char *g_week[] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
int g_months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int IsLeapYear(int year);
void ListDate(int weekday, Date now, int diff);

/* 知道今天星期几以及年月日,编写C程序,要求能算出任意天后是星期几以及年月日 */
void main()
{
    int weekday;
    Date now;
    int diff;
    
    printf("请输入今天是星期几以及日期");
    printf("星期几(0..6,星期日..星期六):");
    scanf("%d", &weekday);
    printf("日期(yyyy-mm-dd): ");
    scanf("%d-%d-%d", &now.year, &now.month, &now.day);
    printf("相隔天数:");
    scanf("%d", &diff);

    ListDate(weekday, now, diff);
}

/* 判断闰年 */
int IsLeapYear(int year)
{
    return ((year%400==0) || (year%4==0 && year%100!=0)) ? 1 : 0;
}

/* 已知今天是星期几(weekday,0..6,Sunday..Saturday)以及日期(now),输出diff天后是星期几以及日期 */
/* diff > 0 指diff天后,diff < 0 指diff天前 */
void ListDate(int weekday, Date now, int diff)
{
    int w1;
    Date d1;
    
    /* 计算diff天后是星期几 */
    w1 = weekday + diff;
    while(w1 < 0)
    {
        w1 += 7;
    }
    w1 = w1 % 7;
    printf("%d 天后:\n", diff);
    printf("%s\n", g_week[w1]);
    
    /* 计算diff天的日期 */
    d1.year = now.year;
    d1.month = now.month;
    d1.day = now.day + diff;
    
    if(d1.day > 0)
    {
        while(d1.day > g_months[d1.month])
        {
            d1.day -= g_months[d1.month] + (d1.month==2 && IsLeapYear(d1.year));
            d1.month++;
            if(d1.month > 12)
            {
                d1.month = 1;
                d1.year++;
            }
        }
    }
    else if(d1.day < 0)
    {
        while(d1.day <= 0)
        {
            d1.month--;
            if(d1.month <= 0)
            {
                d1.month = 12;
                d1.year--;
            }
            d1.day += g_months[d1.month] + (d1.month==2 && IsLeapYear(d1.year));          
        }
    }
    printf("%d-%d-%d\n", d1.year, d1.month, d1.day);
}

第五题

题目描述:设计一个表示日期的结构体。编写一个函数,计算两个日期之间差多少天。在 main 函数 中调用该函数,并显示。

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

#define LEAP_YEAR 366
#define COMMON_YEAR 365

int g_months[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

typedef struct {
    int year;
    int month;
    int day;
} Date;

typedef struct date DATE;

void interval_days()
{
    int i,result,sum1,sum2;
    Date date1, date2;
    printf("请输入第一个日期: ");
    scanf("%d-%d-%d", &date1.year, &date1.month, &date1.day);
    if(date1.year<=0 || date1.month<=0 || date1.month>12 || date1.day<=0 || date1.day>31)
    {
        printf("输入错误,请准确输入日期!\n");
        exit(-1);
    }
    printf("请输入第二个日期: ");
    scanf("%d-%d-%d",&date2.year,&date2.month,&date2.day);
    if(date2.year<0 || date2.month<0 || date2.month>12 || date2.day<0 || date2.day>31)
    {
        printf("输入错误,请准确输入日期!\n");
        exit(-1);
    }
    //算法思路:我们以公元1年1月1日为基准,分别计算间隔天数,然后两者相减就是这两个日期的间隔天数了
    sum1=sum_days(&date1);
    sum2=sum_days(&date2);
    result=abs(sum1-sum2);
    printf("日期之差为: %d\n",result);
}

int sum_days(DATE *date)
{
    int i,sum;
    //计算公元1年1月1日到某年的1月1号的天数
    for(i=1,sum=0;i<date->year;i++){
        if(i%400==0 || (i%4==0 && i%100!=0))
            sum+=LEAP_YEAR;
        else
            sum+=COMMON_YEAR;
    }
    //计算该年的1月1号到该日期的天数
    for(i=1;i<date->month;i++){
        sum+=g_months[i];
    }
    if(date->month>2 && (date->year%400==0 || (date->year%4==0 && date->year%100!=0)))
        sum+=date->day+1;
    else
        sum+=date->day;
    return sum;
}

int main()
{
    interval_days();
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值