我想获取当地时间一天中的每个小时。对于没有夏令时的地方,这很容易,但是当 DST 开始或结束时,当天有 23 或 25 小时!
我编写此代码是为了正确获取它,但我想知道是否有更简单的方法使用 chrono 来编写函数 PrintHours()
#include <iostream>
#include <chrono>
using namespace std::chrono;
constexpr const char* zoneName = "Europe/Berlin";
void PrintHours(std::chrono::local_days date)
{
zoned_time utcTime{"UTC", zoned_time{zoneName, date}};
auto localTime = zoned_time{zoneName, utcTime};
auto dp = std::chrono::floor<days>(localTime.get_local_time());
// keep looping until day change!
for (auto startingDay = year_month_day{dp}.day(); startingDay == year_month_day{dp}.day(); dp = std::chrono::floor<days>(localTime.get_local_time()))
{
std::cout << zoneName << localTime<< " UTC: " << utcTime << std::endl;
// bump time to next hour
utcTime = zoned_time("UTC", utcTime.get_local_time() + hours(1));
localTime= zoned_time{zoneName, utcTime};
}
}
int main(int argc, char **argv)
{
using namespace std::chrono;
year_month_day ymd{year(2023), month(10), day(29)};
PrintHours(local_days(ymd));
return 1;
}
0
2 个回答
2
下列:
#include <chrono>
#include <iostream>
using namespace std::chrono;
constexpr const char* zoneName = "Europe/Berlin";
void PrintHours(year_month_day day) {
// get the year-month-day 00:00:00 in the specific timezone.
for (auto it = zoned_time(zoneName, local_days(day));
// Get the day in the iterator and compare with starting day.
year_month_day(floor<days>(it.get_local_time())).day() == day.day();
// Increment the day in one hour and come back to the timezone.
it = it.get_sys_time() + hours(1)) {
std::cout << it << '\n';
}
}
int main(int argc, char** argv) {
PrintHours(year_month_day{year(2023), month(10), day(29)});
return 1;
}
输出:
2023-10-29 00:00:00 CEST
2023-10-29 01:00:00 CEST
2023-10-29 02:00:00 CEST
2023-10-29 02:00:00 CET
2023-10-29 03:00:00 CET
2023-10-29 04:00:00 CET
2023-10-29 05:00:00 CET
2023-10-29 06:00:00 CET
2023-10-29 07:00:00 CET
2023-10-29 08:00:00 CET
2023-10-29 09:00:00 CET
2023-10-29 10:00:00 CET
2023-10-29 11:00:00 CET
2023-10-29 12:00:00 CET
2023-10-29 13:00:00 CET
2023-10-29 14:00:00 CET
2023-10-29 15:00:00 CET
2023-10-29 16:00:00 CET
2023-10-29 17:00:00 CET
2023-10-29 18:00:00 CET
2023-10-29 19:00:00 CET
2023-10-29 20:00:00 CET
2023-10-29 21:00:00 CET
2023-10-29 22:00:00 CET
2023-10-29 23:00:00 CET
2
-
2这是非常好的。我在查看你的版本之前提出的版本有两个小改进:1)。增量可以通过简单地完成:
it = it.get_sys_time() + 1h
。也就是说,您可以sys_time
直接将 a 分配回 a,zoned_time
而不需要构造临时zoned_time
。 2) 您可以使用 轻松打印正文中的等效 UTC 时间format("{:%F %T %Z}", it.get_sys_time())
。我认为这两个调整足够小,不需要额外的答案。
– -
1我上面忽略的另一项调整是:for 循环中的测试将比问题中定义的
floor<days>(it.get_local_time()) == date
where更有效。date
这避免了每次迭代从串行到字段的转换,并且达到相同的目的。
–
|
使用现代 C++ 标准
#include <chrono>
#include <iomanip>
#include <date/date.h>
#include <ranges>
using namespace std;
using namespace std::chrono;
using namespace std::ranges;
namespace {
constexpr const char* zoneName = "Europe/Berlin";
void PrintHours(const chrono::local_days& date) {
auto zone = date::locate_zone(zoneName);
date::zoned_time<std::chrono::seconds> localTime(zone, date);
cout << "Hours of the day in " << zoneName << ":\n";
for (int hour : views::iota(0, 24)) {
auto specificHour = localTime + hours(hour);
cout << date::format("%Y-%m-%d %H:%M:%S %Z", specificHour) << '\n';
}
}
}
int main() {
using namespace date;
using namespace std::chrono;
year_month_day ymd{year{2023}, month{10}, day{29}}; // Example date: October 29, 2023
PrintHours(local_days{ymd});
return 0;
}
4
-
这不是缺少标题(
<iostream>
和<date/tz.h>
)吗?另外,Date
我有权访问的所有版本都没有zoned_time
可以从您使用的类型构造的。using
两者std::chrono
都会data
造成歧义。最好不要混合使用它们,这样就可以清楚地了解您实际打算选择的类型。
–
-
这行代码无法编译的原因
auto specificHour = localTime + hours(hour)
是它本质上是不明确的。当我读到它的时候,我真的不知道它到底想表达什么。您想要在基础本地时间或基础 UTC 时间上添加一个小时吗?
– -
views::iota(0, 24)
那么有 25 个小时的日子呢?你不能对此进行硬编码。
– -
有些日子有 23 小时、24 小时和 25 小时,这就是我需要为 UI 枚举的内容。所以我不能使用 iota 并假设固定的小时数。我还想使用 chrono 库,而不是 Hinnant 库。
–
|
|