L'arithmétique sur les dates du calendrier en C ou C++ (ajouter N jours à la date donnée)
J'ai été donné une date, que je prends comme une entrée comme (jour, mois, année): 12, 03, 87
.
Maintenant j'ai besoin de savoir la date après n
jours.
J'ai écrit du code pour cela, Mais ce n'est pas efficace. Pouvez-vous me dire en toute bonne logique qui fonctionne plus rapidement et d'avoir moins de complexité.
#include <stdio.h>
static int days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int day, month, year;
unsigned short day_counter;
int is_leap(int y) {
return ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0);
}
next_day()
{
day += 1; day_counter++;
if (day > days_in_month[month]) {
day = 1;
month += 1;
if (month > 12) {
month = 1;
year += 1;
if (is_leap(year)) {
days_in_month[2] = 29;
} else {
days_in_month[2] = 28;
}
}
}
}
set_date(int d, int m, int y)
{
m < 1 ? m = 1 : 0;
m > 12 ? m = 12 : 0;
d < 1 ? d = 1 : 0;
d > days_in_month[m] ? d = days_in_month[m] : 0;
if (is_leap(y)){
days_in_month[2] = 29;
}
else {
days_in_month[2] = 28;
}
day = d;
month = m;
year = y;
}
skip_days(int x)
{
int i;
for (i=0;i<x;i++) next_day();
}
print_date()
{
printf ("day: %d month: %d year: %d\n", day, month, year);
}
int main(int argc, char **argv)
{
int i;
set_date(5, 2, 1980);
skip_days(40);
day_counter = 0;
/* after this call next_day each day */
print_date();
return 0;
}
C ou C++? Choisissez-en un.
Vous avez marqué la question, comme C++, et je vais donc suggérer boost de la date/heure. Cela permettra de gérer tous les problèmes pour vous.
Utiliser les Date et heure utilitaires pour le C et le chrono de la bibliothèque pour le C++
En fait, non, les devoirs de la balise est officiellement obsolète.
Efficace, documenté calendrier des algorithmes: howardhinnant.github.io/date_algorithms.html Pas d'itération nécessaire.
Vous avez marqué la question, comme C++, et je vais donc suggérer boost de la date/heure. Cela permettra de gérer tous les problèmes pour vous.
Utiliser les Date et heure utilitaires pour le C et le chrono de la bibliothèque pour le C++
En fait, non, les devoirs de la balise est officiellement obsolète.
Efficace, documenté calendrier des algorithmes: howardhinnant.github.io/date_algorithms.html Pas d'itération nécessaire.
OriginalL'auteur vivek jain | 2013-03-27
Vous devez vous connecter pour publier un commentaire.
Si cette chose exacte est en effet une critique pour les performances de votre application, vous êtes susceptible de faire quelque chose de mal. Par souci de clarté et de l'exactitude, de s'en tenir aux solutions existantes. Sélectionnez celui qui est le plus approprié à votre environnement de développement.
Le C approche:
Le C++ sans utiliser Boost approche:
La Coup de pouce.Date_Time approche:
Vous pourriez avoir besoin pour le convertir en un type qui surcharge le désiré des opérateurs de comparaison ou de mettre en œuvre vous-même.
OriginalL'auteur moooeeeep
De la bibliothèque standard
mktime
fonction comprend une astuce pour le rendre facile d'ajouter un certain nombre de mois ou de jours à une date donnée: vous pouvez lui donner une date comme "45e de février" ou "2ème jour de la 40e mois" etmktime
reviendra à la normale dans un bon jour. Exemple:Par rapport au fait de faire de l'arithmétique en quelques secondes en utilisant
time_t
, cette approche a l'avantage de l'heure d'été transitions ne cause pas de problèmes.OriginalL'auteur han
Voici ce que la solution ressemble à l'aide d'algorithmes publiés ici par Howard Hinnant.
Date de nouvelle fonctionnalité a été approuvé pour l'inclusion en C++20, mais avec une API différente. C++20 solution sera probablement ressembler à quelque chose comme:
OriginalL'auteur bames53
le plus simple astuce consiste à utiliser
time_t
type et les fonctions correspondantes.mktime
va convertir tm structure detime_t
. ce qui est une valeur entière qui compte les secondes de départ 01-Jan-1970.Après vous avez un
time_t
valeur juste ajouter les secondes comptent, vous devez (86400 par jour).Convertir à l'arrière, utilisez
gmtime
oulocaltime
Et quelques jours sont la moitié de l'année... Sérieusement, vous ne comprenez pas le problème ici? Pourquoi vous compliquer à l'excès les choses?
Je ne crois pas que c'est compliquer à l'excès choses à remarquer que cette solution peut donner de mauvaises réponses. Le bon, la solution la plus simple est d'utiliser correctement la date de l'arithmétique. E. g. en supposant un approprié bibliothèque juste à faire:
civil_from_days(10 + days_from_civil(2015, 11, 16))
.OriginalL'auteur eyalm
Vient de s'ajouter à un time_t objet pour combien de jours vous voulez.
Plutôt que d'utiliser 24*60*60 comme un substitut pour les "one day", vous devriez plutôt utiliser un type date qui sait comment travailler en termes de dates réelles. Un exemple est Howard Hinnant
chrono::date
de la bibliothèque.Encore une fois,
time_t
ne compte pas les secondes intercalaires.OriginalL'auteur lcs
Peuvent être mises en œuvre à l'aide de C++ opérateurs et dans un tout à fait de la POO façon par le représentant de la date en tant que classe.
OriginalL'auteur SajithP
Il pourrait être plus facile de faire le calcul à l'aide de secondes depuis l'époque plutôt que de manipuler les champs de date directement.
Par exemple, ce programme imprime la date 7 jours à partir de maintenant:
De ne pas faire.
time_t
n'est pas l'heure UTC. Tous ses jours sont 86400 secondes. Les secondes intercalaires sont ignorés/sauté/chargement pivote dans POSIX.Qui dépend de la façon dont le système est configuré. Par exemple, considérons la documentation suivante: "Le asctime(), ctime(), difftime(), gmtime(), localtime () et mktime() des fonctions conformes à la norme ISO/IEC 9899:1990 ("ISO C89"), et conformes à la norme ISO/IEC 9945-1:1996 ("POSIX.1") fourni sélectionnés fuseau horaire local ne contient pas de saut-deuxième table (voir la zic(8) )." [emp. ajouté]
Cette note se rapporte à la manière POSIX temps est converti en non-POSIX (les différentes lisible par l'homme timestampes, les structures avec brisée année/mois/jour/heure, etc champs, et ainsi de suite), donc pourquoi les secondes intercalaires sont importantes. Mais
time_t
lui-même est toujours un nombre de secondes depuis le 1er janvier 1970 a pas de comptage des secondes intercalaires. Un timestamp UNIX est défini de cette façon, toujours. Oui, vous avez raison de dire que "les différences peuvent être reflétés par C fonctions de temps", mais vous ne pouvez jamais déclencher ces différences par "à l'aide de secondes de cette façon". Andy méthode sera toujours ajouter une semaine à aujourd'hui, de la période.Non, les systèmes peuvent être configurés de manière à ce que time_t comprend des secondes intercalaires. Voici un autre exemple "Si le paquet est configuré avec saut de seconde est activé, [ ... ] time_t les valeurs continuent à augmenter au cours de saut d'événements"
OriginalL'auteur andy
Ce code affichera la date à venir au bout de 10 jours. Modifier la valeur de N pour un définis par l'utilisateur nombre.
OriginalL'auteur ARJUN