我们可以从相同类型的范围中获取`std :: chrono :: milliseconds`变量吗?

时间:2017-10-19 08:04:10

标签: c++ chrono

我构建了一个函数,该函数将特定日期作为输入,并以std::chrono::milliseconds格式返回此日期。

milliseconds lowerRangeBound = TimeStamp(mm, dd, HH, MM, SS, yyyy);

例如,

milliseconds a = TimeStamp(8/*month*/, 23/*day*/, 14/*hours*/, 46/*minutes*/, 32/*seconds*/, 2017/*year*/);

以转换后的字符串格式返回:2017.08.23-14.46.32

我现在要做的并且不起作用的是两个日期(milliseconds),以便在这两个日期定义的范围内取一个随机日期。例如,给定

milliseconds a = TimeStamp(8/*month*/, 23/*day*/, 13/*hours*/, 46/*minutes*/, 32/*seconds*/, 2017/*year*/);
milliseconds b = TimeStamp(10/*month*/, 23/*day*/, 13/*hours*/, 46/*minutes*/, 32/*seconds*/, 2017/*year*/);

预期输出是milliseconds c,字符串格式是这样的日期,2017.09.13-12.56.12。请注意,所需的输出为milliseconds,提供字符串格式以便在readable format中发言。

到目前为止,我所尝试的是将每个milliseconds变量转换为long个数字(.count()),并在范围{中获得random long {1}}。但是,输出日期无关紧要:[a,b]

你能帮忙吗?

提前谢谢。

编辑:下面的代码受到link的启发

1977.12.06-16.27.02

2 个答案:

答案 0 :(得分:2)

由于混合问题,你可能会对数学感到困惑。

我建议您以毫秒为单位编写“随机时间戳”例程。

您可以在单独的步骤中执行从/到时间戳的转换。

我会写下这样的例程:

#include<random>
#include<chrono>
#include<cassert>
#include<iostream>

template<class Eng>
std::chrono::milliseconds getRandomTimestamp(Eng& eng, 
                                             std::chrono::milliseconds low, 
                                             std::chrono::milliseconds high) 
{
    // deduce the actual integer type. 
    // Otherwise we'll have to guess what T is when using
    // uniform_int_distribution<T>
    using count_type = decltype(low.count());

    // from this we can deduce the correct integer distribution
    using dist_type = std::uniform_int_distribution<count_type>;

    // create the distribution generator
    auto dist = dist_type(low.count(), high.count());

    // and apply it to the random generator, returning
    // milliseconds somewhere between low and high
    return std::chrono::milliseconds(dist(eng));    
}


int main()
{
    using namespace std::literals;

    std::random_device dev;
    std::default_random_engine eng(dev());

    auto t1 = 10'000'000ms;
    auto t2 = 11'000'000ms;
    auto t3 = getRandomTimestamp(eng, t1, t2);

    assert(t1 <= t3);
    assert(t3 <= t2);

    std::cout << t1.count() << std::endl;
    std::cout << t2.count() << std::endl;
    std::cout << t3.count() << std::endl;
}

答案 1 :(得分:1)

如果您利用Howard Hinnant's free, open-source header-only date/time library,您可以更轻松地做到这一点。语法简洁,可读性强。例如,您可以使用chrono::time_point创建任意精度的milliseconds {(1 {}}。

由于您的问题涉及date::sys_time<std::chrono::milliseconds>而不是time_point,因此从类型安全的角度来看,这是更好的方法。这是写durations的一种方法:

getRandomTimestamp

现在你唯一的问题是如何创建那些#include "date/date.h" #include <iostream> #include <random> date::sys_time<std::chrono::milliseconds> getRandomTimestamp(date::sys_time<std::chrono::milliseconds> lowerBound, date::sys_time<std::chrono::milliseconds> upperBound) { static std::default_random_engine generator; using namespace std::chrono; std::uniform_int_distribution<milliseconds::rep> distribution{ lowerBound.time_since_epoch().count(), upperBound.time_since_epoch().count()}; return date::sys_time<milliseconds>{milliseconds{distribution(generator)}}; } !事实证明这是微不足道的:

time_point

以上int main() { using namespace date::literals; using namespace std::chrono_literals; auto t1 = date::sys_days{2017_y/8/23} + 13h + 46min + 32s; auto t2 = date::sys_days{2017_y/10/23} + 13h + 46min + 32s; auto t3 = getRandomTimestamp(t1, t2); // ... } 只是另一个date::sys_days,但精度为chrono::time_point而不是days(它也可能拼写为milliseconds)。 date::sys_time<date::days>2017_y/8/23类型的文字,意思是2017.08.23。

我利用了C ++ 14的计时文字。如果您使用的是C ++ 11,则需要使用date::year_month_day代替hours{13}

最后,您可以非常轻松地以各种格式格式化和流式传输13h,例如:

t3

这只是我的输出:

std::cout << date::format("%Y.%m.%d-%T", t3) << '\n';

如果您有运行时积分值而不是文字作为输入,那么也很容易处理:

2017.09.04-17:14:04.220

如果您需要从using namespace date; auto t1 = sys_days{year{y}/m/d} + hours{h} + ... 中获取任何字段值,这也很容易,例如:

t3

sys_days sd = floor<days>(t3); time_of_day<milliseconds> tod(t3-sd); year_month_day ymd = sd; 有年,月,日的吸气剂,ymd有吸气剂的小时,分​​钟,秒和毫秒(后者拼写为tod)。