c ++ 给定日期的星期几

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40517192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:23:36  来源:igfitidea点击:

c++ day of week for given date

c++dateweekday

提问by OerllydSaethwr

I am trying to write a simple program in c++ that returns the day of the week for a given date.

我正在尝试用 C++ 编写一个简单的程序,该程序返回给定日期的星期几。

The input format is day, month, year. I cannot get it to work with leap years. I tried subtracting one from the avariable when the input year is a leap year, but the program just ends up crashing without an error message.

输入格式为日、月、年。我无法让它在闰年工作。a当输入年份是闰年时,我尝试从变量中减去一个,但程序最终崩溃而没有错误消息。

I would appreciate any suggestions, but please try to remain simple, I am still a beginner. Apologies for the stupid question, and please excuse my mistakes, this is the first time I post on this site.

我很感激任何建议,但请尽量保持简单,我仍然是初学者。为这个愚蠢的问题道歉,请原谅我的错误,这是我第一次在这个网站上发帖。

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;


int d;
int m;
int y;


string weekday(int d, int m, int y){
    int LeapYears = (int) y/ 4;
    long a = (y - LeapYears)*365 + LeapYears * 366;
    if(m >= 2) a += 31;
    if(m >= 3 && (int)y/4 == y/4) a += 29;
    else if(m >= 3) a += 28;
    if(m >= 4) a += 31;
    if(m >= 5) a += 30;
    if(m >= 6) a += 31;
    if(m >= 7) a += 30;
    if(m >= 8) a += 31;
    if(m >= 9) a += 31;
    if(m >= 10) a += 30;
    if(m >= 11) a += 31;
    if(m == 12) a += 30;
    a += d;
    int b = (a - 2)  % 7;
    switch (b){
    case 1:
        return "Monday";
    case 2:
        return "Tuesday";
    case 3:
        return "Wednesday";
    case 4:
        return "Thursday";
    case 5:
        return "Friday";
    case 6:
        return "Saturday";
    case 7:
        return "Sunday";
    }
}

int main(){
    cin >> d >> m >> y;
    cout << weekday(d, m, y);
}

回答by Striezel

First: Do not write your own function, if there already are standardized functions that can handle the same problem.Point is that you might easily make a mistake (and I can already see one in the first line of your weekday()function as it is now), whereas implementations of standardized functions have been tested thoroughly and you can be confident that they deliver the result you are expected to get.

第一:不要编写自己的函数,如果已经有可以处理相同问题的标准化函数。重点是您可能很容易犯错误(我已经可以在weekday()函数的第一行看到一个错误,就像现在这样),而标准化函数的实现已经过彻底测试,您可以确信它们提供了您想要的结果预计得到。

That being said, here is a possible approach using std::localtimeand std::mktime:

话虽如此,这是使用std::localtimestd::mktime的可能方法:

#include <ctime>
#include <iostream>

int main()
{
  std::tm time_in = { 0, 0, 0, // second, minute, hour
      9, 10, 2016 - 1900 }; // 1-based day, 0-based month, year since 1900

  std::time_t time_temp = std::mktime(&time_in);

  //Note: Return value of localtime is not threadsafe, because it might be
  // (and will be) reused in subsequent calls to std::localtime!
  const std::tm * time_out = std::localtime(&time_temp);

  //Sunday == 0, Monday == 1, and so on ...
  std::cout << "Today is this day of the week: " << time_out->tm_wday << "\n";
  std::cout << "(Sunday is 0, Monday is 1, and so on...)\n";

  return 0;
}

回答by HugoTeixeira

You can use the Gregorian Date Systemfrom the Boost C++ libraryto find the day of week of a given date. Here is a simple example:

您可以使用公历日期系统升压C ++库找到一个给定日期的一周中的一天。这是一个简单的例子:

#include <boost/date_time.hpp>
#include <string>
#include <iostream>

const static std::string daysOfWeek[] = {
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"
};

int getDayOfWeekIndex(int day, int month, int year) {
    boost::gregorian::date d(year, month, day);
    return d.day_of_week();
}

int main()
{
    const int index = getDayOfWeekIndex(30, 07, 2018);
    std::cout << daysOfWeek[index] << '\n';
}

This code prints Monday.

此代码打印Monday.

回答by Andy Turfer

Your understanding of what constitutes a leap year is incorrect:

您对闰年的理解是错误的:

A leap year is every 4 years EXCEPTif it's divisible by 100, BUTeven then it's still a leap year if it's divisible by 400.

闰年是每4年EXCEPT如果它是整除100,即便如此,它仍然是一个闰年,如果它是被400整除。

A clear and concise explanation of how to calculate the "day number" (dn) can be found here.

可以在此处找到有关如何计算“天数”(dn) 的清晰简明的说明。

Once you have the day number (dn), just perform a modulus 7. The result will be the day of week (dow).

获得天数 (dn) 后,只需执行模数 7。结果将是星期几 (dow)。

Here's an example implementation (doesn't check if date is valid input):

这是一个示例实现(不检查日期是否为有效输入):

#include <iostream>
#include <iomanip>

typedef unsigned long ul;
typedef unsigned int ui;

// ----------------------------------------------------------------------
// Given the year, month and day, return the day number.
// (see: https://alcor.concordia.ca/~gpkatch/gdate-method.html)
// ----------------------------------------------------------------------
ul CalcDayNumFromDate(ui y, ui m, ui d)
{
  m = (m + 9) % 12;
  y -= m / 10;
  ul dn = 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + (d - 1);

  return dn;
}

// ----------------------------------------------------------------------
// Given year, month, day, return the day of week (string).
// ----------------------------------------------------------------------
std::string CalcDayOfWeek(int y, ul m, ul d)
{
  std::string day[] = {
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday",
    "Monday",
    "Tuesday"
  };

  ul dn = CalcDayNumFromDate(y, m, d);

  return day[dn % 7];
}

// ----------------------------------------------------------------------
// Program entry point.
// ----------------------------------------------------------------------
int main(int argc, char **argv)
{
  ui y = 2017, m = 8, d = 29; // 29th August, 2017.
  std::string dow = CalcDayOfWeek(y, m, d);

  std::cout << std::setfill('0') << std::setw(4) << y << "/";
  std::cout << std::setfill('0') << std::setw(2) << m << "/";
  std::cout << std::setfill('0') << std::setw(2) << d << ": ";
  std::cout << dow << std::endl;

  return 0;
}

回答by Howard Hinnant

New answer for old question because the tools they are a changing...

旧问题的新答案,因为它们是一个不断变化的工具......

The C++20 spec says the following will have identical functionality to the intention of the code in the question:

C++20 规范说以下将具有与问题中代码的意图相同的功能:

#include <chrono>
#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    year_month_day dmy;
    cin >> parse("%d %m %Y", dmy);
    cout << format("{:%A}", weekday{dmy}) << '\n';
}

One can experiment today with this syntax by using this free, open-source date/time library, except that the date objects are in namespace dateinstead of namespace std::chrono, and the syntax of the format string is slightly altered.

今天可以通过使用这个免费的开源日期/时间库来试验这种语法,除了日期对象在namespace date而不是 中namespace std::chrono,并且格式字符串的语法略有改变。

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

int
main()
{
    using namespace std;
    using namespace date;
    year_month_day dmy;
    cin >> parse("%d %m %Y", dmy);
    cout << format("%A", weekday{dmy}) << '\n';
}

回答by ComradeJoecool

What happens when a number is perfectly divisible by 7?

当一个数能被 7 整除时会发生什么?

14 / 7 = 2 14 % 7 = 0

14 / 7 = 2 14 % 7 = 0

The modulo operator (% n) will return a number from 0 to n -1

模运算符 (% n) 将返回一个从 0 到 n -1 的数字

if n is divided by 7 the remainder can never be 7 so

如果 n 除以 7 余数永远不可能是 7 所以

int b = (a - 2)  % 7;
    switch (b){
    case 1:
        return "Monday";
    case 2:
        return "Tuesday";
    case 3:
        return "Wednesday";
    case 4:
        return "Thursday";
    case 5:
        return "Friday";
    case 6:
        return "Saturday";
    case 7:
        return "Sunday";
    }
}

In this case it can never be Sunday

在这种情况下,它永远不会是星期天

Try this

尝试这个

int b = (a - 2)  % 7;
        switch (b){
        case 0:
            return "Sunday";
        case 1:
            return "Monday";
        case 2:
            return "Tuesday";
        case 3:
            return "Wednesday";
        case 4:
            return "Thursday";
        case 5:
            return "Friday";
        case 6:
            return "Saturday";
        default:
            return "Error";
        }

回答by Vivek Mutha

int dayofweek(int day,int month,int year)
{
    int arr[] = {0,3,2,5,3,5,1,4,6,2,4};
    if(month<3)
        year--;
    return ((year+year/4-year/100+year/400+arr[month-1]+day)%7);
}

int main()
{
    int day,month,year;
    cout<<"Enter the Date for which day of the week need to be find (DD/MM/YYYY)."<<endl;
    cin>>day>>month>>year;
    int x = dayofweek(day,month,year);
    if(x==0)
        cout<<"Sunday"<<endl;
    else if(x==1)
        cout<<"Monday"<<endl;
    else if(x==2)
        cout<<"Tuesday"<<endl;
    else if(x==3)
        cout<<"Wednesday"<<endl;
    else if(x==4)
        cout<<"Thursday"<<endl;
    else if(x==5)
        cout<<"Friday"<<endl;
    else if(x==6)
        cout<<"Saturday"<<endl;

}