Я пытаюсь написать простую программу на C ++, которая возвращает день недели для данной даты.
Формат ввода — день, месяц, год. Я не могу заставить его работать с високосными годами. Я пытался вычесть один из a
переменная, когда входной год представляет собой високосный год, но программа просто завершается сбоем без сообщения об ошибке.
Буду признателен за любые предложения, но, пожалуйста, постарайтесь остаться простым, я все еще новичок. Извиняюсь за глупый вопрос, и, пожалуйста, извините за мои ошибки, я впервые публикую на этом сайте.
#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);
}
Первый: Не пишите свою собственную функцию, если уже есть стандартизированные функции, которые могут решить ту же проблему. Дело в том, что вы можете легко ошибиться (и я уже вижу одну в первой строке вашего weekday()
функционировать как сейчас), в то время как реализации стандартизированных функций были тщательно протестированы, и вы можете быть уверены, что они дадут ожидаемый результат.
Это, как говорится, здесь возможный подход с использованием станд :: LocalTime а также станд :: указываете ей:
#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;
}
Ваше понимание того, что представляет собой високосный год, неверно:
Високосный год каждые 4 года КРОМЕ если это делится на 100, НО даже тогда это все еще високосный год, если он делится на 400.
Можно найти четкое и краткое объяснение того, как рассчитать «число дней» (дн). Вот.
Получив номер дня (dn), просто выполните модуль 7. Результатом будет день недели (dow).
Вот пример реализации (не проверяет, является ли дата действительным вводом):
#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;
}
Вы можете использовать Григорианская система дат от Boost 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';
}
Этот код печатает Monday
,
Что происходит, когда число полностью делится на 7?
14/7 = 2
14% 7 = 0
Оператор по модулю (% n) вернет число от 0 до n -1
если 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";
}
}
В этом случае никогда не может быть воскресенье
Попробуй это
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";
}
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;
}