C ++ добавить 1 год до даты - PullRequest
1 голос
/ 09 декабря 2011

Вот так я создаю свою дату, я хочу добавить к ней 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 ]

5 голосов
/ 09 декабря 2011

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

3 голосов
/ 09 декабря 2011

Я согласен с использованием 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);
2 голосов
/ 10 декабря 2011

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

Давайте предположим, что вы увеличиваете год на 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;
};

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

0 голосов
/ 30 июля 2018

О боже, вы, люди 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 год.

...