web-dev-qa-db-fra.com

c ++ jour de la semaine pour une date donnée

J'essaie d'écrire un programme simple en c ++ qui renvoie le jour de la semaine pour une date donnée. 

Le format d'entrée est le jour, le mois et l'année. Je ne peux pas le faire fonctionner avec des années bissextiles. J'ai essayé de soustraire un de la variable a lorsque l'année d'entrée est une année bissextile, mais le programme finit par planter sans message d'erreur. 

J'apprécierais toutes les suggestions, mais s'il vous plaît essayez de rester simple, je suis toujours un débutant. Toutes mes excuses pour la question stupide, et veuillez excuser mes erreurs, c’est la première fois que je poste sur ce 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);
}
5
OerllydSaethwr

D'abord: N'écrivez pas votre propre fonction, s'il existe déjà des fonctions normalisées pouvant traiter le même problème. Le fait est que vous pouvez facilement faire une erreur (et je peux déjà en voir une dans la première ligne de votre fonction weekday() telle qu’elle est à présent), alors que les implémentations de fonctions normalisées ont été testées de manière approfondie et que vous pouvez être sûr résultat que vous êtes censé obtenir.

Ceci étant dit, voici une approche possible utilisant std :: localtime et std :: 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;
}
8
Striezel

Votre compréhension de ce qui constitue une année bissextile est incorrecte:

Une année bissextile est une tous les 4 ans SAUF s'il est divisible par 100, MAIS même s'il reste une année bissextile s'il est divisible par 400.

Vous trouverez une explication claire et concise sur la manière de calculer le "numéro de jour" (dn) ici .

Une fois que vous avez le numéro du jour (dn), effectuez simplement un module 7. Le résultat sera le jour de la semaine (dow).

Voici un exemple d'implémentation (ne vérifie pas si la date est une entrée valide):

#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;
}
2
Andy Turfer

Vous pouvez utiliser le Système de date Grégorien depuis la bibliothèque Boost C++ pour trouver le jour de la semaine d’une date donnée. Voici un exemple simple:

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

Ce code imprime Monday.

2
HugoTeixeira

Que se passe-t-il lorsqu'un nombre est parfaitement divisible par 7?

14/7 = 2 14% 7 = 0

L'opérateur modulo (% n) renverra un nombre compris entre 0 et n -1

si n est divisé par 7, le reste ne peut jamais être 7so

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

Dans ce cas, il ne peut jamais être dimanche

Essaye ça

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