带有 TZ 的时间的 C++ 结构,但没有日期?
C++ structure for time with TZ, but without date?
C++ std::chrono 规范中是否有任何结构来表示时间和时区,但没有日期?问题是我希望能够过滤具有 unix 时间 (time_t) 的记录,以及 return 所有时间在“10:00 EST”和“11:00 EST”之间的记录。这需要将 time_t 转换为 EST,剥离时间,然后将其与“时间”结构进行比较。
C 库函数 localtime
(在 C++ 代码中完全可用)采用 a(指向 a 的指针)time_t
和 returns a(指向 a 的指针)struct tm
具有日期和时间值。
但是,没有法律规定您必须以某种方式使用它的日期部分。您可以忽略它们,只查看小时、分钟和秒值。
C++20 引入了对 chrono 的时区支持。它尚未发货,但有 free, open-source preview library. It does require some installation for the time zone support.
{time-of-day, time_zone}
没有现成的数据结构。但是,您可以通过将一天中的时间存储为 chrono::duration
(比如 seconds
?)和 chrono::time_zone const*
(date::time_zone const*
在 preview lib ).
#include "date/tz.h"
#include <chrono>
#include <ctime>
#include <iostream>
struct my_event
{
date::time_zone const* tz;
std::chrono::seconds tod;
};
std::ostream&
operator<<(std::ostream& os, const my_event& e)
{
return os << date::format("%T ", e.tod) << e.tz->name();
}
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
time_t t = 1609186734;
zoned_time zt{"America/New_York", sys_seconds{seconds{t}}};
auto local_time = zt.get_local_time();
auto tz = zt.get_time_zone();
my_event e{tz, local_time - floor<days>(local_time)};
cout << e << '\n';
}
输出:
15:18:54 America/New_York
至少在我看来,Howard Hinnant 在这里给出了几乎正确的答案(如果他不是那么谦虚,他可能会指出他定义并实现了对他提到的标准)。
特别是,要确定一天中的时间(至少大多数地方都是如此),我们必须首先计算出一年中的第几天,因为许多(大多数?)地方每隔一小时就会改变一个小时一年几次(在 spring 的某个时间向前一个小时,在秋天的某个时间向后一个小时)。所以,要做好这项工作,我们基本上别无选择,只能考虑日期。
目前,假设我们可以忽略时间的变化。当我们这样做的时候,我们还假设我们有一个类似于 POSIX 的 time_t(即,它是自 1970 年 1 月 1 日午夜以来的整数秒数。而且由于大多数人付给他们的钱很少无论如何,我还假设我们可以忽略自 1970 年以来插入的闰秒(如果我没记错的话,其中有 27 个)。
在这种情况下,我们可以简单地将一天视为24小时。 24 hours/day * 60 minutes/hour * 60 seconds/minute 给我们 86'400 seconds/day。所以,some_time_t % 86'400 给了我们当天的偏移量(以秒为单位)。
10 AM 是午夜过后 10 小时,因此偏移量为 10 小时 * 60 minutes/hour * 60 seconds/minute = 36'000 秒。上午 11 点是 11 小时 * 60 * 60 = 39'600 秒。
因此,对于这个大大简化的时间模型,我们将问题简化为:
bool in_range(time_t input) {
int offset = input % 86'400;
return offset >= 36'000 && offset < 39'600;
}
从理论上讲,您至少可以添加一些我们到目前为止有意忽略的因素——闰秒会很容易,只要您不介意更新配置文件 (或按该顺序的东西)任何时候插入另一个闰秒。补偿夏令时 time/summer 时间在某些方面相当容易。基本上计算时钟偏移发生时的秒数到一年的偏移量,并且(很像上面)计算秒数 % seconds/year 以获得秒数到一年的偏移量,然后将其与时钟偏移发生时的偏移量进行比较.
但是,由于您一般指定了 EST
,我猜测(无论出于何种原因)您不关心季节性时间变化。
但我要重复一遍:我认为这只是一种智力练习(在适当的情况下,通过正确的简化假设)可以起作用,而不是实际起作用或将起作用的东西.霍华德的回答确实是正确的处理方式。
C++ std::chrono 规范中是否有任何结构来表示时间和时区,但没有日期?问题是我希望能够过滤具有 unix 时间 (time_t) 的记录,以及 return 所有时间在“10:00 EST”和“11:00 EST”之间的记录。这需要将 time_t 转换为 EST,剥离时间,然后将其与“时间”结构进行比较。
C 库函数 localtime
(在 C++ 代码中完全可用)采用 a(指向 a 的指针)time_t
和 returns a(指向 a 的指针)struct tm
具有日期和时间值。
但是,没有法律规定您必须以某种方式使用它的日期部分。您可以忽略它们,只查看小时、分钟和秒值。
C++20 引入了对 chrono 的时区支持。它尚未发货,但有 free, open-source preview library. It does require some installation for the time zone support.
{time-of-day, time_zone}
没有现成的数据结构。但是,您可以通过将一天中的时间存储为 chrono::duration
(比如 seconds
?)和 chrono::time_zone const*
(date::time_zone const*
在 preview lib ).
#include "date/tz.h"
#include <chrono>
#include <ctime>
#include <iostream>
struct my_event
{
date::time_zone const* tz;
std::chrono::seconds tod;
};
std::ostream&
operator<<(std::ostream& os, const my_event& e)
{
return os << date::format("%T ", e.tod) << e.tz->name();
}
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
time_t t = 1609186734;
zoned_time zt{"America/New_York", sys_seconds{seconds{t}}};
auto local_time = zt.get_local_time();
auto tz = zt.get_time_zone();
my_event e{tz, local_time - floor<days>(local_time)};
cout << e << '\n';
}
输出:
15:18:54 America/New_York
至少在我看来,Howard Hinnant 在这里给出了几乎正确的答案(如果他不是那么谦虚,他可能会指出他定义并实现了对他提到的标准)。
特别是,要确定一天中的时间(至少大多数地方都是如此),我们必须首先计算出一年中的第几天,因为许多(大多数?)地方每隔一小时就会改变一个小时一年几次(在 spring 的某个时间向前一个小时,在秋天的某个时间向后一个小时)。所以,要做好这项工作,我们基本上别无选择,只能考虑日期。
目前,假设我们可以忽略时间的变化。当我们这样做的时候,我们还假设我们有一个类似于 POSIX 的 time_t(即,它是自 1970 年 1 月 1 日午夜以来的整数秒数。而且由于大多数人付给他们的钱很少无论如何,我还假设我们可以忽略自 1970 年以来插入的闰秒(如果我没记错的话,其中有 27 个)。
在这种情况下,我们可以简单地将一天视为24小时。 24 hours/day * 60 minutes/hour * 60 seconds/minute 给我们 86'400 seconds/day。所以,some_time_t % 86'400 给了我们当天的偏移量(以秒为单位)。
10 AM 是午夜过后 10 小时,因此偏移量为 10 小时 * 60 minutes/hour * 60 seconds/minute = 36'000 秒。上午 11 点是 11 小时 * 60 * 60 = 39'600 秒。
因此,对于这个大大简化的时间模型,我们将问题简化为:
bool in_range(time_t input) {
int offset = input % 86'400;
return offset >= 36'000 && offset < 39'600;
}
从理论上讲,您至少可以添加一些我们到目前为止有意忽略的因素——闰秒会很容易,只要您不介意更新配置文件 (或按该顺序的东西)任何时候插入另一个闰秒。补偿夏令时 time/summer 时间在某些方面相当容易。基本上计算时钟偏移发生时的秒数到一年的偏移量,并且(很像上面)计算秒数 % seconds/year 以获得秒数到一年的偏移量,然后将其与时钟偏移发生时的偏移量进行比较.
但是,由于您一般指定了 EST
,我猜测(无论出于何种原因)您不关心季节性时间变化。
但我要重复一遍:我认为这只是一种智力练习(在适当的情况下,通过正确的简化假设)可以起作用,而不是实际起作用或将起作用的东西.霍华德的回答确实是正确的处理方式。