2015-12-16 6 views
6

Muszę przechowywać wiek (lata, miesiące, dni ... ewentualnie godziny, minuty, sekundy) użytkownika. Pracuję z C++ i zwiększam.Które klasy zwiększające powinny być używane do przechowywania ludzi w wieku

Nie jestem pewien, która klasa boost::posix_time (lub boost::date_time) powinienem użyć.

Próbowałem boost::posix_time::time_duration, ale nie jest to oczywiste, ponieważ nie ma konstruktora biorąc liczbę lat, to zaledwie kilka godzin, więc zrobiłam:

boost::posix_time::time_duration age = boost::posix_time::hours(24*365*ageInYears); 

Ale nie jestem pewien, że to dobra strategia, ponieważ wszystkie lata nie ma 365 dni ;-)

Próbowałem także boost::gregorian::date, ale to trudne, ponieważ ten nie pozwala na przechowywanie year przed 1400 (i to przechowuje datę, a nie czas).

  • Nie chcę przechowywać daty urodzenia użytkownika, ponieważ muszę przechowywać jego wiek, kiedy mój program był uruchomiony (dane medyczne).
  • Nie chcę przechowywać zwykłego int, ponieważ nie jest on wystarczająco dokładny (24 lata + 11 miesięcy to prawie 25).
  • Nie chcę przechowywać float bo nie chcę wyważać otwartych drzwi z pływakiem do nawrócenia wiekowej musiałbym zrobić ...

Czy naprawdę nie ma klasy, co ułatwia przechowywać wiele lat i opcjonalnie liczbę miesięcy i dni doładowania?

Idealnie dla faceta 30 lat i pół roku, chciałbym, aby móc utworzyć obiekt tak: boost::....... theAge(30, 6, 0); a następnie:

  • posiada funkcję, aby uzyskać wiek w latach: theAge.years() powrót 30 (pomijając miesięcy)
  • ewentualnie mieć konwersję do pływaka, który dałby mi 30.5 jako wiek
+0

"Nie chcę, aby zapisać datę urodzenia użytkownika" Tak więc obliczyć różnicę (CURRENT_TIME - date_of_birth) jako 'boost :: posix_time :: time_duration'. Nie sądzę, że 1400 jest prawdziwym ograniczeniem dla programu medycznego. –

+0

Problem polega na tym, że tak naprawdę nie znam daty urodzin pacjenta ... lekarz wprowadza bezpośrednio wiek jako dane wejściowe. – jpo38

+0

Jeśli lekarz wprowadzi wiek, obliczyć DOB z tego. –

Odpowiedz

4

Istnieje rzeczywiście rodzaje trwania w boost::gregorian, a konkretnie:

Idealnie nadają się do przechowywania, tj. Przechowują krotkę (lata, miesiące, dni).

Uwaga jednak, że arytmetyka stosując w szczególności months i years może mieć nieoczekiwane wyniki, ponieważ zapewniają one snap-to-end-of-miesiąca zachowanie:

months single(1); // 1 month duration 
date(2005,Feb,28) + single; // => 2005-Mar-31 

Edycja od właściciela OP: Jest rzeczywiście istniejąca struktura doładowania do przechowywania obiektów rok/miesiąc/dzień (boost::date_time::date_time::year_month_day_base).

Oto idealna realizacja odpowiedzieć OP:

class age : public date_time::year_month_day_base<years, months, days> 
{ 
    typedef date_time::year_month_day_base<years, months, days> baseClass; 
public: 
    age(int yearsCount, int monthsCount = 0, int daysCount = 0) : 
     baseClass(boost::gregorian::years(yearsCount), 
        boost::gregorian::months(monthsCount), 
        boost::gregorian::days(daysCount)) 
    { 
    } 

    inline int years() const { return year.number_of_years().as_number(); } 
    inline int months() const { return month.number_of_months().as_number(); } 
    inline int days() const { return day.days(); } 

    float getAsFloat() const 
    { 
     float age = static_cast<float>(years()); 
     age += months()/12.0f; 
     age += days()/365.25f; 
     return age; 
    } 
}; 

Następnie age(30).years() == 30 i age(30,6,8).getAsFloat() == 30.521902

+0

Niestety, ma to samo ograniczenie co użycie 'boost :: gregorian :: date' jako' boost :: gregorian :: years' odrzuca dowolną wartość <1400 ..... – jpo38

+0

@ jpo38 Jak dokładnie próbujesz użyć 'boost :: gregorian :: years'? Powinno to działać dobrze: http://coliru.stacked-crooked.com/a/478a0aa295da1c5a – ecatmur

+0

Próbowałem 'boost :: gregorian :: greg_year_month_day patientAge (30,0,0);' To potwierdza, że ​​rok musi być> 1400 i także dlatego, że miesiąc musi wynosić 1..12, a dzień musi wynosić 1..31. Więc powinienem użyć 'boost :: gregorian :: greg_year_month_day patientAge (1430,1,1);' by zakodować 30 lat ... nie bardzo wygodny. – jpo38

5

boost::posix_time::time_duration naprawdę jest jednym ze sposobów, aby to zrobić prawidłowo. Innym sposobem (który ja osobiście wolałbym) jest przechowywanie daty urodzenia i "daty aktualnej" zarówno, jak i odejmowanie ich, gdy trzeba znaleźć wiek jako tej daty.

W każdym razie nie potrzebujesz konstruktora, który zajmuje wiele lat - możesz po prostu odjąć date_rodziny od dzisiaj - jeśli zrobisz to za pomocą obiektów date_time, dostaniesz time_duration.