Я видел примеры для С#, Java, но для С++ я не могу найти решение, чтобы вычислить, сколько дней между двумя датами.
Например, между 24 января 2012 г. и 08 января 2013 г.
Спасибо!
Я видел примеры для С#, Java, но для С++ я не могу найти решение, чтобы вычислить, сколько дней между двумя датами.
Например, между 24 января 2012 г. и 08 января 2013 г.
Спасибо!
Это один из способов.
#include <iostream>
#include <ctime>
int main()
{
struct std::tm a = {0,0,0,24,5,104}; /* June 24, 2004 */
struct std::tm b = {0,0,0,5,6,104}; /* July 5, 2004 */
std::time_t x = std::mktime(&a);
std::time_t y = std::mktime(&b);
if ( x != (std::time_t)(-1) && y != (std::time_t)(-1) )
{
double difference = std::difftime(y, x) / (60 * 60 * 24);
std::cout << std::ctime(&x);
std::cout << std::ctime(&y);
std::cout << "difference = " << difference << " days" << std::endl;
}
return 0;
}
Thu Jun 24 01:00:00 2004
Mon Jul 05 01:00:00 2004
difference = 11 days
Вот ссылка на исходное сообщение автора а>
12:0:0
для времени, не 0:0:0
.) И, конечно же, порядок элементов в struct tm
не указан; вам нужно что-то вроде std::tm a; a.tm_year = 104; a.tm_mon = 5; a.tm_mday = 24; a.tm_hour = 12;
.
- person James Kanze; 08.01.2013
August 15, 1979
и June 15, 2018
, это даст мне 14182
, что составляет 2
дней меньше. Правильное количество дней 14184
. Я постараюсь это исправить.
- person chankruze; 29.08.2020
Преобразуйте свои даты в целое число, обозначающее количество дней, прошедших с эпохи, а затем вычтите. В этом примере я выбрал Rata Die, объяснение алгоритма можно найти по адресу ‹http://mysite.verizon.net/aesir_research/date/rata.htm>.
int
rdn(int y, int m, int d) { /* Rata Die day one is 0001-01-01 */
if (m < 3)
y--, m += 12;
return 365*y + y/4 - y/100 + y/400 + (153*m - 457)/5 + d - 306;
}
int days = rdn(2013, 1, 8) - rdn(2012, 1, 24);
(153*m - 457)/5 + d - 306
?
- person immiao; 28.01.2017
(153 * m - 457)/5
вычисляет количество предыдущих дней сдвинутого месяца. Между 1 марта нулевого года и 31 декабря 306 дней.
- person chansen; 07.03.2017
Новый ответ на старый вопрос:
Используя эту библиотеку дат только для заголовков C++11/C++14, вы можете теперь пиши:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
auto x = 2012_y/1/24;
auto y = 2013_y/1/8;
cout << x << '\n';
cout << y << '\n';
cout << "difference = " << (sys_days{y} - sys_days{x}).count() << " days\n";
}
Что выводит:
2012-01-24
2013-01-08
difference = 350 days
Если вы не хотите зависеть от этой библиотеки, вы можете написать свою собственную, используя те же алгоритмы дат, которые использует указанная выше библиотека дат. Они находятся в этой статье: хроносовместимые низкоуровневые алгоритмы дат. Алгоритм из этой статьи, который используется в этом примере, таков:
// Returns number of days since civil 1970-01-01. Negative values indicate
// days prior to 1970-01-01.
// Preconditions: y-m-d represents a date in the civil (Gregorian) calendar
// m is in [1, 12]
// d is in [1, last_day_of_month(y, m)]
// y is "approximately" in
// [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
// Exact range of validity is:
// [civil_from_days(numeric_limits<Int>::min()),
// civil_from_days(numeric_limits<Int>::max()-719468)]
template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
static_assert(std::numeric_limits<unsigned>::digits >= 18,
"This algorithm has not been ported to a 16 bit unsigned integer");
static_assert(std::numeric_limits<Int>::digits >= 20,
"This algorithm has not been ported to a 16 bit signed integer");
y -= m <= 2;
const Int era = (y >= 0 ? y : y-399) / 400;
const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365]
const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
return era * 146097 + static_cast<Int>(doe) - 719468;
}
См. раздел хроносовместимые низкоуровневые алгоритмы дат, чтобы узнать, как работает этот алгоритм, и его модульные тесты. , и диапазон его действия.
Этот алгоритм моделирует пролептический григорианский календарь, который бесконечно расширяет григорианский календарь как вперед, так и назад. Для моделирования других календарей (например, юлианского календаря) вам потребуются другие алгоритмы, таких, как показанные здесь. Как только вы настроите другие календари и синхронизируете их с той же последовательной эпохой (эти алгоритмы используют 1970-01-01 по григорианскому календарю, который также является время Unix эпоха), вы можете легко вычислить количество дней не только между любыми двумя датами, но и между любыми двумя смоделированными вами календарями.
Это дает вам свободу и избавляет от необходимости жестко кодировать дату перехода с юлианского на григорианский. Вам просто нужно знать, на какой календарь ссылаются ваши входные данные.
Иногда даты в исторических документах, которые в противном случае могли бы быть двусмысленными, снабжены аннотациями старый/новый стиль для укажите юлианский или григорианский календарь соответственно.
Если вас также беспокоит время суток с вашими датами, эта одинаковая библиотека дат легко интегрируется с библиотекой <chrono>
для использования hours
, minutes
, seconds
, milliseconds
, microseconds
и nanoseconds
и с system_clock::now()
для получения текущей даты и времени.
Если вас беспокоят часовые пояса, поверх написана дополнительная (отдельная) библиотека часовых поясов из библиотеки дат для обработки часовых поясов с помощью база данных часовых поясов IANA. При необходимости библиотека часовых поясов также имеет средства для вычислений, включающих високосные секунды.
Чтобы не создавать собственную функцию, вы можете использовать date_time от Boost.
(date1 - date2).to_days();
или даже с использованием C++11 и соответствующего кода("2012-01-24"_date - "2013-01-08"_date).to_days();
- person Geoffroy   schedule 08.01.2013