Δημοσιεύτηκε: 21 Ιουν 2011, 14:01
migf1 έγραψε:Προσπάθησα να στο απλοποιήσω, για ρίξε μια ματιά και πες μου (κάνω και έλεγχο μέσω των Ιουλιανών αριθμών ώστε να μη δέχεται 2η ημερομηνία μεγαλύτερη της 1ης στην είσοδο... επίσης χρειάζεται έλεγχος ώστε οι ημερομηνίες εισόδου να αντιστοιχούν σε έγκυρες ημερομηνίες, αλλά για να μη σε μπερδέψω με όλα μαζί θα το κάνω ξεχωριστά σε άλλο κώδικα).
[snip]clepto έγραψε:ρε συ μπορείς να μου δώσεις ένα πολύ απλό παράδειγμα χρήσης του αλγόριθμου μετατροπής ημερομηνίας σε Ιουλιανό αριθμό;
διάβασα τον κώδικα σου αλλά είναι λίγο δύσκολο να καταλάβω...
Αν δεν έχεις απορίες στον απλοποιημένο προηγούμενο κώδικα, μπορείς να δεις την παρακάτω έκδοσή του που κάνει ελέγχους για έγκυρες ημερομηνίες, υπολογίζει και τυπώνει ημέρες εβδομάδας, δίσεκτα έτη και προσθήκη/αφαίρεση ημερών στις 2 ημερομηνίες.
Επειδή το κομμάτι του κώδικα που τυπώνει καλλωπισμένη την κάθε ημερομηνία επαναλαμβάνεται συνεχώς, σε επόμενο post θα το κάνω συνάρτηση για να είναι πιο ευανάγνωστη η main
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE !FALSE
#define isleap(y) ( !((y) % 4) && ( (y) % 100 || !((y) % 400) ) )
// ---------------------------------------------------------------------------------
// Έλεγχος έγκυρης ημερομηνίας
//
int validdate( int d, int m, int y, int mdays[] )
{
if ( y < 1582 )
return FALSE;
if ( m < 1 || m > 12 )
return FALSE;
if ( d < 1 || d > mdays[ m-1 ] )
{
if ( isleap(y) && m == 2 && d == 29 )
return TRUE;
return FALSE;
}
return TRUE;
}
// ---------------------------------------------------------------------------------
// Μετατροπή ημερομηνίας d,m,y σε Ιουλιανό αριθμό
//
long int date_2jdn( int d, int m, int y )
{
return ( 1461 * ( y + 4800 + ( m - 14 ) / 12 ) ) / 4 +
( 367 * ( m - 2 - 12 * ( ( m - 14 ) / 12 ) ) ) / 12 -
( 3 * ( ( y + 4900 + ( m - 14 ) / 12 ) / 100 ) ) / 4 +
d - 32075;
}
// ---------------------------------------------------------------------------------
// Μετατροπή Ιουλιανού αριθμού σε ημερομηνία d,m,y
//
void jdn_2date( int *d, int *m, int *y, long int jdn )
{
long int l = jdn + 68569;
long int n = ( 4 * l ) / 146097;
l = l - ( 146097 * n + 3 ) / 4;
long int i = ( 4000 * ( l + 1 ) ) / 1461001;
l = l - ( 1461 * i ) / 4 + 31;
long int j = ( 80 * l ) / 2447;
*d = l - ( 2447 * j ) / 80;
l = j / 11;
*m = j + 2 - ( 12 * l );
*y = 100 * ( n - 49 ) + i + l;
return;
}
// ---------------------------------------------------------------------------------
int main( void )
{
int mdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char *daynames[7] = {"Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ", "Κυρ"};
char *monthnames[12] = { "ΙΑΝ", "ΦΕΒ", "ΜΑΡ", "ΑΠΡ", "ΜΑΙ", "ΙΟΥΝ", "ΙΟΥΛ", "ΑΥΓ", "ΣΕΠ", "ΟΚΤ", "ΝΟΕ", "ΔΕΚ"};
int d1, m1, y1, d2, m2, y2;
long int jdn1, jdn2;
// διάβασμα 1ης ημερομηνίας (απαίτηση να είναι έγκυρη)
do {
printf("\n1η ημερομηνία (η μ χ): ");
scanf("%d %d %d", &d1, &m1, &y1);
if ( !validdate( d1, m1, y1, mdays ) )
puts("\tάκυρη ημερομηνία, δοκιμάστε ξανά");
} while ( !validdate( d1, m1, y1, mdays ) );
jdn1 = date_2jdn( d1, m1, y1); // υπολογισμός Ιουλιανού αριθμού
printf( "\tΑντιστοιχεί σε: %s, %d %s %d (%ld) ",
daynames[ (jdn1 % 7) ], d1, monthnames[ m1-1], y1, jdn1
);
if ( isleap(y1) )
printf("ΔΙΣΕΚΤΟ ΕΤΟΣ");
putchar('\n');
// διάβασμα 2ης ημερομηνίας (απαίτηση να είναι έγκυρη και μικρότερη της 1ης)
do {
printf("\n2η ημερομηνία (η μ χ); ");
scanf("%d %d %d", &d2, &m2, &y2);
if ( !validdate( d2, m2, y2, mdays ) )
puts("\tάκυρη ημερομηνία, δοκιμάστε ξανά");
else {
jdn2 = date_2jdn( d2, m2, y2); // υπολογισμός Ιουλιανού αριθμού
if (jdn2 > jdn1)
puts("\tπρέπει να είναι μικρότερη της 1ης ημερομηνίας, δοκιμάστε ξανά");
}
} while ( !validdate(d2, m2, y2, mdays) || jdn2 > jdn1);
printf( "\tΑντιστοιχεί σε %s, %d %s %d (%ld) ",
daynames[ (jdn2 % 7) ], d2, monthnames[ m2-1], y2, jdn2
);
if ( isleap(y2) )
printf("ΔΙΣΕΚΤΟ ΕΤΟΣ");
putchar('\n');
// υπολόγισε τη διαφορά μεταξύ των ημερομηνιών σε ημέρες
printf("\n\nΟι ημερομηνίες απέχουν μεταξύ τους %ld ημέρες\n", jdn1-jdn2);
// υπολόγισε την ημερομηνία 10 μέρες πριν την 1η ημερομηνία
jdn_2date( &d1, &m1, &y1, jdn1-10);
printf("\n10 μέρες πριν από την 1η ημερομηνία είναι: %d %d %d\n", d1, m1, y1);
printf( "\tΑντιστοιχεί σε %s, %d %s %d (%ld) ",
daynames[ (jdn1-10) % 7 ], d1, monthnames[ m1-1], y1, jdn1-10
);
if ( isleap(y1) )
printf("ΔΙΣΕΚΤΟ ΕΤΟΣ");
putchar('\n');
// υπολόγισε την ημερομηνία 15 μέρες μετά τη 2η ημερομηνία
jdn_2date( &d2, &m2, &y2, jdn2+15);
printf("\n15 μέρες μετά από την 2η ημερομηνία είναι: %d %d %d\n", d2, m2, y2);
printf( "\tΑντιστοιχεί σε %s, %d %s %d (%ld) ",
daynames[ (jdn2+15) % 7 ], d2, monthnames[ m2-1], y2, jdn2+15
);
if ( isleap(y2) )
printf("ΔΙΣΕΚΤΟ ΕΤΟΣ");
putchar('\n');
printf("\npress ENTER to exit...");
fflush(stdin); getchar();
exit(0);
}