georginos1989 Δημοσ. 16 Ιανουαρίου 2012 Δημοσ. 16 Ιανουαρίου 2012 Θα ηθελα να μου πειτε ποια ειναι η λογικη της αναζητησης προηγουμενων ημερομηνιων σε ενα ημερολογιο.. Θελω να το δοκιμασω σε c++ Δλδ υπαρχει καποιο ετος αφετηριας και απο κει και μετα βρισκεις διαφορα με την ημερομηνια που θες και ετσι μετα μπορεις να υπολογισεις ημερομηνιες απο παλια ετη;
migf1 Δημοσ. 16 Ιανουαρίου 2012 Δημοσ. 16 Ιανουαρίου 2012 Θα ηθελα να μου πειτε ποια ειναι η λογικη της αναζητησης προηγουμενων ημερομηνιων σε ενα ημερολογιο.. Θελω να το δοκιμασω σε c++ Δλδ υπαρχει καποιο ετος αφετηριας και απο κει και μετα βρισκεις διαφορα με την ημερομηνια που θες και ετσι μετα μπορεις να υπολογισεις ημερομηνιες απο παλια ετη; Μεταφράζεις τις ημερομηνίες σε Julian Day Numbers, κι από εκεί και πέρα όλα τα υπόλοιπα είναι εύκολα 1. http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html 2. http://en.wikipedia.org/wiki/Julian_day
erimitis Δημοσ. 16 Ιανουαρίου 2012 Δημοσ. 16 Ιανουαρίου 2012 Για κοίταξε και αυτό #include <iostream> #include <ctime> #include <cstring> #include <string.h> #include <sstream> #define TRUE 1 #define FALSE 0 #include <fstream> #include <cstring> #include <sstream> #include <stdexcept> int StrToInt( const std::string& s ) { int result; std::istringstream ss( s ); ss >> result; if (!ss) throw std::invalid_argument( "StrToInt" ); return result; } int months_of_year[] = {31,28,31,30,31,30,31,31,30,31,30,31}; int is_leap_year(int year) { int result; if ( (year%4) != 0 ) // or: if ( year%4 ) result = FALSE; // means: if year is not divisible by 4 else if ( (year%400) == 0 ) // or: if ( !(year%400) ) result = TRUE; // means: if year is divisible by 400 else if ( (year%100) == 0 ) // or: if ( !(year%100) ) result = FALSE; // means: if year is divisible by 100 else // (but not by 400, since that case result = TRUE; // considered already) return ( result ); } int number_of_days_in_the_year(int year) { return(is_leap_year(year))? 366 : 365; } int number_of_days_till_now(int day,int mon,int year) { int i,sum=0; for (i=0;i<mon-1;i++) { sum+= months_of_year; } sum+= day; if(is_leap_year(year) && mon>2) sum++; return sum; } int Difference_Days(std::string s1,std::string s2){ char * pch; int d1,m1,y1,d2,m2,y2; std::string token, text(s1); std::istringstream iss(text); int flag=0; while ( getline(iss, token, '-') ){ if(flag ==0)d1=StrToInt(token); if(flag ==1)m1=StrToInt(token); if(flag ==2)y1=StrToInt(token); flag++; } std::string text2(s2); std::istringstream iss2(text2); flag=0; while ( getline(iss2, token, '-') ){ if(flag ==0)d2=StrToInt(token); if(flag ==1)m2=StrToInt(token); if(flag ==2)y2=StrToInt(token); flag++; } int first=number_of_days_till_now(d1,m1,y1); int secont=number_of_days_till_now(d2,m2,y2); if(y1==y2)return secont-first+1; return secont-first+1+number_of_days_in_the_year(y1); } int main() { std::string sa1 ="01-01-2012"; std::string sa2 ="28-1-2012"; std::cout<<"Exoyn diafora "<<sa1<<" me tin "<<sa2<<" "<<Difference_Days(sa1,sa2)<<" days\n"; std::cout<<"\n"; system("pause"); return 0; }
migf1 Δημοσ. 16 Ιανουαρίου 2012 Δημοσ. 16 Ιανουαρίου 2012 Αν δεν έχεις πρόβλημα να διαβάζεις C, μπορείς να δεις τον κώδικα ενός σχετικού προγράμματος που είχα γράψει παλαιότερα. Οι συναρτήσεις μετατροπής από και σε JDN είναι οι ακόλουθες: > ... typedef struct Date { // our date structure long int d; // 1-31 long int m; // 1-12 long int y; // 1752-9999 } Date; ... // ------------------------------------------------------------------------------------ // Convert a Gregorian date to a Julian Day count // IMPORTANT: accurate ONLY for dates after Oct 15, 1582 (Gregorian Calendar) // Algorithm by Henry F. Fliegel & Thomas C. Van Flandern: // http://www.hermetic.ch/cal_stud/jdn.htm#comp // long date_2jdn( Date date ) { return ( 1461 * ( date.y + 4800 + ( date.m - 14 ) / 12 ) ) / 4 + ( 367 * ( date.m - 2 - 12 * ( ( date.m - 14 ) / 12 ) ) ) / 12 - ( 3 * ( ( date.y + 4900 + ( date.m - 14 ) / 12 ) / 100 ) ) / 4 + date.d - 32075; } // ---------------------------------------------------------------------------------- // Convert a Julian Day count to a Gregorian date (d,m,y) // IMPORTANT: accurate ONLY for dates after Oct 15, 1582 (Gregorian Calendar) // Algorithm by Henry F. Fliegel & Thomas C. Van Flandern: // http://www.hermetic.ch/cal_stud/jdn.htm#comp // Date *jdn_2date( Date *date, long jd ) { long l = jd + 68569; long n = ( 4 * l ) / 146097; l = l - ( 146097 * n + 3 ) / 4; long i = ( 4000 * ( l + 1 ) ) / 1461001; l = l - ( 1461 * i ) / 4 + 31; long j = ( 80 * l ) / 2447; date->d = l - ( 2447 * j ) / 80; l = j / 11; date->m = j + 2 - ( 12 * l ); date->y = 100 * ( n - 49 ) + i + l; return date; } ...
erimitis Δημοσ. 17 Ιανουαρίου 2012 Δημοσ. 17 Ιανουαρίου 2012 Πολύ καλή δουλειά όμως όταν έτρεξα το αρχείο βγάζει σφάλμα undefined reference to "islank"
migf1 Δημοσ. 17 Ιανουαρίου 2012 Δημοσ. 17 Ιανουαρίου 2012 Πολύ καλή δουλειά όμως όταν έτρεξα το αρχείο βγάζει σφάλμα undefined reference to "islank" Αν εννοείς το dates, ευχαριστώ Σε μένα τρέχει μια χαρά όμως. Το ξανακατέβασα μόλις τώρα επί τούτου για να το δοκιμάσω (κι από το site κι από το ideone.com) και κάνει κανονικά compile... το δοκίμασα και με mingw gcc και με pelles-c. Το μόνο που βγάζει είναι 3 προειδοποιήσεις για αχρησιμοποίητα ορίσματα στις συναρτήσεις: print_diffs() & main().
migf1 Δημοσ. 20 Ιανουαρίου 2012 Δημοσ. 20 Ιανουαρίου 2012 Πολύ καλή δουλειά όμως όταν έτρεξα το αρχείο βγάζει σφάλμα undefined reference to "islank" ... Σε μένα τρέχει μια χαρά όμως. ... Επειδή ξεκίνησα μια σχεδόν πλήρη αναθεώρηση στην αρχιτεκτονική του κώδικα, καθώς και μετατροπή του σε πλήρη συμβατότητα με το C89, είδα πως τελικά το μήνυμα που παίρνεις είναι από την: isblank() η οποία δεν υπάρχει στο C89. Μπορείς είτε να την αντικαταστήσεις με την isspace() είτε να ενεργοποιήσεις στον compiler σου τη συμβατότητα με C99... αν έχεις οποιαδήποτε παραλλαγή του gcc, προσέθεσέ του στη γραμμή εντολών το flag: -std=c99. Π.χ... > gcc -std=c99 dates.c -o dates.exe αν είσαι σε Windows ή > gcc -std=c99 dates.c -o dates αν είσαι σε Unix/Linux ΥΓ. Σε 1-2 μέρες θα ανεβάσω έκδοση 3.6 του κώδικα που θα είναι πλήρως συμβατός με C89.
migf1 Δημοσ. 22 Ιανουαρίου 2012 Δημοσ. 22 Ιανουαρίου 2012 ... ΥΓ. Σε 1-2 μέρες θα ανεβάσω έκδοση 3.6 του κώδικα που θα είναι πλήρως συμβατός με C89. Έτοιμο, λεπτομέρειες για τις αλλαγές καθώς και link κατεβάσματος του κώδικα: http://x-karagiannis.gr/prog/libs/content/misc/other/dates/dates.php
migf1 Δημοσ. 25 Ιανουαρίου 2012 Δημοσ. 25 Ιανουαρίου 2012 Μιας και το 'πιασα, του έκανα μερικές ακόμα προσθήκες, με σημαντικότερες: α) την αλλαγή των σχολίων σε μορφή αναγνωρίσιμη από το το Doxygen, για αυτοματοποίηση στη δημιουργία πλήρους τεκμηρίωσης (overkill για το συγκεκριμένο πρόγραμμα, αλλά χρήσιμο ως λειτουργικό παράδειγμα όσων θελήσουν να ασχοληθούν με Doxygen). β) μεγαλύτερη ευελιξία στη διαχείριση της γραμμής εντολών Παραθέτω κι ένα απόσπασμα από την περιγραφή της έκδοσης 3.65 στη σελίδα του προγράμματος, το οποίο πιστεύω είναι χρήσιμο σε όσους θέλουν να υλοποιήσουν ημερολόγια μόνοι τους... ... Είναι σημαντικό να γνωρίζετε πως το Γρηγοριανό Ημερολόγιο υιοθετήθηκε από την Ελλάδα το 1923, ενώ αλλάχτηκε ξανά το 1924 σε μια παραλλαγή γνωστή ως Revised Julian Calendar. Το link αυτό εξηγεί τις λεπτομέρειες, με σημαντικότερη το ότι το 2800 τα δυο ημερολόγια θα αρχίσουν να αποκλίνουν. Οπότε για να έχετε αξιόπιστα αποτελέσματα για γεγονότα που συνέβησαν στην Ελλάδα πριν από αυτές τις ημερομηνίες θα πρέπει να χρησιμοποιήσετε άλλα προγράμματα ή/και μονάδες μέτρησης. Οι Ιουλιανοί αριθμοί που χρησιμοποιεί το DATES είναι αξιόπιστες μονάδες μέτρησης για την περίοδο που καλύπτει το ημερολόγιό του, αλλά δεν ισχύει το ίδιο για τις "χαμένες" ημέρες ως νούμερα και τις ημέρες της εβδομάδας που τους αντιστοιχούν. Το πρόβλημα παραμένει και για όλες τις υπόλοιπες χώρες που ακολουθούν το Γρηγοριανό ημερολόγιο, όχι μόνο επειδή το υιοθέτησαν σε διαφορετικές ημερομηνίες, αλλά κι επειδή κατά τη διαδικασία της αλλαγής αφαιρέθηκε διαφορετικός αριθμός ημερών. Για παράδειγμα, η Αγγλική μετατροπή που έγινε στις 14 Σεπ 1752 αφαίρεσε 10 ημέρες, με αποτέλεσμα οι ημερομηνιες από την 5 Σεπ 1752 έως και την 13 Σεπ 1752 να μην υπάρχουν στο Αγγλικό ημερολόγιο. Αλλά η Ελλάδα και η Ρωσσία που υιοθέτησαν το Γρηγοριανό ημερολόγιο το 1923 αφαίρεσαν 13 ημέρες... και πάει λέγοντας και για τις υπόλοιπες χώρες. ... Εδώ η σχετική ενότητα της τεκμηρίωσης στα Αγγλικά, που είναι λίγο πιο αναλυτική: http://x-karagiannis...ndex.html#Intro Θα ήθελα κάποια στιγμή να του προσθέσω και δυνατότητα απεικόνισης ημερομηνιών σύμφωνα με το Ιουλιανό ημερολόγιο, καθώς και υποστήριξη εορτολογίων (πιθανότατα με διάβασμά τους από αρχεία κειμένου με τη βοήθεια κάποιου command line flag, μιας και τα εορτολόγια διαφέρουν από χώρα σε χώρα). Θέλουν αρκετή δουλειά όμως, οπότε δεν ξέρω πότε κι εάν θα το κάνω.
migf1 Δημοσ. 27 Ιανουαρίου 2012 Δημοσ. 27 Ιανουαρίου 2012 ... Θα ήθελα κάποια στιγμή να του προσθέσω και δυνατότητα απεικόνισης ημερομηνιών σύμφωνα με το Ιουλιανό ημερολόγιο, καθώς και υποστήριξη εορτολογίων (πιθανότατα με διάβασμά τους από αρχεία κειμένου με τη βοήθεια κάποιου command line flag, μιας και τα εορτολόγια διαφέρουν από χώρα σε χώρα). Θέλουν αρκετή δουλειά όμως, οπότε δεν ξέρω πότε κι εάν θα το κάνω. Για να μην ανοίγω νέο νήμα, αντί για τα παραπάνω ξεκίνησα να του βάζω υποστήριξη για χρώματα... Μοβ : δίσεκτα έτη Γαλάζιο : μη δίσεκτα έτη Κόκκινο: αργίες Κίτρινο: σημερινή μέρα & διαφορά μεταξύ ημερομηνιών * τα συγκεκριμένα είναι πολύ πιο ευδιάκριτα σε μαύρο φόντο. Αντί να χρησιμοποιήσω full-blown βιβλιοθήκες (όπως π.χ. την curses) ξεκίνησα να φτιάχνω ένα header file (con_color.h το λέω προς το παρόν) για cross-platform υποστήριξη χρωμάτων κονσόλας σε Windows και Linux/Unix. Αν τα Windows παρείχαν υποστήριξη σε ANSI escape characters, όπως κάνει πλέον η συντριπτική πλειοψηφία τερματικών σε Linux/Unix θα ήταν πολύ πιο απλό, αλλά δυστυχώς δεν υποστηρίζει. Σας παραθέτω το header file, για να πειραματιστείτε και μόνοι σας όσοι ενδιαφέρεστε: http://ideone.com/AWC0z Διαβάστε όμως τη συνέχεια του μηνύματος (και των spoilers) για να καταλάβετε πως δουλεύει και πως μπορείτε να το χρησιμοποιήσετε για να γράφετε cross-platform πηγαίο κώδικα με αυτό. Το DOS/command.com υποστήριζε μέσω του ANSI.SYS drivers για όσους το θυμούνται, το οποίο όμως από XP και μετά καταργήθηκε (μαζί με το DOS). Υπάρχει ένα εξαιρετικό προγραμματάκι που προσθέτει ANSI υποστήριξη στη κονσόλα του XP και μετά (ANSICON λεγεται, ψάξτε το να το κατεβάσετε, είναι πολύ καλό... έχει και option να γίνεται hooked στο cmd.exe αν θέλετε). Το header file είναι σε πολύ αρχικό στάδιο, ίσα-ίσα για να κάνω τη δουλειά μου... (π.χ. του έχω μόνο χρώματα, και όχι άλλα text attributes όπως bold, italics, κλπ, ή editing support, όπως π.χ. μετακίνηση δρομέα, κλπ). Επίσης χρησιμοποιεί 4 καθολικές μεταβλητές (μόνο όταν γίνει compile σε περιβάλλον Windows) τα ονόματα των οποίων δεν είναι ασυνήθιστα ως οφείλουν να είναι για να μη "συγκρούονται" με ονόματα κανονικών μεταβλητών στα προγράμματα που χρησιμοποιούν το con_color.h. Αυτά θα τα δω πιο μετά. Το βασικό HL macro είναι το ... > CONOUT_PRINTF( fg, bg, ... ) που είναι variadic, άρα κανονικά θέλει C99 enabled compiler (αλλά οι περισσότεροι υποστήριζαν έτσι κι αλλιώς variadic macros από πριν). Αν είστε σε Windows πρέπει να χρησιμοποιήστε 2 ακόμα HL macros, ένα για αρχικοποίηση στην αρχή των προγραμμάτων σας (που αποθηκεύει την τρέχουσα κατάσταση της κονσόλας), κι ένα στο τέλος για την επαναφορά της κονσόλας στην κατάσταση που είχε πριν ξεκινήσετε να... χρωματίζετε > #include "con_color.h" ... CONOUT_INIT(); CONOUT_PRINTF( FG_CYAN, BG_NOCHANGE, "Hello world\n" ); printf( "Here is a "); CONOUT_PRINTF( FG_RED, BG_NOCHANGE, "red" ); printf( " word, and here is some " ); CONOUT_PRINTF( FG_DARKGREEN, BG_GRAY, "dark-green text on gray foreground\n" ); CONOUT_RESTORE(); ... Αν δουλεύετε σε Lιnux/Unix περιβάλλον, τότε δεν χρειάζεστε καν τα CONOUT_INIT() και CONOUT_RESTORE() ... > #include "con_color.h" ... CONOUT_PRINTF( FG_CYAN, BG_NOCHANGE, "Hello world\n" ); printf( "Here is a "); CONOUT_PRINTF( FG_RED, BG_NOCHANGE, "red" ); printf( " word, and here is some " ); CONOUT_PRINTF( FG_DARKGREEN, BG_GRAY, "dark-green text on gray foreground\n" ); ... καλό είναι να τα βάζετε όμως για να λειτουργεί σωστά ο κώδικάς σας κι όταν γίνεται compile σε Windows. Αν θέλετε να παίξετε με πιο LL macros, τότε είναι λίγο πιο πολύπλοκο. Εν ολίγοις, αν θέλετε να πειραματιστείτε με τα 3-4 LL macros, η πιο συνηθισμένη σειρά τους πάει ως εξής: > CONOUT_SET_COLOR( fgColor ); CONOUT_ADD_COLOR( bgColor ); printf( "blablab" ); CONOUT_RESET(); Το CONOUT_SET_COLOR() σώζει την τρέχουσα κατάσταση της κονσόλας πριν θέσει το χρώμα που του ορίσατε, ενώ το CONOUT_ADD_COLOR( ) απλά προσθέτει κι άλλο χρώμα πάνω σε αυτό του που έχει θέσει το CONOUT_SET_COLOR() (ή οποιαδήποτε άλλο CONOUT_ADD_COLOR() μεταγενέστερο του CONOUT_SET_COLOR(). Όταν τυπώσετε κάτι (στα χρώματα που ορίσατε), πρέπει να επαναφέρετε την κονσόλα στην κατάσταση που είχε πριν το τύπωμα, ώστε το επόμενο τύπωμα να γίνει με εκείνα τα χρώματα ... οπότε πρέπει να κάνετε CONOUT_RESET(). Η ανάγκη για SET; ADD; ADD; ... RESET; προκύπτει από τον τρόπο που διαχειρίζονται τα Windows τα χρώματα της κονσόλας (ουσιαστικά, είναι ένα bitmap flag, στο οποίο μπορείτε να μιξάρετε πολλά χρώματα με χρήση του binary operator | ). Στο ANSI από την άλλη μεριά, το κάθε χρώμα είναι μια ακολουθία χαρακτήρων, οπότε δεν μπορούμε να μιξάρουμε χρώματα. Για αυτό και οι ANSI εκδοχές των CONOUT_SET_COLOR() και CONOUT_ADD_COLOR() έχουν ακριβώς ίδιο κώδικα. Στο ANSI έχουν νόημα 2 μόνο κλήσεις... μια για το χρώμα προσκηνίου και μια για το χρώμα παρασκηνίου, με οποιοδήποτε από τα 2 παραπάνω macros(). Εν ολίγοις, για να είναι εντάξει ο κώδικάς σας και στα 2 modes (ANSI, Windows) χρησιμοποιήστε μονάχα τη σειρά που δείχνω παραπάνω... 1. μια κλήση του SET με χρώμα προσκηνίου 2. μια κλήση στην ADD με χρώμα φόντου 3. τύπωμα με συνάρτηση της C 4. RESET για περαιτέρω τύπωμα Ουσιαστικά, αυτό κάνει το HL macro: CONOUT_PRINTF() οπότε είναι σαφώς ευκολότερο (και συνιστώμενο) να χρησιμοποιείτε απευθείας αυτό! Κι ένα τελευταίο... Αν θέλετε να δοκιμάσετε το ANSI mode σε Windows (με χρήση του ANSICON προγράμματος που αναφέρω παραπάνω) τότε στη γραμμή 16 του κώδικα του con_color.h αλλάξτε το... > #if 0 /* change to 1 to FORCE ANSI mode (for Windows you need: ansicon.exe)*/ σε ... > #if 1 /* change to 1 to FORCE ANSI mode (for Windows you need: ansicon.exe)*/
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα