C++ добавить 1 год до даты

Вот как я создаю свою дату, я хочу добавить к ней 1 год. Заранее спасибо.

char tmpbuf[128];
time_t ltime;
struct tm *today;
stringstream reD;
string todayDate;
time( &ltime );
today = localtime( &ltime );
strftime( tmpbuf, 128,"%Y-%m-%d_%H:%M:%S", today );
reD << tmpbuf;
reD >> todayDate;
boost::replace_all(todayDate, "_", " ");
cout << todayDate << endl;

ОК, я решил пойти с повышением, так как будет легче добавить дни, так что 2 примера мне нужно один добавить 1 год, а один добавить 14 дней, вот что у меня так дорого

 #include "boost/date_time.hpp"
 #include "boost/date_time/local_time/local_time.hpp"

 using namespace boost::posix_time;
 using namespace boost::local_time;

 int main(){
    local_date_time t = local_sec_clock::local_time(time_zone_ptr());
    local_time_facet* lf(new local_time_facet("%Y-%m-%d_%H:%M:%S"));
    std::cout.imbue(std::locale(std::cout.getloc(), lf));
    std::cout << t << std::endl;
    return 0;
 }

Изменить время в строке

 stringstream reD;
 reD.imbue(locale(reD.getloc(), lf));
 reD << t;
 bthis = reD.str();
 cout << bthis << endl;

4 ответа

Решение

Я согласен с использованием boost::date_timeОднако решение здесь довольно простое.

today->tm_year++;

Хотя, если вы снова вызовете localtime, значение будет перезаписано, поэтому вам следует сделать копию. Делать today экземпляр вместо указателя и разыменование возвращаемого значения localtime следующим образом:

today = *localtime( &ltime );

Вы должны будете принять во внимание определенные аномалии, такие как увеличение года с 29 февраля в високосный год.

Изменить: я вижу, вы решили использовать boost::date_time в конце концов. Это делает вещи намного проще. Вот как вы добавляете год:

t += boost::gregorian::years(1);

И вот как вы добавляете 14 дней:

t += boost::gregorian::days(14);

Или же

t += boost::gregorian::weeks(2);

Если вы используете C++, я настоятельно рекомендую boost::date_time, чтобы избавиться от этого.

Нет такой вещи как "добавление года".

Давайте предположим, что вы увеличиваете год на 1, в конце концов, это то, к чему вы стремитесь.

К сожалению, в том, как мы справляемся со временем, есть некоторые несоответствия:

  • високосные годы: если вы находитесь на 29 февраля 2008 года, что означает добавление года? 28 февраля 2009 или 1 марта 2009? (Подсказка: смена месяца очень сбивает с толку пользователя календаря)

  • високосные секунды: 30 июня или 31 декабря можно добавить секунду или две к последней минуте, сделав эту минуту 61 или 62 секунды. Это абсолютно противоречиво, и, к счастью, теперь от него отказались, но оно затронуло годы с 1972 по 2008 год. (Подсказка: еще раз, изменение дня сбивает с толку)

  • специальные события: например, перенастройка календаря, произошедшая в 1582 году, когда за четвергом, 4 октября 1582 года, последовала пятница, 15 октября 1582 года, что привело к полной потере в 10 дней.

Проблема здесь не в том, чтобы "добавить" год, вы всегда можете выбрать округление (предпочтительно, когда участвуют конечные пользователи) или увеличение. Реальная проблема заключается в том, что если вы будете следовать этим рассуждениям, вы, к сожалению, потеряете симметрию между добавлением и удалением года:

  • оригинал: 29 февраля 2008 г.
  • + 1 год: 1 марта 2009 г. (округление)
  • - 1 год: 1 марта 2008 г.

или добавив 4 года в несколько последовательных скачков:

  • оригинал: 29 февраля 2008 г.
  • + 2 года: 28 февраля 2010 года (округление вниз)
  • + 2 года: 28 февраля 2012

Oups!

Математическое решение этого состоит в том, чтобы просто оценить продолжительность года в секундах. Давайте спросим об этом у Вольфрама: 3,154 × 10^7 секунд.

Тем не менее, это может быть довольно запутанным для пользователя.

И, наконец, последнее решение заключается в том, что всякий раз, когда вы производите вычисления на основе дат и длительности, вы сохраняете исходную дату, вычисляете длительности самостоятельно, а затем корректируете "отображаемую" дату.

Таким образом, вы будете как математически корректны (т.е. уважать симметрию и ассоциативность), так и вести себя интуитивно для конечных пользователей.

class MyTime {
  ...
private:
  tm _origin;
  tm _deviation;
};

Тем не менее, это больше работы... так что вам придется самостоятельно выбирать схему, в зависимости от потребностей вашего приложения.

О боже, вы, C++ люди:)

// compare June 15 2018 - 2017 to 2017 - 2016
struct tm y1_tm, y2_tm, y3_tm;
time_t y1716, y1817;  // differences

y1_tm.tm_sec = 0;  // 2016
y1_tm.tm_min = 0;
y1_tm.tm_hour = 0;
y1_tm.tm_mon = 6;
y1_tm.tm_mday = 15;
y1_tm.tm_year = 2016 - 1900;
y1_tm.tm_mday = 1;

y2_tm.tm_sec = 0;  // 2017
y2_tm.tm_min = 0;
y2_tm.tm_hour = 0;
y2_tm.tm_mon = 6;
y2_tm.tm_mday = 15;
y2_tm.tm_year = 2017 - 1900;
y2_tm.tm_mday = 1;

y3_tm.tm_sec = 0;  // 2018
y3_tm.tm_min = 0;
y3_tm.tm_hour = 0;
y3_tm.tm_mon = 6;
y3_tm.tm_mday = 15;
y3_tm.tm_year = 2018 - 1900;
y3_tm.tm_mday = 1;

y1716 = mktime(&y2_tm) - mktime(&y1_tm);  // 2017 - 2016
y1817 = mktime(&y3_tm) - mktime(&y2_tm);  // 2018 - 2017

Оба вычитания дают 31536000 секунд. Добавьте это к time_t на 1 год.

Другие вопросы по тегам