繁体   English   中英

如何在 c 中的当前日期添加一定天数

[英]How can i add a certain number of days to a current date in c

我一直在尝试将特定天数(我正在尝试添加 30)添加到当前日期。

假设今天的日期是 2023 年 1 月 1 日,加上我要添加的天数后,我会得到 2023 年 1 月 31 日,主要问题是如果 2 月有 29 天而不是 28 天,我是否想添加。

我得到了当前日期,但无法添加我想要的天数,因为如果格式不是这样的“Sun Jan 01 16:29:19 2023”,我不知道其他获取当前日期的方法。

顺便说一下,我看到人们使用 c 将 x 天添加到日期,但这些问题是用户将他们想要的日期插入到问题中,我的问题是将其添加到当前日期。

任何人都可以帮我解决这个问题吗?

标准库时间函数已经知道闰年和一个月中的天数等。因此使用日历“专业知识”是有意义的。

这是我在Algorithm to add or subtract days from a date? 上的回答的“重复”? 但略微修改以删除 C++ 细节(因此不将其标记为重复)。 当然,那里的其他答案可能会有所调整。

#include <time.h>

// Adjust date by a number of days +/-
void DatePlusDays( const struct tm* date, int days )
{
    const time_t ONE_DAY = 24 * 60 * 60 ;

    // Seconds since start of epoch
    time_t date_seconds = mktime( date ) + (days * ONE_DAY) ;

    // Update caller's date
    // Use localtime because mktime converts to UTC so may change date
    *date = *localtime( &date_seconds ) ; ;
}

关于:

我看到人们使用 c 将 x 天添加到日期,但这些问题是用户将他们想要的日期插入到问题中,我的问题是将其添加到当前日期。

所以你肯定只需要提供当前日期作为输入。 无需将解决方案限制得如此不灵活。

“当前日期”的用法示例:

#include <stdio.h>
#include <time.h>

int main( void )
{
    struct tm today ;
    today = *localtime( time(NULL) ) ;

    // Date, plus 30 days
    DatePlusDays( &today, 30 ) ; 

    // Show time/date using default formatting
    printf( "%s\n", asctime( &today) ) ;
}

它也可以用来减去天数(传递负天数)。

当然,如果您真的想将解决方案限制在当前日期:

#include <time.h>

// Adjust date by a number of days +/-
const struct tm* TodayPlusDays( int days )
{
    const time_t ONE_DAY = 24 * 60 * 60 ;

    // Seconds since start of epoch
    time_t date_seconds = time( NULL ) + (days * ONE_DAY) ;

    // Update caller's date
    // Use localtime because mktime converts to UTC so may change date
    return localtime( &date_seconds ) ; ;
}

用法示例:

#include <stdio.h>
#include <time.h>

int main( void )
{
    struct tm today = *TodayPlusDays( 30 ) ;

    // Show time/date using default formatting
    printf( "%s\n", asctime( &today) ) ;
}

假设您已经将日期解析为其组成部分日、月和年。 我们可以用一个非常简单的算法来“增加天数”。 我们甚至可以减去天数(或添加负天数)。

下面没有使用任何标准库来管理日期和时间。 不反对这些解决方案或标准库。 但我想展示一种简单的可移植方式,它使用公历,也考虑到了闰年。

首先是一个指示日期的结构:

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

那么我们需要一个闰年的小帮手。

bool isLeapYear(int year)
{
    // leap years happen on 4 year boundaries unless year is divisible by 100 and not 400
    // 2000 was a leap year, but 2100 is not
    if (year % 400 == 0) return true;
    if (year % 100 == 0) return false;
    return (year % 4 == 0);
}

有了这个用于日期和闰年检测的数据结构 function,我们可以构建一个非常简单的解决方案。 基本算法是“一次增加一天”给定日期,直到达到增加的天数。 每次我们将 day 成员增加到超过一个月的天数时,它都会重置为 1,而 month 成员也会增加。 同样,我们处理递增到下一年。 然后也调整闰年。

// adds "numberOfDays" to the date object pointed to by "d"
void AddDays(Date* d, int numberOfDays)
{
    static const int daysInMonths[]     = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    static const int daysInMonthsLeap[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    const int* monthTable = isLeapYear(d->year) ? daysInMonthsLeap : daysInMonths;

    // handle the case where we are adding a positive number of days to "d"
    while (numberOfDays > 0)
    {
        d->day++;
        if (d->day > monthTable[d->month])
        {
            d->month++;
            if (d->month > 12)
            {
                d->month = 1;
                d->year++;
                monthTable = isLeapYear(d->year) ? daysInMonthsLeap : daysInMonths;
            }
            d->day = 1;
        }
        numberOfDays--;
    }

    // handle the case where we are adding a negative number of days to "d". 
    while (numberOfDays < 0)
    {
        d->day--;
        if (d->day <= 0)
        {
            d->month--;
            if (d->month <= 0)
            {
                d->year--;
                d->month = 12;
                monthTable = isLeapYear(d->year) ? daysInMonthsLeap : daysInMonths;
            }
            d->day = monthTable[d->month];
        }
        numberOfDays++;
    }
}

以上并不是最有效的 - 特别是如果您在给定日期 object 上添加数百万天。但是为了处理少量天数、数周甚至少于几千年的时间调整,您可以做得更糟。 优化构建中的快速基准测试表明,上述方法在将今天的日期增加 500 万天以达到 16000 年及以后的日期时工作得相当快。

在上面的循环中也有很多优化的机会。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM