English 中文(简体)
我如何根据ISO 8601规定的日期获得固定时间点?
原标题:How do I get a fixed chrono time_point based on a date as specified by ISO 8601?

https://stackoverflow.com/a/76627660/576911”

我只希望ch光能够让我做这样的事情:

std::chrono::time_point<std::chrono::system_clock> xmas = std::chrono::datetime("2023-12-25");

例如,请允许我根据ISO 8601规定的日期获得一个固定的时间点。 如果日期是错误的,要么提出例外,要么以其他方式确定时间点,以发现任何错误处理是适当的。 非ISO 8601日期将得不到支持,尽管还应注意到其他标准也可执行。

选择来说,你本年度可使用XXXX,例如XXXX-01,今年首年,XXXX-12-25成为第25条,但现在我正在希望名单上真正删除:

问题回答

参看C++20std:chrono,作为“日期和时间代码”的一组组成部分。 在避免与时间、时间区和日历有关的大多数骗局的同时,你实际上无法轻易摆脱这些基本组成部分。

For example here is a function that is only a couple of dozen lines long that allows you do to exactly what you want, including getting everything on your wish list. Line-by-line explanation follows the code:

#include <chrono>
#include <sstream>
#include <stdexcept>

namespace my
{

std::chrono::system_clock::time_point
datetime(std::string const& s)
{
    std::istringstream in{s};
    std::chrono::year y;
    std::chrono::month_day md;
    if (in.peek() ==  X )
    {
        in >> std::chrono::parse("XXXX-%m-%d", md);
        if (in.fail())
            throw std::runtime_error(
                "Unable to parse a date of the form XXXX-mm-dd out of "" + s +  " );
        y = std::chrono::year_month_day{
                std::chrono::floor<std::chrono::days>(
                    std::chrono::system_clock::now())}.year();
    }
    else
    {
        in >> std::chrono::parse("%Y-", y) >> std::chrono::parse("%m-%d", md);
        if (in.fail())
            throw std::runtime_error(
                "Unable to parse a date of the form yyyy-mm-dd out of "" + s +  " );
    }
    auto date = y/md;
    if (!date.ok())
        throw std::runtime_error("Parsed invalid date out of "" + s +  " );
    return std::chrono::sys_days{date};
}

}  // namespace my
  • 第一件事是,看看一下插图是否为<代码>。 iii 这一点很容易地通过表面特征的推测来实现。 如果是<代码>X,则该代码必须是XXXX-d,否则该编码必须是yyyy-mm-d,否则就是一种错误,我们用一个附有详细错误信息的例外来表示。

  • 如果舱面像样是XXXX-mm-d,则打上chrono: 月_day,其格式为XXXX-%m-%d>。 如果存在任何平级差错,或者如果按字母顺序排列的<代码>月_日。 不可能有效,教区将失败。

  • 如果该教区失败,就会发出一个有帮助的错误信息。

  • 如果区系成功,则计算本年度(UTC),并将之分配到<代码>y。 如果希望达到当地年,或希望达到亚纳联盟任何时间区的年,这只是一条两条不同的法典。

  • 否则,舱面必须采用<代码>yyyy-mm-d。 Parse into a chrono:year and a chrono:个月的_day separate.

  • 如果任何教区都失败,则会发出一个有帮助的错误信息。

  • 最后,将<条码>年和<条码>月_日合并成<条码>年_月_日(本标准代码中的“<条码>)。

  • <代码>年有效,<代码>月_日有效,但两者的结合无效。 这将在2月29日这一非一年的时间里赶上。 如果发现的话,就会发出一个有帮助的错误信息。

  • 更改<代码> 日期:至system_clock:time_point,先改为sys_days,然后让默示转换精确到system_clock:time_point

这样做可以:

#include <iostream>

int
main()
{
    auto xmas = my::datetime("2023-12-25");
    std::cout << xmas <<  
 ;
    xmas = {};
    xmas = my::datetime("XXXX-12-25");
    std::cout << xmas <<  
 ;
    try
    {
        xmas = my::datetime("XXXX-25-12");
    }
    catch (std::exception const& e)
    {
        std::cout << e.what() <<  
 ;
    }
}

哪些产出:

2023-12-25 00:00:00.000000
2023-12-25 00:00:00.000000
Unable to parse a date of the form XXXX-mm-dd out of "XXXX-25-12"

请注意,我们的法典发现了正确的辛迪加错误,但月25日无效。

还指出,如果需要,可以通过更多的检查和分行来支持其他日期格式。





相关问题
Return range from different sources

I m wondering how to make same type for return value? Consider an example: auto get_securities_by_mic(const std::string& mic) { auto it = some_map.find(mic); // I want to write like this: ...

Portable branch prediction hints

Is there any portable way of doing branch prediction hints? Consider the following example: if (unlikely_condition) { /* ..A.. */ } else { /* ..B.. */ } Is this any different than ...

热门标签