简体   繁体   English

给定日期的c ++星期几

[英]c++ day of week for given date

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 a variable 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);
}

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::localtime and 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;
}

Your understanding of what constitutes a leap year is incorrect:您对闰年的理解是不正确的:

A leap year is every 4 years EXCEPT if it's divisible by 100, BUT even then it's still a leap year if it's divisible by 400.闰年是每 4 年,除非它可以被 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;
}

You can use the Gregorian Date System from the Boost C++ library to find the day of week of a given date.您可以使用Boost C++ 库中的公历日期系统来查找给定日期的星期几。 Here is a simple example:这是一个简单的例子:

#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

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 <format>
#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 date instead 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';
}

I had the same problem, and I was able to find a simple solution.我有同样的问题,我能够找到一个简单的解决方案。

According to this post:根据这篇文章:
"Following is a simple function suggested by Sakamoto, Lachman, Keith and Craver to calculate day. The following function returns 0 for Sunday, 1 for Monday, etc." “以下是Sakamoto、Lachman、Keith 和 Craver建议的用于计算日期的简单函数。以下函数返回 0 表示周日,1 表示周一,等等。”

int dayofweek(int d, int m, int y)  
{  
    static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };  
    y -= m < 3;  
    return ( y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;  
}

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";
        }

try using the CTime class尝试使用 CTime 类

Exemple:示例:

const CTime currTime = CTime::GetCurrentTime();
const int nWeekDay = currTime.GetDayOfWeek();

switch (nWeekDay)
{
    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 the example above I'm using the current time, but you can do it differently, with the time you want example:在上面的示例中,我使用的是当前时间,但您可以使用不同的方式,使用您想要的时间示例:

const CTime currTime = CTime(year,month, day, hours, minutes, seconds );
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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM