我将每个日期都放在struct (vector<value>)
的向量中:
struct value {
string code;
string date;
string name;
};
日期格式为“YYYY-MM-DD HH:MM:SS”
我希望在两个给定日期之间获取日期(例如2016年1月1日至2016年2月1日)。我怎么能这样做?
答案 0 :(得分:2)
日期格式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返回true,就会从u
开始将元素隐藏到u.begin()
中。它们的顺序与你给它们的顺序相同。
如果您的范围已排序,则可以使用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
,的第一个值 {{1} }},以便范围to
是值为[lb, ub[
的范围。
答案 1 :(得分:1)
在示例中,您可以这样做:将所有日期转换为time_t
值(日期和时间的数字表示),然后迭代矢量并使用三个time_t数字之间的正常比较。供参考:man mktime
,man strptime
。
答案 2 :(得分:1)
这个问题有两个方面:
从日期字符串
中查找有效时间戳C ++使用time_t对象作为设定日期(1970年1月1日)There's plenty of concise information about that的有效秒数,在每种情况下,您可以将其视为以秒为单位的整数表示。
接下来,您需要知道如何将数据解析为时间戳:这里有一些相当有用的链接。
我首选的方法是mktime - 这是Here on stack-overflow的一个例子。它也是seems someone else has done the same course as you ;)
如果日期格式不正常,您可能需要考虑使用A function of your own design。在这种情况下,使用scanf通常是最简单的方法 - 这个函数的界面有些老派“c风格”,但这并没有改变它运作的简单事实,而且很好。 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';
}
}
注意: