c++ - 如何计算当月的星期日?

标签 c++ arduino arduino-esp8266 sparkcore

我不久前基于 arduino 制作了一个 LED 挂钟和日历,现在我想修改它以添加一个变量以自动调整 DST 的偏移量。我已经每天轮询 2 次 Internet 时间服务器以确保准确性,但时间服务器通常不提供 DST 信息。更改发生在 3 月的第 2 个星期日和 11 月的第 1 个星期日。 ( https://www.nist.gov/pml/time-and-frequency-division/popular-links/daylight-saving-time-dst ) 本质上,我需要知道什么时候是三月的第二个星期日,并告诉它在 11 月的第一个星期日将时区偏移量调整 +1,然后调整为 -1。我只是不确定如何实现。

我在想:

如果 月 == 3 或 11 和 如果工作日 == 1; 然后 星期日 + 1; 别的 星期日 = 0;

如果星期天== 2; 和 月 == 3; 然后 夏令时 = 真;

如果星期天== 1; 和 月 == 11; 然后 isDST = FALSE;

我希望这是一个很好的例子来说明我想做的事情。我讨厌使用这么多嵌套的 if,但这是我能想到的最好的,仍然是一个相对的新手。这甚至会起作用还是有更好的方法来解决这个问题?如有任何帮助,我们将不胜感激。

最佳答案

这是一个paper with calendrical algorithms可用于计算诸如三月的第二个星期日之类的事情。参见 Example: Finding nth weekday of month .

如果你有可用的 C++11,你可以使用这个 free, open-source date library用非常高级的语法来计算这些东西。该库使用来自 the paper 的算法在引擎盖下。例如:

std::chrono::system_clock::time_point
DST_US(std::chrono::system_clock::time_point tp, std::chrono::hours std_offset)
{
    using namespace date;
    using namespace std::chrono;
    const auto y = year_month_day{floor<days>(tp)}.year();
    const auto begin = sys_days{sun[2]/mar/y} + 2h - std_offset; // DT begins at this UTC time
    const auto end   = sys_days{sun[1]/nov/y} + 1h - std_offset; // ST begins at this UTC time
    if (tp < begin || end <= tp)
        return tp + std_offset;
    return tp + std_offset + 1h;
}

如果您有 C++11(它是可移植的),请随意使用 datetime 库,并使用 the paper 中的算法创建您自己的库否则。

免责声明:时区规则一直在变化。以上对于自制时钟来说当然足够了。对于需要最新时区规则的工业强度应用程序,请使用基于 IANA timezone database 的库例如this one .

关于c++ - 如何计算当月的星期日?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45641206/

相关文章:

c++ - 将 std::begin() 应用于 unique_ptr 中动态分配的数组?

c++ - 重载运算符和静态成员变量的行为

c++ - 如何使用 C 文件中的 esp8266 引脚排列?

c++ - 字符串损坏 - 堆栈溢出?

ESP8266(Arduino 库)中的 SSL - 如何处理证书更改?

c++ - 从字符串中修剪/删除无用的空格和制表符

c++ - 获取具有相同扩展名的文件列表并处理它们

node.js - firmatajs,多个 Arduino 超时(johnny- Five、cylonjs)

c - Arduino Due Sam3X8E 访问定时器值

c++ - 使用更多像素时 Neopixel 示例代码崩溃