amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Tagesdifferenz berechnen [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

14.02.2007, 23:52 Uhr

MaikG
Posts: 5172
Nutzer
Ich hab ein Beispiel aus einem Buch genommen um die Differenz
von 2 Daten zu berechnen:

(T=Tag, M=Monat, J=Jahr)

code:
incr m
If m>=4 then 830
m=m+12:decr j
830 n=int(j*365,25)*Int(m*30.6001)+t


Aus faulheit hab ich irgendwie mal nur die letzte zeile genommen,
ich dachte das wird schon gehen.

Aber es geht z.B. für den 31.12.2006 und den 01.01.2007 nicht,
zweiteres Ergebniss ist größer als das erste.

Es gehts ja um die Anzahl der Tage seit Zeitzählung.
Der wert 30.6001 scheint mir nicht korrekt, 365,25/12=30.4375,
nochmal durchgerechnet und die die Ergebnisse der beiden Tage
sind jetzt immerhin gleich für meine zwecke würde das reichen.

Wäre die Rechnung so richtig? Ich meine warum steht das in dem
Buch dann so kompliziert?

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 00:18 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Also so einfach wirst du das nicht hinbekommen, weil z.B. die Anzahl der Tage in einem Jahr nicht wirklich 365.25 ist, die Rechnung ist wohl etwas komplizierter weil die 365.25 ja so eine Art korrektur für die Schaltjahre beinhaltet die nur Annährend funktioniert.

365.25 würde für die Tage seit begin der Zeitrechnung nur stimmen, wenn jedes 4te Jahr wirklich ein Schaltjahr wäre, allerdings sind alle durch 100 Teilbaren Jahre keine Schaltjahre, durch 400 jedoch schon, der Faktor 30.6001 erscheint mir auch komisch, aber da ist ja noch so ne Komische Rechnung davor, die für mich undurchsichtig ist.

Für mein Tool habe Ich so eine Funktion mal geschrieben, aber die ist ziemlich Lang, vieleicht gibt's wirklich eine Einfachere "formel"


[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 09:08 Uhr

DrNOP
Posts: 4118
Nutzer
Zitat:
Original von MaikG:
Der wert 30.6001 scheint mir nicht korrekt, 365,25/12=30.4375,

Ich hab' zuallererst einmal Probleme mit deiner Kommasetzung. Vielleicht willst du dich ja entscheiden, ob du ein Dezimalkomma oder einen Dezimalpunkt benutzen willst?
Also 365,25/12=30,4375 oder 365.25/12=30.4375?

Zitat:
Original von MaikG:
Aber es geht z.B. für den 31.12.2006 und den 01.01.2007 nicht,
zweiteres Ergebniss ist größer als das erste.

Der 1.1.07 ist doch auch später als der 31.12.06, da muß das Ergebnis doch auch größer sein? Exakt um einen Tag größer?
--
Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 09:31 Uhr

Solar
Posts: 3680
Nutzer
Wenn Du Datumsberechnung richtig machen willst, ist das kein Einzeiler. Vor allem dann nicht, wenn Du über das Mittelalter hinaus in die Vergangenheit willst, denn der Kalender hat sich vormals diverse Male geändert.

Wer auch immer sich diese "Näherungsbrüche" ausgedacht hat, sollte die Finger von ernsthafter Programmierung lassen. 30.6001 als Näherung für die Länge eines Monats? Um Himmels willen...

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 10:09 Uhr

MaikG
Posts: 5172
Nutzer
>365.25 würde für die Tage seit begin der Zeitrechnung nur stimmen,
>wenn jedes 4te Jahr wirklich ein Schaltjahr wäre,

Also ist schon die Jahreszahl falsch.


Also 365,25/12=30,4375 oder 365.25/12=30.4375?

zweites.

>Der 1.1.07 ist doch auch später als der 31.12.06, da muß das
>Ergebnis doch auch größer sein? Exakt um einen Tag größer?

Ja, weil INT ist eine Rundung auf eine ganzzahl.


2006 = 732692, 12=367, 31=31 entspricht 733090
2007 = 733057, 1=31, 1=1 entspricht 733089


>Wenn Du Datumsberechnung richtig machen willst, ist das kein
>Einzeiler. Vor allem dann nicht, wenn Du über das Mittelalter
>hinaus in die Vergangenheit willst, denn der Kalender hat sich
>vormals diverse Male geändert.

Nein, soweit muss ich nicht zurück 1978 ist vollkommen ausreichend.

>Wer auch immer sich diese "Näherungsbrüche" ausgedacht hat, sollte
>die Finger von ernsthafter Programmierung lassen. 30.6001 als
>Näherung für die Länge eines Monats? Um Himmels willen...

Es steht in einem alten Buch, das Programm war wohl für ein KC85,
der hat vielleicht auch gewisse Einschränkungen bei Fließkommazahlen.

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 10:24 Uhr

melior
Posts: 160
Nutzer
@MaikG:

Warum läßt Du denn nicht das AmigaOS (utility.library: Amiga2Date, CheckDate) die Aufgabe erledigen?

Tschüß André

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 11:31 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Hier mal ein Code, den Ich vor einiger Zeit geschrieben habe. OK ist ziemlich lang, aber Ich bin nicht so der Optimizer.

das 2te Datum muß nach dem ersten liegen, es dürfte aber nicht so schwer sein das zu ändern.

GetDB2Dates(day1,month1,year1, day2, month2, year2);

liefert (oder sollte liefern) die Tage zwischen zwei Daten
c code:
int getDaysMonth(int year, int month) {
       switch (month) {
           case 1:
               return 31;
               break;
           case 2:
               if ((year % 400) == 0) return 29;
               if ((year % 100) == 0) return 28;
               if ((year % 4) == 0) return 29;
               return 28;
               break;
           case 3:
               return 31;
               break;
           case 4:
               return 30;
               break;
           case 5:
               return 31;
               break;
           case 6:
               return 30;
               break;
           case 7:
               return 31;
               break;
           case 8:
               return 31;
               break;
           case 9:
               return 30;
               break;
           case 10:
               return 31;
               break;
           case 11:
               return 30;
               break;
           case 12:
               return 31;
               break;
       }
   }

   int getDaysYear(int year) {
       if ((year % 400) == 0) return 366;
       if ((year % 100) == 0) return 365;
       if ((year % 4) == 0) return 366;
       return 365;
   }

   int DB2Dates(int d1, int m1, int y1, int d2, int m2, int y2);
   
   unsigned int GetDB2Dates(int d1, int m1, int y1, int d2, int m2, int y2) {
       unsigned int days = 0, i;

       if ((m1 == m2) && (y1 == y2) && (d1 == d2)) return 0;
       if ((m1 == m2) && (y1 == y2)) {
           days = d2 - d1;
           if (days > 0) return days; else return 0;
       } else if (y1 == y2) {
           if (m1 > m2) return 0;
           days += getDaysMonth(y1, m1) - d1;
           for (i = m1+1; i <= (m2-1); i++) days += getDaysMonth(y1, i);
           days += d2;
        
       } else {
           days += DB2Dates(d1, m1, y1, 31, 12, y1);
           for (i = y1+1; i <= (y2-1); i++) days += getDaysYear(i);
           days += DB2Dates(1, 1, y2, d2, m2, y2);
           days++;
       }
    
       return days;
   }

   int DB2Dates(int d1, int m1, int y1, int d2, int m2, int y2) {
       if (y2 < y1) return -GetDB2Dates(d2, m2, y2, d1, m1, y1);
       if (m2 < m1) return -GetDB2Dates(d2, m2, y2, d1, m1, y1);
       if (d2 < d1) return -GetDB2Dates(d2, m2, y2, d1, m1, y1);
       return GetDB2Dates(d1, m1, y1, d2, m2, y2);
   }


[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 12:39 Uhr

p-OS
Posts: 131
Nutzer
Also, wenn du ne einfache Lösung suchst, sieh dir mal die date.library an.
Die beinhaltet ein umfangreiches Repertoire an Funktionen für Datumsberechnungen. Läßt sich als shared library auch in den meisten Programmiersprachen nutzen.

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 13:05 Uhr

MaikG
Posts: 5172
Nutzer
>Warum läßt Du denn nicht das AmigaOS (utility.library: Amiga2Date,
>CheckDate) die Aufgabe erledigen?

Mh, die arbeiten aber mit 1978 oder? Und der 20xx Bug wurde ja auch
noch nicht behoben.


>Hier mal ein Code, den Ich vor einiger Zeit geschrieben habe. OK
>ist ziemlich lang, aber Ich bin nicht so der Optimizer.

Wow, ist ja ganz schön komplex sowas. Muss ich mal sehen, die Funktion
wird ja relativ häufig aufgerufen.


[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 14:32 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Zitat:
Original von MaikG:
>Warum läßt Du denn nicht das AmigaOS (utility.library: Amiga2Date,
>CheckDate) die Aufgabe erledigen?

Mh, die arbeiten aber mit 1978 oder? Und der 20xx Bug wurde ja auch
noch nicht behoben.


beheben kannst du Ihn sowieso nicht, da ein ULONG eben nur eine bestimmte Anzahl an Sekunden aufnehmen kann, einen Jhar 2000 Bug hatte das AOS aber sowieso nicht, mit Vorzeichenbehaftung dürfte das aber bis ca. 2040 mit ULONG funktionieren, wenn man wirklich daran glauben will das das AOS dann noch existiert.


[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 14:35 Uhr

melior
Posts: 160
Nutzer
Zitat:
>>Warum läßt Du denn nicht das AmigaOS (utility.library: Amiga2Date,
>>CheckDate) die Aufgabe erledigen?

>Mh, die arbeiten aber mit 1978 oder?

Das stimmt. Weiter oben hast Du doch aber geschrieben, daß das ausreichend ist.

>Und der 20xx Bug wurde ja auch noch nicht behoben.

Hast Du dafür ein Beispiel?


Ich habe mal in meinen Sourcen gekramt ein kleines Testprogramm geschrieben:

21.(0)Work:Oberon2> bin/Kalendertest 31-Dec-06 01-Jan-07
86400 s
1440 min
24 h
1 d
21.(0)Work:Oberon2> bin/Kalendertest 31-Dec-06 02-Jan-07
172800 s
2880 min
48 h
2 d
21.(0)Work:Oberon2>

So weit so gut, oder?

Tschüß André

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 15:34 Uhr

MaikG
Posts: 5172
Nutzer
>beheben kannst du Ihn sowieso nicht, da ein ULONG eben nur eine
>bestimmte Anzahl an Sekunden aufnehmen kann, einen Jhar 2000 Bug
>hatte das AOS aber sowieso nicht, mit Vorzeichenbehaftung dürfte
>das aber bis ca. 2040 mit ULONG funktionieren, wenn man wirklich
>daran glauben will das das AOS dann noch existiert.

In einen voll Kompatiblen weg kann man das sicherlich nicht beheben,
aber zukünftig(was bei OS3.9 hätte schon geschehen sollen) könnte
man z.B. eine weitere ULONG verwenden die das Programm dann hinzuaddieren
muss.


>Ich habe mal in meinen Sourcen gekramt ein kleines Testprogramm
>geschrieben:

Also müsste ich in dem fall der utility.library einen Tag geben
und bekomme dann Tage, Stunden, Minuten und Sekunden zurück welche
ich dann zusammenrechnen muss?

>So weit so gut, oder?

Ja, das scheint korrekt zu Funktionieren.

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 16:23 Uhr

melior
Posts: 160
Nutzer
Zitat:
Also müsste ich in dem fall der utility.library einen Tag geben
und bekomme dann Tage, Stunden, Minuten und Sekunden zurück welche
ich dann zusammenrechnen muss?


Du übergibst der utility.library ein Datum (= mit Tag, Monat und Jahr ausgefüllte Struktur "ClockData"). Daraus berechnet Dir die Library die Anzahl der Sekunden seit dem 1.1.1978. Wenn Du das mit 2 Datumswerten machst, bekommst Du mit Differenz zwischen den beiden Sekundenwerten den Abstand zwischen Datum1 und Datum2 in Sekunden. Na und das mußt Du nur noch durch 60 (min), 60 (h) und 24 (d) teilen.

Tschüß André

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 17:48 Uhr

MaikG
Posts: 5172
Nutzer
mh, die Struktur ist nirgens beschrieben.

Ist das korrekt?

code:
'$INCLUDE utility.bh
'$INCLUDE Exec.bh

LIBRARY OPEN "exec.library"
LIBRARY OPEN "utility.library"


tCD&=AllocVec&(ClockData_sizeof% ,MEMF_CLEAR&)
POKEW tCD&  +sec%, 0
POKEW tCD&  +min_%, 0
POKEW tCD&  +hour%, 0
POKEW tCD&  +mday%, 31
POKEW tCD&  +month%, 12
POKEW tCD&  +year%, 2006
POKEW tCD&  +wday%, 0

PRINT  Date2Amiga&(tCD&)


FreeVec tCD&


nicht das ich jetzt irgendwo Word reinschreibe und Long wird
benötigt oder so.

[ - Antworten - Zitieren - Direktlink - ]

15.02.2007, 18:37 Uhr

melior
Posts: 160
Nutzer
Zitat:
mh, die Struktur ist nirgens beschrieben.

Im NDK 3.1 gibt es date.h:

struct ClockData
{
UWORD sec;
UWORD min;
UWORD hour;
UWORD mday;
UWORD month;
UWORD year;
UWORD wday;
};

Zitat:
Ist das korrekt?

Sieht gut aus, wenngleich ich mich nicht als Basic-Fachmann bezeichnen möchte. ;-)

Tschüß André

[ - Antworten - Zitieren - Direktlink - ]

16.02.2007, 00:16 Uhr

MaikG
Posts: 5172
Nutzer
>Im NDK 3.1 gibt es date.h:

Na das muss man erstmal finden...
Okay alles Word also, dann ist es richtig.
Gut, dann werde ich das mal Implementieren.
Danke @all


[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Tagesdifferenz berechnen [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.