C++ 获取两个日期之间的日期
C++ get dates between two dates
我把每个日期都放在一个结构向量中 (vector<value>)
:
struct value {
string code;
string date;
string name;
};
日期格式为"YYYY-MM-DD HH:MM:SS"
我想获取两个给定日期之间的日期(例如从 01/01/2016 到 01/02/2016)。我该怎么做?
在示例中,您可以这样做:将所有日期转换为 time_t
值(日期和时间的数字表示),然后遍历向量并使用三个 time_t 数字之间的正常比较.供参考:man mktime
, man strptime
.
这个问题是双重的:
- 如何从字符串表示中获取可排序的日期值
- 如何有效地对所述值进行排序。
从 date-string
中查找有效时间戳
C++ 使用 time_t 对象作为从设定日期(UTC 时间 1970 年 1 月 1 日)开始的有效秒数 There's plenty of concise information about that,在 every-case 中你可以认为这是一个 Integer-representation 以秒为单位的时间。
接下来您需要了解如何将数据解析为 time-stamp:这里有一些非常有用的链接。
我的首选方法是mktime - there's an example of that Here on stack-overflow. Also it seems someone else has done the same course as you ;)
您可能要考虑使用 A function of your own design, if the date format is unusual. In this case, using scanf 通常是最简单的方法 - 此函数的接口有点 old-school "c-style",但这并没有改变它的简单事实工作,很好。
Here's a link to someone reading a simple-date with scanf.
原来我下面写的代码接近The answer to this great question
#include <stdio.h>
#include <time.h>
time_t GetDateFromObject(value & Date_Object)
{
char * Date_String = Date_Object.date.c_str();
int year, month, day, hour, minute, second;
if(sscanf(Date_String , "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second) == 6)
{
time_t rawTime;
time(&rawTime);
struct tm * parsedTime;
parsedTime = localtime(&rawTime);
// tm_year is years since 1900
parsedTime->tm_year = year - 1900;
// tm_months is months since january
parsedTime->tm_mon = month - 1;
parsedTime->tm_mday = day;
parsedTime->tm_hour = hour;
parsedTime->tm_min = minute;
parsedTime->tm_sec = second;
return mktime(parsedTime);
}
}
日期的关联与排序
一旦您知道如何从您的约会中获取 time_t,您就可以开始创建数据的关联数组 - 在这种情况下,我将使用 map.
下面是一个使用地图插入、排序和输出数据的示例。
#include<iostream>
#include<map>
#include<vector>
#include<ctime>
struct value {
std::string code;
std::string date;
std::string name;
};
void Print_Range(std::vector<value> & Data, value & Date_Start, value & Date_end)
{
std::map<time_t, value *> Associated_Data;
for(auto Date_Object : Array_Of_Dates)
{
time_t Object_Time = GetDateFromObject(Date_Object);
Associated_Data.insert(std::make_pair(Object_Time, & Date_Object);
}
//as the std::map is sorted by-default,
//we can know locate the iterator for any two time codes
time_t Search_From = GetDateFromObject(Date_Start);
time_t Search_To = GetDateFromObject(Date_End);
auto Start_IT = Associated_Data.find(Search_From);
auto End_IT = Associated_Data.find(Search_To);
std::cout << "Printing all dates in range \n";
for(auto IT=Start_IT; IT != End_IT; IT++)
{
std::cout << IT->Second->date << '\n';
}
}
备注:
- 我在这里使用 C++11 语法,如果你不理解 Range based loops 你可能想阅读它们。
- 我假设您描述的结构存储在 vector.
中
- 我在这里使用的 "GetDateFromObject" 函数是您用来获取时间戳的任何函数的占位符)
- Inserting data into a map using std::make_pair.
- 我持有指向原始 value-objects 的指针。
日期格式YYYY-MM-DD HH:MM:SS
的特殊之处在于字典顺序(逐个字母)比较与时间比较相同,因此您可以直接使用它。
如果您的容器最初没有按日期排序,您将不得不一个一个地检查所有日期。 std::copy_if
提供了一种很好的方法:
std::vector<value> get_between(const std::vector<value>& v,
const std::string& from, const std::string& to)
{
std::vector<value> u;
std::copy_if(v.begin(), v.end(), std::inserter(u, u.begin()),
[from,to](const auto& val) {
return val.date >= from && val.date <= to;
});
return u;
}
copy_if
遍历 [v.begin(), v.end()[
并在 lambda returns 为真时从 u.begin()
开始将元素插入 u
。它们的顺序与您输入的顺序相同。
如果您的范围已排序,您可以使用 std::lower_bound
和 std::upper_bound
来获取开始和结束迭代器:
std::vector<value> get_between(const std::vector<value>& v,
const std::string& from, const std::string& to)
{
value fromv { "", from, "" };
auto begin = std::lower_bound(v.begin(), v.end(), fromv,
[](const auto& lhs, const auto& rhs) {
return lhs.date < rhs.date;
});
value tov { "", to, "" };
auto end = std::upper_bound(begin, v.end(), tov,
[](const auto& lhs, const auto& rhs) {
return lhs.date < rhs.date;
});
return std::vector<value>(begin, end);
}
lower_bound
和upper_bound
求出的第一个值至少from
和的第一个值大于 to
,因此范围 [lb, ub[
是值为 [from, to]
.
的范围
我把每个日期都放在一个结构向量中 (vector<value>)
:
struct value {
string code;
string date;
string name;
};
日期格式为"YYYY-MM-DD HH:MM:SS"
我想获取两个给定日期之间的日期(例如从 01/01/2016 到 01/02/2016)。我该怎么做?
在示例中,您可以这样做:将所有日期转换为 time_t
值(日期和时间的数字表示),然后遍历向量并使用三个 time_t 数字之间的正常比较.供参考:man mktime
, man strptime
.
这个问题是双重的:
- 如何从字符串表示中获取可排序的日期值
- 如何有效地对所述值进行排序。
从 date-string
中查找有效时间戳C++ 使用 time_t 对象作为从设定日期(UTC 时间 1970 年 1 月 1 日)开始的有效秒数 There's plenty of concise information about that,在 every-case 中你可以认为这是一个 Integer-representation 以秒为单位的时间。
接下来您需要了解如何将数据解析为 time-stamp:这里有一些非常有用的链接。
我的首选方法是mktime - there's an example of that Here on stack-overflow. Also it seems someone else has done the same course as you ;)
您可能要考虑使用 A function of your own design, if the date format is unusual. In this case, using scanf 通常是最简单的方法 - 此函数的接口有点 old-school "c-style",但这并没有改变它的简单事实工作,很好。 Here's a link to someone reading a simple-date with scanf.
原来我下面写的代码接近The answer to this great question
#include <stdio.h>
#include <time.h>
time_t GetDateFromObject(value & Date_Object)
{
char * Date_String = Date_Object.date.c_str();
int year, month, day, hour, minute, second;
if(sscanf(Date_String , "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second) == 6)
{
time_t rawTime;
time(&rawTime);
struct tm * parsedTime;
parsedTime = localtime(&rawTime);
// tm_year is years since 1900
parsedTime->tm_year = year - 1900;
// tm_months is months since january
parsedTime->tm_mon = month - 1;
parsedTime->tm_mday = day;
parsedTime->tm_hour = hour;
parsedTime->tm_min = minute;
parsedTime->tm_sec = second;
return mktime(parsedTime);
}
}
日期的关联与排序
一旦您知道如何从您的约会中获取 time_t,您就可以开始创建数据的关联数组 - 在这种情况下,我将使用 map.
下面是一个使用地图插入、排序和输出数据的示例。
#include<iostream>
#include<map>
#include<vector>
#include<ctime>
struct value {
std::string code;
std::string date;
std::string name;
};
void Print_Range(std::vector<value> & Data, value & Date_Start, value & Date_end)
{
std::map<time_t, value *> Associated_Data;
for(auto Date_Object : Array_Of_Dates)
{
time_t Object_Time = GetDateFromObject(Date_Object);
Associated_Data.insert(std::make_pair(Object_Time, & Date_Object);
}
//as the std::map is sorted by-default,
//we can know locate the iterator for any two time codes
time_t Search_From = GetDateFromObject(Date_Start);
time_t Search_To = GetDateFromObject(Date_End);
auto Start_IT = Associated_Data.find(Search_From);
auto End_IT = Associated_Data.find(Search_To);
std::cout << "Printing all dates in range \n";
for(auto IT=Start_IT; IT != End_IT; IT++)
{
std::cout << IT->Second->date << '\n';
}
}
备注:
- 我在这里使用 C++11 语法,如果你不理解 Range based loops 你可能想阅读它们。
- 我假设您描述的结构存储在 vector. 中
- 我在这里使用的 "GetDateFromObject" 函数是您用来获取时间戳的任何函数的占位符)
- Inserting data into a map using std::make_pair.
- 我持有指向原始 value-objects 的指针。
日期格式YYYY-MM-DD HH:MM:SS
的特殊之处在于字典顺序(逐个字母)比较与时间比较相同,因此您可以直接使用它。
如果您的容器最初没有按日期排序,您将不得不一个一个地检查所有日期。 std::copy_if
提供了一种很好的方法:
std::vector<value> get_between(const std::vector<value>& v,
const std::string& from, const std::string& to)
{
std::vector<value> u;
std::copy_if(v.begin(), v.end(), std::inserter(u, u.begin()),
[from,to](const auto& val) {
return val.date >= from && val.date <= to;
});
return u;
}
copy_if
遍历 [v.begin(), v.end()[
并在 lambda returns 为真时从 u.begin()
开始将元素插入 u
。它们的顺序与您输入的顺序相同。
如果您的范围已排序,您可以使用 std::lower_bound
和 std::upper_bound
来获取开始和结束迭代器:
std::vector<value> get_between(const std::vector<value>& v,
const std::string& from, const std::string& to)
{
value fromv { "", from, "" };
auto begin = std::lower_bound(v.begin(), v.end(), fromv,
[](const auto& lhs, const auto& rhs) {
return lhs.date < rhs.date;
});
value tov { "", to, "" };
auto end = std::upper_bound(begin, v.end(), tov,
[](const auto& lhs, const auto& rhs) {
return lhs.date < rhs.date;
});
return std::vector<value>(begin, end);
}
lower_bound
和upper_bound
求出的第一个值至少from
和的第一个值大于 to
,因此范围 [lb, ub[
是值为 [from, to]
.