Kamil Izdebski Administrator sieci
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Udało Ci się stworzyć kod nieodczytywalny!Gratz!
Kamil Izdebski Administrator sieci
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Już znalazłem błędy, dzięki faktycznie namieszałem ;)))
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Nie masz za co dziękować - ale cieszę się że się udało :)Może podziel to na funkcje zanim pokażesz do oceny...Szymon Kubisiak edytował(a) ten post dnia 21.12.09 o godzinie 16:52
Adam
Woźniak
software architect
and developer
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Kamil Izdebski:
przesuwanie dat o zadaną liczbę dni
Jeśli to jest zadanie na zaliczenie to rozumiem, że dlatego implementujesz to ręcznie.
Jeśli nie jest to na zaliczenie, to osobiście pomyślałbym nad wsparciem się jakimiś dostępnymi bibliotekami (zamiast pisać ręcznie).
Pozdrawiam, Adam
Kamil Izdebski Administrator sieci
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Szymon Kubisiak:Tak podzielę, starałem się kod przedstawić w najprostszej postaci.
Nie masz za co dziękować - ale cieszę się że się udało :)
Może podziel to na funkcje zanim pokażesz do oceny
Adam Woźniak:Jest tylko częścią zaliczenia i z wykorzystaniem funkcji gotowych. Ja jednak swoje chcę napisać.
Jeśli to jest zadanie na zaliczenie to rozumiem, że dlatego implementujesz to ręcznie.
Jeśli nie jest to na zaliczenie, to osobiście pomyślałbym nad wsparciem się jakimiś dostępnymi bibliotekami (zamiast pisać ręcznie).
Siedzę i piszę, coraz trudniej mi się myśli. W razie problemów zgłoszę się z prośbą o pomoc.
PS. Właśnie opisywałem swój kolejny problem, lecz opisując go znalazłem rozwiązanie:).
Adam
Woźniak
software architect
and developer
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Kamil Izdebski:>Adam Woźniak:
Jeśli to jest zadanie na zaliczenie to rozumiem, że dlatego implementujesz to ręcznie.
Jest tylko częścią zaliczenia i z wykorzystaniem funkcji gotowych. Ja jednak swoje chcę napisać.
Ręczne operacje na datach to żmudna i niewdzięczna robota.
Np. trzeba jakoś uwzględnić lata przestępne:
http://pl.wikipedia.org/wiki/Rok_przest%C4%99pny#Algorytm
Pozdro, Adam
Kamil Izdebski Administrator sieci
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Tzn, mam daną jakaś datę w postaci DD-MM-YYYY i już napisałem funkcję, która konwertuje mi ją do unix time - czyli liczby sekund od 1.1.1970r. Teraz chcę przesunąć ją o X dni. Więc dodaję do unix time X*86400 sekund. Po czym trzeba ją konwertować w drugą stronę do "zapisu ludzkiego", czyli DD-MM-YYY.I tutaj zaczęły się schody, przede wszystkim nie wiem dlaczego jeśli mam przykładowo datę 22-3-1973 to po dodaniu liczby wskazującej na 30 lub 31 tego samego miesiąca on mi wypluwa 0 lub 1 następnego miesiąca. Skąd tam to 0 to nie wiem jeszcze.
Postaram się opisać działanie na zasadzie co jak wykonuję (kod też mogę pokazać).
Przykładowo mam taką tablicę tabRoznicyLat = {0,0,1} co by oznaczało, że 0 to rok zwykły, a 1 przestępny.
sekundy - przechowuje ilość sekund od 1.1.1970r (unix epoch)
rok_zwykly - liczba sekund dla roku nieprzestępnego
rok_przestepny - liczba sekund dla roku przestępnego
/* zlicza lata */
int liczLat=0, i=0;
while (sekundy>rok_zwykly || sekundy>rok_przestepny)
{
if (tabRoznicyLat[i]==0)
{
liczLat++;
sekundy-=rok_zwykly;
}
if (tabRoznicyLat[i]==1)
{
liczLat++;
sekundy-=rok_przestepny;
}
i++;
}
Wyjdzie nam liczba lat, które mineły od początku unix epoch więc trzeba dodać do wyniku 1970, czyli liczLat+1970.
Wciąż bazujemy na tej samej zmiennej sekundy (pomniejszonej).
Tablice dla roku zwykłego i przestępnego:
tMiesZ[12] = {l31,l28,l31,l30,l31,l30,l31,l31,l30,l31,l30,l31};
tMiesP[12] = {l31,l29,l31,l30,l31,l30,l31,l31,l30,l31,l30,l31};
Przykładowo l31 to liczba sekund dla miesiąca, który ma 31 dni.
/* zlicza miesiace */
int liczMiesiecy=0, licznik=0;
while(licznik<roznicaLat)
{
for (int i=0; i<12; i++)
{
if (tabRoznicyLat[licznik]==1) //to przestepny
{
if (sekundy>tMiesP[i])
{
liczMiesiecy++;
sekundy-=tMiesP[i];
}
}
else //nieprzestepny
{
if (sekundy>tMiesZ[i])
{
liczMiesiecy++;
sekundy-=tMiesZ[i];
}
}
}
licznik++;
}
No i do wyniku liczby miesięcy musimy dodać 1 bo funkcja ostatniego miesiąca nie uzna nam za pełny, który może się składać przykładowo z 10 dni.
l1 to 86400 sekund, czyli jeden dzień
/* zlicza dni */
int liczDni=0;
while (sekundy>=l1)
{
liczDni++;
sekundy-=l1;
}
I nie wiem dlaczego, ale nie działa mi to jak należy. Przykładowo jeśli mam datę 22-3-1973 w sekundach oczywiście i do niej dodaję dni to (marzec ma 31 dni):
1-6 //dodaje prawidłowo
7 //wyświetla mi datę 1.4.1973
8 //wyświetla mi datę 2.4.1973
9 //wyświetla mi datę 1.4.1973
10 //wyświetla mi datę 1.4.1973 odtąd już dobrze...
Nie mam pojęcia skąd takie wyniki.. a gdy rok zmienię na przestępny to jeszcze dzień 0 mi się pokazuje...Kamil Izdebski edytował(a) ten post dnia 21.12.09 o godzinie 19:24
Łukasz
C.
Senior Technical
Architect
Temat: [C++] przesuwanie dat o zadaną liczbę dni
e...?nie wiem czemu ale mam poczucie ze z tym bedzie latwiej i przyjemniej: http://pl.wikipedia.org/wiki/Data_Julia%C5%84ska
Kamil Izdebski Administrator sieci
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Nawet ciekawe, tylko co ma oznaczać, przykładowo Y = INT ((X + 32044,5) / 36524,25) = 67drugi znak przypisania? to komentarz? :-/
R – Rok
M – Miesiąc
D – Dzień
JD – Dni Juliańskie
W = JD + 0.5 = 2441925
X = INT (W) = 2441925
U = W – X = 0
Y = INT ((X + 32044,5) / 36524,25) = 67
Z = X + Y – INT (Y / 4) – 38 = 2441938
A = Z + 1524 = 2443462
B = INT ((A – 122,1) / 365,25) = 6689
C = A – INT (365,25 * B) = 305
E = INT (C / 30,61) = 9
F = INT (E / 14) = 0
R = B – 4716 + F = 1973
M = E – 1 – 12 * F = 8
D = C + U – INT (153 * E / 5) = 30
konto usunięte
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Ja używam daty w formacie Delphi - float o postaci "dzien.czesc_dnia".Część "dzien" to liczba całkowita określająca nr dnia np. od 1970 roku. Część "czesc_dnia" to "frakcja" dnia - np. 06:00 to coś ok. 0.25
Dzieki temu data + k wyglada tak:
moja_data data_nowa = data_stara + static_cast<double>(k);
Ułatwia to zresztą wiele rzeczy - np. operacje na czasie w tej dacie zawartym.
Łukasz
C.
Senior Technical
Architect
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Piotr Likus:data julianska ma wiecej mozliwosci, bo nie masz ograniczenia roku 1970, a idea ogolnie ta sama
Ja używam daty w formacie Delphi - float o postaci "dzien.czesc_dnia".
Jarosław
Rybski
Programista
C/C++/Python
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Nie ma co sobie życia utrudniać - wystarczy prosta klasa
class cDate
{
private:
int month;
int day;
int year;
static const int days[];
void incDay();
bool przestepnyRok( int _year ) const;
bool endMonth( int _day ) const;
public:
cDate(); // 1900.01.01
cDate( int y, int m, int d);
void addDays(int countDays);
};
i dalej
const int cDate::days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool cDate::przestepnyRok( int _year ) const
{
if ( _year % 400 == 0 || ( _year % 100 != 0 && _year % 4 == 0))
return true;
return false;
}
//----------
bool cDate::endMonth( int _day ) const
{
if ( month == 2 && przestepnyRok( year ))
return _day == 29;
return _day == days[ month ];
}
//----------
void cDate::addDays(int countDays)
{
for(int i = 0; i < countDays; i++)
{
incDay();
}
}
//----------
void cDate::incDay()
{
if (!endMonth( day ))
++day;
else
if ( month < 12 )
{
++month;
day = 1;
}
else
{
++year;
month = 1;
day = 1;
}
}
//----------
To będzie najprostsze rozwiązanie do zaimplementowaniaJarosław Rybski edytował(a) ten post dnia 22.12.09 o godzinie 10:05
Jakub L. Programista
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Dni ogólnie duzo nie ma jak na wydajność komputerów, ale oranie liniowo nie wydaje mi się najlepszym pomysłem.Podszedł bym do tego robiąc skoki o lata (dzielenie całkowite przez 365), później kroki o miesiąc i na końcu dzień, biorąc ewentualne korekty na lata przestępne.
Jarosław
Rybski
Programista
C/C++/Python
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Jakub L.:
Dni ogólnie duzo nie ma jak na wydajność komputerów, ale oranie liniowo nie wydaje mi się najlepszym pomysłem.
Podszedł bym do tego robiąc skoki o lata (dzielenie całkowite przez 365), później kroki o miesiąc i na końcu dzień, biorąc ewentualne korekty na lata przestępne.
Owszem jeśli mielibyśmy dodawać stulecia/tysiąclecia natomiast w pozostałych przypadkach to niech każdy już sobie odpowie
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Myślę że przeliczanie na unixtime nie jest najlepszym rozwiązaniem, gdyż zaczynają dochodzić sekundy przestępne z których część jest dodawana zupełnie arbitralnie decyzją komisji.konto usunięte
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Istnieje bardzo dobra biblioteka do tego celu. To DateUtils. Przesunięcie o zadaną liczbę dni zajmuje się funkcja IncDay(const TDateTime AValue, const int ANumberOfDays = 1).konto usunięte
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Mirosław Ślanda:
Istnieje bardzo dobra biblioteka do tego celu. To DateUtils. Przesunięcie o zadaną liczbę dni zajmuje się funkcja IncDay(const TDateTime AValue, const int ANumberOfDays = 1).
Albo cos bardziej znanego np. Boost Date Time.
Paweł
Zubrycki
Proszę oferty tylko
z widełkami
płacowymi na co
najwyżej ...
Temat: [C++] przesuwanie dat o zadaną liczbę dni
Jak wyżej, myślę, że lepiej uzyc Boosta:Paweł Zubrycki edytował(a) ten post dnia 15.01.10 o godzinie 00:17
#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>
int main(){
using namespace boost::posix_time;
using namespace boost::gregorian;
std::cout << "O ile dni przesunac? ";
long n;
std::cin >> n;
date d(day_clock::local_day());
std::cout << ( d + days(n) ) << std::endl;
return 0;
}
Następna dyskusja: