Day of Year to Date

BallerNacken

Ensign
Registriert
März 2008
Beiträge
227
Nabend Leute,

ich habe mir mit Hilfe vieler Quellen ein kleines Programm geschrieben, welches den User fragt welches Jahr es ist, daraus errechnet ob es sich um ein Schaltjahr handelt oder nicht und dementsprechend aus dem DOY (weitere Userabfrage) das entsprechende Datum berechnet.
Das funktioniert soweit auch einwandfrei, mit einer kleinen Einschränkung. Für die Monate Januar und Februar funktioniert das nicht wirklich. Auch wenn es sich dabei nicht um ein Schaltjahr handelt.

Ein paar kleine Beispiele:

Eingabe User:
Jahr: 2015
DOY: 300
Ausgabe:
2015 ist ein normales Jahr mit dem folgenden Datum: 27.10.2015
Eingabe User:
Jahr: 2012
DOY: 300
Ausgabe:
2015 ist ein normales Jahr mit dem folgenden Datum: 26.10.2015
Das wird beides richtig berechnet. Nehme ich die gleichen Jahre, aber den Tag 31, was für ein normales Jahr den 31.01.2015 bedeuten würde, erhalte ich den 03.02.2015. Bei einem Schaltjahr erhalte ich den 02.02.2015.

Ich komme dem Fehler leider nicht auf die schliche. Und bei dem ganzen Kram, den ich heute bezüglich der Zeitformate in c++ gelesen habe, bin ich auch ganz schön verwirrt. :D

Hier der Code:
Code:
#include <time.h>
#include <cstdio>
#include <iostream>

using namespace std;

//benutzen der Funktionen zum Ermitteln von Schaltjahren
bool leapYear(int);

int main(int argc, char *argv[])
{
    tm t;
    int daynum;
    int year;
    int leap;
    
//Userabfrage
    cout << "Please enter the year: ";
    cin >> year;
    cout << "Please enter the DOY you want to convert into the date: ";
    cin >> daynum;
    
    leap = leapYear(year);
//Wenn es ein Schaltjahr ist, wird das Datum so berechnet   
if (leap)
    {	
    time_t now = time(NULL);
    gmtime_r(&now, &t);
    t.tm_sec = 0;
    t.tm_min = 0;
    t.tm_hour = 0;
    t.tm_mday = 0;
    t.tm_mon = 1;
    time_t ref = mktime(&t);
    time_t day = ref + (daynum -1) * 86400;
    gmtime_r(&day, &t);
    cout << year << " is a leap year, the date is: ";
    std::printf("%02d/%02d/%04d\n", t.tm_mday, t.tm_mon, year);
    }
else // Ist es kein Schaltjahr wird es so berechnet
    {
    time_t now = time(NULL);
    gmtime_r(&now, &t);
    t.tm_sec = 0;
    t.tm_min = 0;
    t.tm_hour = 0;
    t.tm_mday = 1;
    t.tm_mon = 1;
    time_t ref = mktime(&t);
    time_t day = ref + (daynum - 1) * 86400;
    gmtime_r(&day, &t);
    cout << year << " is a normal year, the date is: ";
    std::printf("%02d/%02d/%04d\n", t.tm_mday, t.tm_mon, year);
    }
    return 0;
}

//Funktion zur Bestimmung eines Schaltjahres
bool leapYear(int year)
{
  return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0));
}

Grüße,
BallerNacken
 
Zuletzt bearbeitet:
1. Dein geposteter Sourcecode ist offensichtlich nicht was deine Ausgabe produziert hat.
2. Dein wirklicher Sourcecode ist total falsch, denn 2012 war offensichtlich kein normales Jahr sondern Schaltjahr.
3. Du darfst die Berechnung für das Schaltjahr nur dann so durchführen wenn der Tag nach dem 29. Februar ist. ansonsten sind ja Schaltjahr und normales Jahr exakt gleich
 
BallerNacken schrieb:
ich habe mir mit Hilfe vieler Quellen ein kleines Programm geschrieben, ...
und dabei das KISS-Prinzip ausser Acht gelassen.

Mein "naiver" (im Sinne von "kann ich es selber ohne großen Aufwand lösen?" -> "Ja, mit einer for-Schleife") Ansatz ist daher ohne "time.h" und sieht so aus:

Code:
#include <iostream>
#include <iomanip>


using namespace std;


// Funktion zur Bestimmung eines Schaltjahres
bool leapYear(int year)
{
    return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0));
}


int main(int argc, char *argv[])
{
    int daynum;
    int year;
    bool isleap;
    int days_per_month[]= { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int days_left;
    int day, month;
    
    
    // Userabfrage
    cout << "Please enter the year: ";
    cin >> year;
    cout << "Please enter the DOY you want to convert into the date: ";
    cin >> daynum;
    
    isleap = leapYear(year);
    if (isleap) days_per_month[1]= 29;
    
    if ( (daynum<1) || (daynum>(isleap?366:365)) )
    {
        cout << "DOY out of range!";
        return 1;
    }
    
    days_left= daynum;
    for(int m= 0; m<12; m++)
    {
        if (days_left<=days_per_month[m])
        {
            day= days_left;
            month= m+1;
            break;
        }
        days_left-= days_per_month[m];
    }
    
    cout << setfill('0') << setw(4) << year << " is a " << (isleap?"leap":"common") << " year, the date is: " << setw(2) << day << "." << setw(2) << month << "." << setw(4) << year << endl;
    
    return 0;
}

diverse Test liefern:
Code:
Please enter the year: 2012
Please enter the DOY you want to convert into the date: 300
2012 is a leap year, the date is: 26.10.2012

Please enter the year: 2015
Please enter the DOY you want to convert into the date: 300
2015 is a common year, the date is: 27.10.2015

Please enter the year: 2012
Please enter the DOY you want to convert into the date: 366
2012 is a leap year, the date is: 31.12.2012

Please enter the year: 2015
Please enter the DOY you want to convert into the date: 366
DOY out of range!

Please enter the year: 2012
Please enter the DOY you want to convert into the date: 367
DOY out of range!

Please enter the year: 2012
Please enter the DOY you want to convert into the date: 0
DOY out of range!

Please enter the year: 2015
Please enter the DOY you want to convert into the date: 0
DOY out of range!

Please enter the year: 2012
Please enter the DOY you want to convert into the date: 60
2012 is a leap year, the date is: 29.02.2012

Please enter the year: 2015
Please enter the DOY you want to convert into the date: 60
2015 is a common year, the date is: 01.03.2015

Please enter the year: 2012
Please enter the DOY you want to convert into the date: 31
2012 is a leap year, the date is: 31.01.2012

Please enter the year: 2012
Please enter the DOY you want to convert into the date: 32
2012 is a leap year, the date is: 01.02.2012

Please enter the year: 2015
Please enter the DOY you want to convert into the date: 31
2015 is a common year, the date is: 31.01.2015

Please enter the year: 2015
Please enter the DOY you want to convert into the date: 32
2015 is a common year, the date is: 01.02.2015

Laut https://en.wikipedia.org/wiki/Leap_year wird ein "Nicht-Schaltjahr" mit "common" bezeichnet.

Deinen Ansatz via "gmtime_r" und "tm" könnte man imho retten, wenn Du "tm_year" richtig setzen würdest, ich habe aber nicht die Muße das durchzutesten...


HTH

BigNum
 
Zurück
Oben