【问题标题】:Q&A: How do I figure out what the last day of the month is?问与答:我如何知道一个月的最后一天是哪一天?
【发布时间】:2013-03-26 06:36:07
【问题描述】:

我正在尝试编写一个自己滚动的时区转换器,我需要一种方法来确定该月的最后一天是哪一天。经过一番研究,我发现了寻找闰年的公式。

这是一个很小的贡献,但也许我会节省其他人我花了 20 分钟弄清楚并应用它的时间。

此代码接受一个带符号的短月,索引为 0(0 是一月)和一个索引为 0 的 int 年(2012 年是 2012 年)。

它返回索引为 1 的日期(27 日是 27 日,但在 SYSTEMTIME 结构等中,您通常需要 0 索引 - 只需要注意)。

【问题讨论】:

    标签: c++ gregorian-calendar monthcalendar date-arithmetic leap-year


    【解决方案1】:
    short _get_max_day(short month, int year) {
        if(month == 0 || month == 2 || month == 4 || month == 6 || month == 7 || month == 9 || month == 11)
            return 31;
        else if(month == 3 || month == 5 || month == 8 || month == 10)
            return 30;
        else {
            if(year % 4 == 0) {
                if(year % 100 == 0) {
                    if(year % 400 == 0)
                        return 29;
                    return 28;
                }
                return 29;
            }
            return 28;
        }
    }
    

    【讨论】:

    • if (year % 4 == 0 && year % 400 != 0) return 29 else return 28 我认为是一种更简洁的表达方式。
    • @AlexeyFrunze 请提供更正或反例。
    • @john ((400 % 4) == 0) && ((400 % 400) != 0) 是 0,哎呀。 ((100 % 4) == 0) && ((100 % 400) != 0) 是 1,哎呀第二次了。
    • @AlexeyFrunze 糟糕,我很困惑。
    • @john leap = !(year % 4) && (year % 100 || !(year % 400));
    【解决方案2】:

    怎么样

    #include <time.h>
    #include <iostream>
    
    int LastDay (int iMonth, int iYear)
    {
        struct tm when;
        time_t lastday;
    
        // Set up current month
        when.tm_hour = 0;
        when.tm_min = 0;
        when.tm_sec = 0;
        when.tm_mday = 1;
    
        // Next month 0=Jan
        if (iMonth == 12)
        {
            when.tm_mon = 0;
            when.tm_year = iYear - 1900 + 1;
        }
        else
        {
            when.tm_mon = iMonth;
            when.tm_year = iYear - 1900;
        }
        // Get the first day of the next month
        lastday = mktime (&when);
    
        // Subtract 1 day
        lastday -= 86400;
    
        // Convert back to date and time
        when = *localtime (&lastday);
    
        return when.tm_mday;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        for (int m = 1; m <= 12; m++)
            std::cout << "Last day of " << m << " is " << LastDay (m, 2002) << std::endl;
    
        return 0;
    }
    

    打印出来(2002 年)...

    Last day of 1 is 31
    Last day of 2 is 28
    Last day of 3 is 31
    Last day of 4 is 30
    Last day of 5 is 31
    Last day of 6 is 30
    Last day of 7 is 31
    Last day of 8 is 31
    Last day of 9 is 30
    Last day of 10 is 31
    Last day of 11 is 30
    Last day of 12 is 31
    

    【讨论】:

    • 一点点!但与多个 ifss 相比,这是一个干净的解决方案,并且可以检查闰年等的不同规则。
    • 没错,有两个可能的答案是没有问题的!只是为您提供了更多解决问题的方法。
    • 这很好。它使用库而不是依赖外部知识的@CollinBiedenkapp 的答案给出答案。这个答案更有可能考虑到语言环境! (我不知道它是否像写的那样。)
    【解决方案3】:

    我使用一个简单的函数来返回(标准)COleDateTime 中的整个日期。它可能没有其他选项那么快,但它非常有效,适用于闰年并且非常简单。

    这是我正在使用的代码:

    COleDateTime get_last_day_of_month(UINT month, UINT year)    
    {
    if(month == 2)
        {                                               // if month is feb, take last day of March and then go back one day
            COleDateTime    date(year, 3, 1, 0, 0, 0);  // 1 March for Year
            date -= 1;                                  // go back one day (the standard class will take leap years into account)
            return date;
        }
        else if(month == 4 || month == 6 || month == 9 || month == 11) return COleDateTime(year, month, 30, 0, 0, 0);
        else return COleDateTime(year, month, 31, 0, 0, 0);
    }
    

    【讨论】:

    • 您能否也发布一些代码解释......?将有助于使您的答案清晰......
    【解决方案4】:
    import datetime 
    from datetime import date
    from dateutil.relativedelta import relativedelta
    
    year = int((date.today()).strftime("%Y"))
    month = list(range(1, 13, 1))
    YearMonthDay = [(datetime.datetime(year, x, 1) + relativedelta(day=31)).strftime("%Y%m%d") for x in month]
    print(YearMonthDay)
    

    2['20220131', '20220228', '20220331', '20220430', '20220531', '20220630', '20220731', '20220831', '20220930', '20221031', '2 ']

    【讨论】:

      【解决方案5】:

      在 C++20 中:

      #include <chrono>
      
      std::chrono::day
      get_max_day(std::chrono::month m, std::chrono::year y)
      {
          return (y/m/std::chrono::last).day();
      }
      

      如果您确实需要使用类型不安全的 API:

      int
      get_max_day(int m, int y)
      {
          return unsigned{(std::chrono::last/m/y).day()};
      }
      

      【讨论】:

        【解决方案6】:
        Word Year, Month, Day;
        TDateTime datum_tdatetime = Date();
        
        // first day of actual month
        datum_tdatetime.DecodeDate(&year, &month, &day);
        day = 1;
        datum_tdatetime = EncodeDate(year, month, day);
        // last day of previous month
        datum_tdatetime -= 1;
        // first day of previous month
        datum_tdatetime.DecodeDate(&year, &month, &day);
        day = 1;
        datum_tdatetime = EncodeDate(year, month, day);
        

        【讨论】:

          猜你喜欢
          • 2020-04-06
          • 2011-01-30
          • 2015-02-06
          • 1970-01-01
          • 2010-09-07
          • 1970-01-01
          • 1970-01-01
          • 2021-12-24
          相关资源
          最近更新 更多