C++ добавить 1 год до даты
Вот как я создаю свою дату, я хочу добавить к ней 1 год. Заранее спасибо.
char tmpbuf[128];
time_t ltime;
struct tm *today;
stringstream reD;
string todayDate;
time( <ime );
today = localtime( <ime );
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( <ime );
Вы должны будете принять во внимание определенные аномалии, такие как увеличение года с 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 год.