【问题标题】:Coming dates in C++C++ 中的即将到来的日期
【发布时间】:2022-01-06 00:21:48
【问题描述】:

我有以下代码,我用它得到今天的日期。我想知道是否可以从这段代码中获得 6 个月和 12 个月后的日期。或者我怎样才能得到这些日期?

谢谢!

#include <iostream>
#include <ctime>

using namespace std;

int main() {
    time_t hoy = time(0);
    char* fecha = ctime(&hoy);
    
    cout << "La fecha es: " << fecha << endl;
}

我尝试制作一个程序,让用户计划某些植物的受精期,这就是为什么我尝试让程序打印从今天起接下来的 6 个月和 12 个月的日期(嗯,从用户注册工厂之日起)。到目前为止,我还没有成功。 :(

【问题讨论】:

  • 你知道localtime()怎么用吗?
  • 是的,这肯定会持续 +/- 6 个月。只需添加该秒数。
  • 定义“6 个月后”。那是6 * 30天吗?那是一个月的同一天,提前 6 个月,比如 3/22 到 9/22?
  • 现代 C++ 中处理时间的方法是改用std::chrono
  • 非常相似的问题有几个不同的答案,所有答案都是正确的:stackoverflow.com/q/43010362/576911

标签: c++ time ctime


【解决方案1】:

如果您希望从给定日期算起 6 个月,计算月数而不是天数,解决方案是拆分日期并手动增加月数和年数。然后你将不得不调整年份换行和月份换行。

这些函数在 C89/C99 中定义,因此不特定于 Posix。

此解决方案的最大优点是您不必链接任何外部库。它应该可以在 Linux、Mac 甚至 Windows/MS Visual Studio 上与您的编译器一起使用。

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

time_t add_months( time_t from_date, uint32_t months ) {
    // Split date
    struct tm* tmptr = ::gmtime( &from_date );
    if ( tmptr == nullptr ) return 0;
    struct tm date = *tmptr;

    // Save original date
    struct tm org = date;

    // Add months/years
    uint32_t years = months/12;
    months = months % 12;
    date.tm_year += years;
    date.tm_mon += months;

    // Correct for year wrap
    if ( date.tm_mon>11 ) { 
        date.tm_mon -= 12;
        date.tm_year += 1;
    }

    // Convert back to time_t
    time_t dt = mktime( &date );

    // Check for end of month wrap
    // eg Jan/30 -> Mar/02 -> Feb/28
    if ( date.tm_mday != org.tm_mday ) {
        dt -= date.tm_mday * 86400;
    }
    return dt;
}

int main() {
    time_t now = time(nullptr);
    time_t later = add_months( now, 6 );

    struct tm* tmptr = ::gmtime( &now );
    if ( tmptr!=nullptr ) {
        printf( "Now: %s\n", asctime(tmptr));
    }
    tmptr = ::gmtime( &later );
    if ( tmptr!=nullptr ) {
        printf( "Later: %s\n", asctime(tmptr));
    }
}

结果:

Program stdout
Now: Thu Jan  6 01:47:07 2022
Later: Wed Jul  6 01:47:07 2022

天箭:https://godbolt.org/z/vE4xhsP3E

【讨论】:

  • 哇。这按我的预期工作。感谢大家的贡献! :D
  • @ArturoGarcíaFlores 仔细检查这是您期望的月底包装的行为 - 如果您通过 Jan 30 并添加一个月,它将转到 Feb 30thmktime() 将更正为March 2nd。然后你减去 2 天回到Feb 28th
【解决方案2】:

由于您的用例似乎只需要对未来日期的粗略估计,因此您可能只需假设每个月大约有 30.4 天,然后计算未来的秒数即可基于此。然后,您可以使用 ctime() 为该未来时间生成一个新的日期字符串:

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

int main(int argc, const char ** argv)
{
   const time_t now = time(NULL);

   // Assuming every month has ~30.4 days; that's not really true
   // but it's close enough for plant fertilization purposes, I think
   const time_t ROUGHLY_ONE_MONTH_IN_SECONDS = (30*24*60*60) + (10*60*60);

   for (int i=0; i<=12; i++)
   {
      const time_t then = (now+(i*ROUGHLY_ONE_MONTH_IN_SECONDS));
      printf("In %i months, the approximate date/time will be:  %s", i, ctime(&then));
   }

   return 0;
}

请注意,对于准确的答案,您需要考虑不同的月份长度,加上闰年和只有上帝知道的其他情况,在这种情况下,您' d 使用现代日期/时间库可能会更好。

【讨论】:

    【解决方案3】:

    我会使用struct tm 并使用gmtime 转换您的time_t

    然后您可以将612 添加到tm_mon(不要忘记通过在tm_year 中添加1 来处理溢出),然后使用mktime 转换回time_t

    【讨论】:

    • 有一种情况,你通过Jan 31st,你给不存在的Jun 31st加了6个月。然后mktime() 将转换为July 1st,您必须将其推回Jun 30th
    【解决方案4】:

    试试 Boost 日期时间库?易于使用,无需学习时间转换或其他任何东西,专注于您想做的事情。

    #include "boost/date_time/gregorian/gregorian.hpp"
    #include <iostream>
    #include <string>
    
    int
    main(int argc, char* argv[])
    {
    
        using namespace boost::gregorian;
    
        try {
            //Read ISO Standard(CCYYMMDD) and output ISO Extended
            std::string ud("20011009"); //2001-Oct-09
            date d1(from_undelimited_string(ud));
            std::cout << "date is="<<to_iso_extended_string(d1) << std::endl;
            {
                boost::gregorian::months monthObj(6);
                date d2(d1 + monthObj);
                std::cout << "date  6 month later is=" << to_iso_extended_string(d2) << std::endl;
            }
            {
                boost::gregorian::months monthObj(12);
                date d2(d1 + monthObj);
                std::cout << "date  12 month later is=" << to_iso_extended_string(d2) << std::endl;
            }
        }
        catch (std::exception& e) {
            std::cout << "  Exception: " << e.what() << std::endl;
        }
    
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多