Zum neuen Informatik-Forum >>
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Datumsarithmetik
Gehe zu Seite 1, 2  Weiter
 
Dieses Forum ist gesperrt, du kannst keine Beiträge editieren, schreiben oder beantworten.   Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten.    Informatikerboard.de Foren-Übersicht -> Perl
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Nyckelpiga



Anmeldungsdatum: 18.07.2006
Beiträge: 1

BeitragVerfasst am: 18. Jul 2006 21:19    Titel: Datumsarithmetik Antworten mit Zitat

Würde mir gerne ein Programm schreiben, dass mir für jedes Datum vom 1.1.1 bis 31.12.2999 die Quersumme in der Form ausrechnet:
Tag + Monat + Jahr = Zahl
Z+a+h+l = Quersumme
Falls Quersumme > 21 bilde weitere Quersumme

Bsp.: 27.06.1967
27 + 6 + 1967 = 2000
2 + 0 + 0 + 0 = 2
if 2 < 22 then goto Ende

Bsp.: 26.06.1967
26 + 6 + 1967 = 1999
1 + 9 + 9 + 9 = 28
if 28 < 22 then goto Ende
else 2 + 8 = 10

usw. Wie gesagt hätte ich gerne für alle existierenden Daten eine Quersumme kleiner 22.

Ich kann in Perl programmieren, gibt es da evtl. ein paar schicke Module die sowas erleichtern, habe keine Lust die ganze Datumslogik mit den Schaltjahren usw. selber zu schreiben? Ich dachte es sollte sowas geben, da sage ich erstmal einfach: "Gib mir alle realen Daten seit 1.1.1 bis 31.12.2999," dann rechne ich die Quersumme aus für jedes einzelne davon und schreibe alles schick formatiert raus in eine Datei.

Klingt das gut? Hat jemand sowas schon einmal gemacht, oder so was ähnliches und welches Modul von Perl sollte ich dazu verwenden? Gibt es vielleicht auch ein Quersummenmodul? Was heisst Quersumme in englisch?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Thomas
Administrator


Anmeldungsdatum: 13.02.2005
Beiträge: 208

BeitragVerfasst am: 18. Jul 2006 22:00    Titel: Antworten mit Zitat

Thema dazu im Matheboard:

http://www.matheboard.de/thread.php?threadid=37285
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
as_string



Anmeldungsdatum: 24.02.2006
Beiträge: 80
Wohnort: Heidelberg

BeitragVerfasst am: 19. Jul 2006 03:03    Titel: Antworten mit Zitat

Hallo,

Also, in Perl gibt's ja die Funktion "localtime()", die Du auch mit einem Argument aufrufen kannst, das der Unixzeit entspricht. Wenn Du das immer um 3600*24 Sekunden erhöhst, dann bekommst Du ja nach und nach alle Daten. Die Funktion liefert ein Array zurück, das auch Tag, Monat und Jahr enthält. Ich weiß allerdings nicht, in welchem Bereich man die Funktion verwenden kann. Das steht aber sicher irgendwo.

Für die Quersumme wäre meine Idee das hier:
Code:
#!/usr/bin/perl

print quersumme(9265342134), "\n";

sub quersumme {
   my $number = shift;
   my $sum = 0;
   for my $digit (unpack 'C*', $number) {
      $sum += char($digit);
   }
   return $sum;
}


Mir fällt im Augenblick nichts eleganteres/schnelleres ein...

Gruß
Marco
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
as_string



Anmeldungsdatum: 24.02.2006
Beiträge: 80
Wohnort: Heidelberg

BeitragVerfasst am: 19. Jul 2006 03:31    Titel: Antworten mit Zitat

Hallo!

Ich habe mal etwas rumgespielt:
Code:
#!/usr/bin/perl

for($i = (-20 * 365); $i<(20*365);$i++) { # 365 Tage pro Jahre, mal unabhängig von Schaltjahren...
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
      localtime($i * 86400); #60 * 60 * 24 = 86400
   my $quersumme = quersumme($mday + $mon + $year +1901);
   while($quersumme > 21) {
      $quersumme = quersumme($quersumme);
   }
   printf("%02d.%02d.%04d:%3d\n", $mday, $mon + 1 , $year + 1900, $quersumme);
}

sub quersumme {
   my $number = shift;
   my $sum = 0;
   for my $digit (unpack 'C*', $number) {
      $sum +=chr($digit);
   }
   return $sum;
}


Keine Ahnung, ob der Code selbst erklärend ist... Wenn nicht, einfach nochmal fragen!

Gruß
Marco
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dachdecker2
Moderator


Anmeldungsdatum: 11.06.2005
Beiträge: 106
Wohnort: Maintal / Hessen

BeitragVerfasst am: 19. Jul 2006 07:54    Titel: Antworten mit Zitat

Ich denke mal, dass es auf ein paar Schalttage nicht ankommt. Die sind sowieso unwichtig, weil da mit hoher Wahrscheinlichkeit nichts bedeutendes passiert, wenn das entsprechende Blatt nicht im Kalender drin ist Augenzwinkern. Wenn du alle 29. Februare weglässt, fehlen dir dann die Daten von 242,5 Tagen pro Jahrtausend.

Aber nur zur Info, die Zeitrechnung auf der deine Daten beruhen werden, ist im Jahre 1582 eingeführt worden. Es macht sicherlich nicht viel Sinn, darüber hinauszurechnen.

Ansonsten gibts ne einfache Regel: alle Jahre, die durch 4 ohne Rest teilbar sind, sind Schaltjahre. Keine Schaltjahre sind die Jahre, die ohne Rest durch 100 teilbar sind, außer denen die durch 400 gehen (die sind dann wieder Schaltjahr vgl. 2000 n. Chr., keine Schaltjahre sind etwa 1900 und 2100 n. Chr.).

_________________
In a world without walls and fences, who needs windows and gates? [Internet]

Gruß, dachdecker2
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden MSN Messenger
as_string



Anmeldungsdatum: 24.02.2006
Beiträge: 80
Wohnort: Heidelberg

BeitragVerfasst am: 19. Jul 2006 14:49    Titel: Antworten mit Zitat

Hallo Dachdecker!

Bei meinem Code werden die Schalttage schon auch mit berücksichtigt. Das Problem ist nur die Gesamtanzahl der Tage, die die Schleife durchläuft. Wenn man exakt zwischen Datum soundso bis Datum soundsoanders durchlaufen will, dann müßte man erst kompliziert berechnen, wieviele Tage das insgesamt sind, damit man auch wirklich beim Zieldatum ankommt, so wie Du das mit den Schalttagen ja auch beschrieben hast. Man müßte also berechnen: zwischen Anfangsdatum und Enddatum liegen so und so viele Schalttage und diese dann dazu addieren.
Ein anderes Problem wären noch die Leapseconds. Wenn die in der Perl-Funktion berücksichtigt werden würden, dann würde das Programm u. U. mal zweimal den selben Tag ausgeben oder so (also dann den 1.1. oder 31.12. ?). Aber das ändert nichts an der Quersumme, die ist dann ja trotzdem richtig.
Insgesamt denke ich, dass man mit diesen Einschränkungen leben kann. Es geht ja, wenn ich das richtig verstanden habe, nur um eine Tabelle dieser ganzen Zahlen, bei der aber alle Dati (wie ist eigentlich der Plural von Datum? Daten ist ja irgendwie irreführend im Zusammenhang mit Informatik, oder?) vorkommen sollen. Das leistet mein Miniprogramm schon. Allerdings ist es eben schwierig den Wertebereich fest zu legen und der Bereich ist vielleicht so wie eingeschränkt durch die localtime-Funktion.

Gruß
Marco
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dachdecker2
Moderator


Anmeldungsdatum: 11.06.2005
Beiträge: 106
Wohnort: Maintal / Hessen

BeitragVerfasst am: 19. Jul 2006 19:57    Titel: Antworten mit Zitat

Der Plural von Datum ist Daten (Datum ist nicht nur ein Zeitpunkt sondern allgemein die Einzahl vom Wort Daten).

Ich kann kein Perl aber ich denke mal, dass man doch aus der for-Schleife ne while-Schleife machen können müsste - dann könnte man die durchläufe zählen und nachher (falls es interessiert) die Anzahl der Tage ausgeben.

_________________
In a world without walls and fences, who needs windows and gates? [Internet]

Gruß, dachdecker2
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden MSN Messenger
as_string



Anmeldungsdatum: 24.02.2006
Beiträge: 80
Wohnort: Heidelberg

BeitragVerfasst am: 19. Jul 2006 20:26    Titel: Antworten mit Zitat

dachdecker2 hat Folgendes geschrieben:
Der Plural von Datum ist Daten (Datum ist nicht nur ein Zeitpunkt sondern allgemein die Einzahl vom Wort Daten).

Ah, danke... smile
dachdecker2 hat Folgendes geschrieben:
Ich kann kein Perl aber ich denke mal, dass man doch aus der for-Schleife ne while-Schleife machen können müsste - dann könnte man die durchläufe zählen und nachher (falls es interessiert) die Anzahl der Tage ausgeben.

Ja, das kann man natürlich machen, keine Frage. Das einzige, was dann vielleicht noch etwas Probleme macht ist, dass man das Anfangsdatum in Unix-Sekunden umrechnen muß. Dazu gibt es aber ein Perl-Modul: Time::Local. Das Modul liefert dann eine Funktion, die quasi genau das umgekehrte macht, wie die localtime() Funktion aus dem Core-Perl, nämlich aus einem entsprechenden Array mit Sekunden, Minuten, Stunden, Tag des Monats, Monat, Jahr... eine Unix-Zeit aus zu rechnen.
So könnte man relativ einfach ein Programm schreiben, das ein Datum einließt, mit dem die while-Schleife startet und die while-Schleife so lange geht, bis das Enddatum getroffen ist. Wenn man Anfangs-Datum als auch Enddatum umrechnet, dann würde sogar wieder eine for-Schleife gehen...

Gruß
Marco
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dachdecker2
Moderator


Anmeldungsdatum: 11.06.2005
Beiträge: 106
Wohnort: Maintal / Hessen

BeitragVerfasst am: 19. Jul 2006 20:57    Titel: Antworten mit Zitat

Basiert denn das Unixdatum auf einem unsigned-Typ? wenn nicht, wird das wohl mit der Umrechnung der Daten nichts werden, die 0 liegt bestimmt in der Gegend von 1980 oder 1900. also wird man weder bei 0 n. Chr. noch bei 1582, dem Start des aktuellen Kalenders anfangen können.

Wahrscheinlich muss man sich da was eigenes bauen.

_________________
In a world without walls and fences, who needs windows and gates? [Internet]

Gruß, dachdecker2
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden MSN Messenger
as_string



Anmeldungsdatum: 24.02.2006
Beiträge: 80
Wohnort: Heidelberg

BeitragVerfasst am: 19. Jul 2006 22:41    Titel: Antworten mit Zitat

Ich hatte mit meinem Beispiel-Skript etwas experimentiert und festgestellt, dass er negative Zahlen auch annimmt und auch korrekt verarbeitet. Die 0 entspricht übrigens dem 1.1.1970 00:00Uhr , so weit ich weiß, müßte jetzt aber auch nochmal nachschauen.
Ob man damit bis zum Jahr 16. Jahrhundert zurück kommt, weiß ich allerdings auch nicht. Soweit ich im entsprechenden Thread im Matheboard gesehen habe, geht es wohl eher um Geburtsdaten, so dass im Normalfall das letzt Jahrhundert ausreichen sollte, oder? Ich vermute, dass das eine 64-bit signed Zahl ist intern, aber wie gesagt: keine Ahnung...

Ich habe gerade mal etwas auf http://search.cpan.org gesucht und ich denke, dass ich das ideale Modul für unsere Zwecke gefunden habe:
Date::Step
Da gibt man ein Startdatum, ein Enddatum und einen Zeitschritt an (also '1d' für einen Tag in unserem Fall) und das Ding liefert dann nach und nach die entsprechenden Daten. Anscheinend auch in einem sehr großen Wertebereich...
Wenn ich noch Zeit habe, versuche ich unser kleines Bsp. mal entsprechend um zu schreiben.

Gruß
Marco
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Dieses Forum ist gesperrt, du kannst keine Beiträge editieren, schreiben oder beantworten.   Dieses Thema ist gesperrt, du kannst keine Beiträge editieren oder beantworten.    Informatikerboard.de Foren-Übersicht -> Perl Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum nicht herunterladen