【问题标题】:Getting the day info only from a date int C/C++ [closed]仅从日期 int C/C++ 获取日期信息 [关闭]
【发布时间】:2018-07-09 13:07:51
【问题描述】:

我有一个程序从某个协议获取日期,格式为DD/MM/YYYY

问题是我需要知道那一天的信息(星期几,一年中的哪一天......),我不知道该怎么做。

通常,当我想获取一天信息时,我使用 time(time_t*) 并将结果转换为 tm struct 使用 localltime_r(tm*, time_t*) 然后我就拥有了我需要的一切。

但在这种情况下,这不是当前时间(所以我不能使用 time(time_t*)),除了日期我什么都没有。

我可以创建一个新的 tm struct 并且只填写 tm_yeartm_montm_mday 并使用 mktime(tm*),但我不确定这是否会给我所需日期的正确详细信息。

【问题讨论】:

  • 您使用的是 C 还是 C++?
  • 为什么它不起作用? tm struct 绝不会绑定到 当前 日期。
  • "使用 mktime(tm*),但我不确定这是否会给我所需日期的正确详细信息" - 只要您将其他字段归零,是的,它应该可以工作。
  • 我不确定在未知字段中输入零是否会提供正确的信息。我会试一试
  • 阅读documentation for mktime。如果您填写您知道的日期(包括月份和日期),并致电mktimemktime 将为您计算星期几和一年中的星期几。您应该将时间设置为 12:00:00,并将tm_isdst 设置为 0 或 -1。

标签: c++ c date time


【解决方案1】:

您可以考虑使用Howard Hinnant's free, open-source date/time library。它适用于 C++11 及更高版本,移植到 gcc、clang 和 VS。它已被 C++20 草案规范接受。

示例代码:

#include "date/date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std;
    using namespace date;
    istringstream in{"09/07/2018"};
    sys_days sd;
    in >> parse("%d/%m/%Y", sd);
    cout << "Day of the week is " << weekday{sd} << '\n';
    cout << "Day of the year is " << sd - sys_days{year_month_day{sd}.year()/1/0} << '\n';
}

输出:

Day of the week is Mon
Day of the year is 190d

如果您更愿意自己进行计算,here 是用于日历计算的非常高效的非迭代公共领域算法。上面引用的库只不过是围绕这些算法的类型安全包装器,具有更令人愉悦的语法。

【讨论】:

    【解决方案2】:

    如果您想获得获取星期/年的写入方法而不是使用库,这就是我要做的。

    您需要考虑闰年。对于任何给定的年份,确定它是否是闰年。这样的事情会起作用(使用此处找到的公式:https://en.wikipedia.org/wiki/Leap_year#Algorithm:

        bool isLeapYear(short year)
        {
            bool leapYear = false;
            if (((year % 4 == 0 && year % 100 != 0)) || (year % 400 == 0))
                leapYear = true;
            return leapYear;
        }
    

    由此,计算一年中的哪一天很简单。只需将每个月的所有天数相加,如果是闰年,如果遇到 2 月,则将 29 天添加到一年中的某一天。

    至于查找星期几,如果您从一年的一些下限开始(在本例中为 LOWYEAR = 1760)并从该年的第一天开始( STARTDAYOFWEEK = 2)。一周中的每一天都对应一个数字 (0-6),其中星期日为 0,星期一为 1,依此类推。

    int DayOfWeek(void)
    {
       //jan 1 1760 was tuesday (2)
        short dayCount = STARTDAYOFWEEK;
        for (unsigned i = LOWYEAR; i < year; i++)
        {
            if (isLeapYear(i))
                dayCount += 2;
            else
                dayCount++;
        }
        return (dayCount + dayOfYear) - 1) % DAYSINWEEK;
    }
    

    现在很容易找到星期几,在计算 dayCount 之后,通过将 dayCount 与 dayOfYear 相加并通过 DAYSINWEEK (6) 修改来找到星期几。

    生成的数字将对应于星期几 (0-6)。

    【讨论】:

    • 虽然这很适合学习,但如果您正在为标准 C 库函数可用的环境编写生产代码,使用标准库函数,请不要自己动手。众所周知,日期和时间操作代码很难正确处理。即使您确实设法做对了(而且您所拥有的看起来还不错),您也不希望让您的继任者担心您是否做对了,以及在需求发生变化时维护它。跨度>
    • 对。我只是觉得他可以从我的回答中学到一些东西。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 2010-11-04
    • 2017-12-24
    • 2016-06-13
    • 2016-12-09
    • 2016-11-19
    相关资源
    最近更新 更多