【问题标题】:Adding days to the date in c++在c ++中将日期添加到日期
【发布时间】:2011-11-08 14:24:20
【问题描述】:

我是 C++ 新手,所以我想知道是否有一些库可以帮助更流畅地处理日期。

我有一个相当简单的任务。我有一个不同值的开始日期,当我将日期增加随机天数时,我必须得到它的日期。

我认为mktimetime_t 对象接缝有助于我尝试做的事情。如果他们是答案,有人可以给我一个好的指南的链接吗?

【问题讨论】:

    标签: c++ date


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      一天通常是 86400 秒(leap seconds 除外)。您可以将其添加到time_t 并获得一个新的time_t 等。然后您可以使用mktimelocaltime 将其转换为struct tm,它可以用strftime 显示,也可以用@987654329 解析@

      【讨论】:

      • 不幸的是,直接添加到time_t 不是一个可移植的解决方案,因为不同的库/平台可能对time_t 使用不同的表示(参见cplusplus.com/reference/ctime/time_t)。
      【解决方案3】:

      嗯,有Boost Date and time module。如果您的编译器足够新,则可以使用 C++11 chrono 命名空间。

      【讨论】:

        【解决方案4】:

        我刚刚编写了自己的函数来将 Days、Months 和 Years 添加到现有的 DATE 类中。我还不能测试它,但也许它有帮助:

        bool DATE::add(int Day, int Month, int Year){
        int DaysPerMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        this -> Day += Day;
        while(this -> Day > DaysPerMonth[ this-> Month ]){
            if((this -> Year % 4 == 0 && this -> Year % 100 != 0) || this -> Year % 400 == 0){
                DaysPerMonth[2] = 29; 
            }
            this -> Day -= DaysPerMonth[ this-> Month ];
            this -> Month++;
            if(this -> Month > 12){
                this -> Month = 1;
                this -> Year++;
            } 
        }
        this -> Month   = ( this -> Month + (Month % 12));
        this -> Year    = ( this -> Year + Year + (Month/12));
        if((this -> Year % 4 == 0 && this -> Year % 100 != 0) || this -> Year % 400 == 0){
            DaysPerMonth[2] = 29;   
            // check pathologic case wether date is 1 of March and added Year targets switchyear 
            if( this -> Day == 1 && this -> Month == 3){            
                this -> Day = 29;
                this -> Month = 2;
            }
        }
        if(this -> Month < 1 || this -> Month > 12 || this -> Day < 1 || this -> Day > DaysPerMonth[this->Month]){  
            valid = false;
            cerr << "something went wrong, calculated Date is: " << this -> Day << "."<< this -> Month << "." << this -> Year << endl << flush;
            return false;
        }else{
            return true;
        }
        

        }

        【讨论】:

          【解决方案5】:

          一个十年前的问题的新答案,因为时代变了,工具也变得更好了。

          在 C++20 中,日期可以用几种不同的简洁有用的方式表示。

          • std::chrono::sys_days
          • std::chrono::year_month_day
          • std::chrono::year_month_weekday

          (这不是一个详尽的列表)

          上面的每个数据结构都代表一个日期,但各有优缺点,就像我们有几种容器类型表示一系列值(vectorlistdeque 等)各有优缺点.

          要为日期添加天数,sys_days 显然是日期表示的最佳选择。 sys_days 只不过是自 1970-01-01 以来(或之前)的天数。它是一个类型别名:

          time_point<system_clock, days>
          

          其中daysstd::chrono::duration

          duration&lt;至少 25 位的有符号整数类型, ratio_multiply&lt;ratio&lt;24&gt;, hours::period&gt;&gt;

          因此,将days 添加到sys_days 只是底层的积分运算。

          C++20 允许在{year, month, day} 概念和sys_days 之间进行无缝转换。所以这看起来像:

          sys_days tp = sys_days{January/30/2022} + days{400};  // tp = 2023-03-06
          

          积分可以用作上述公式的输入。但是,在使用 &lt;chrono&gt; 时,最好尝试保持在 &lt;chrono&gt; 的强类型系统中。:

          int y = 2022;
          int m = 1;
          int d = 30;
          int num_days = 400;
          sys_days tp = sys_days{month(m)/d/y} + days{num_days};  // tp = 2023-03-06
          

          无论如何,只需将tp 打印出来即可轻松观察到:

          cout << tp << '\n';
          

          输出:

          2023-03-06
          

          还提供其他格式选项,并且还可以通过编程方式访问年、月和日的值。最好将这些值保留在 chrono 强类型 yearmonthday 中,但也可以转换为整数类型。

          【讨论】:

            【解决方案6】:

            使用标准ctime 标头的可移植方法是使用localtime()(或gmtime() 使用UTC 时间)构造一个mt 结构。然后,将天数添加到 tm_day 成员并使用 mktime() 将结构转换回时间。

            tm_day 成员代表一个月中的某天,但mktime 允许它超过一个月的天数,甚至允许它为负值,以防需要减法 em> 从日期算起的天数,因此您不必担心换行。

            一个例子:

            #include <ctime>
            
            time_t add_days(const time_t& time_value, int days) {
              tm tm_value = *localtime(&time_value);
              tm_value.tm_mday += days;
              return mktime(&tm_value);
            }
            

            此方法的缺点可能是标准库可能无法以线程安全的方式实现localtime()。这可以通过使用 localtime_r() 来解决,但移植性较差。

            【讨论】:

              猜你喜欢
              • 2010-11-28
              • 2011-10-15
              • 2017-01-06
              • 2023-03-08
              • 1970-01-01
              • 2011-08-31
              • 2010-10-08
              • 1970-01-01
              相关资源
              最近更新 更多