Wie wäre es wenn du erstmal deinen Ansatz postest und man dann zusammen weiter macht. Bis jetzt hört es sich stark nach "Kann das mal einer für mich machen" an.
Hallo Forum,
Der Thread-Titel verrät eigentlich schon alles.
Ich habe eine Funktion, die die aktuelle Unix-Zeit ermittelt.
Auf diese Unix-Zeit addiere ich eine Anzahl von Sekunden und möchte den Zeitpunkt (Datum und Uhrzeit) in menschenlesbarer Form ausgeben.
Dies alles soll mit Bascom auf einem Atmega 128 stattfinden - wobei der Punkt Bascom eigentlich egal ist.
Der grundsätzliche Ansatz ist klar, mir geht es darum die Fehlersuche abzukürzen, da ich mir vorstelle, Dass eventuelle Fehler nur zu bestimmten Daten auftreten und so mit nicht sichergestellt wäre, ob wirklich alle ausgeschlossen sind.
Deshalb meine Frage, hat jemand bereits einen C- oder Bascom-Code welcher fehlerfrei eine Unix-Zeitangabe zurückrechnet?
mfG
BoGe-Ro
Wie wäre es wenn du erstmal deinen Ansatz postest und man dann zusammen weiter macht. Bis jetzt hört es sich stark nach "Kann das mal einer für mich machen" an.
Hallo,
Nach "Kann das mal einer machen" sollte es nicht klingen - die Frage war mehr: "Hat es schon einer gemacht und ist zufrieden mit dem Ergebnis?".
Natürlich habe ich mir auch eine Lösung einfallen lassen - welche auch an den getesteten Zeitpunkten funktioniert - jedoch halte ich sie für ziemlich langsam, noch wurden alle Eventualitäten überprüft.
Nachfolgend meine Lösung, welche im Bascom-Simulator läuft:
Code:$regfile = "m128def.dat" $crystal = 16000000 $framesize = 120 $swstack = 120 $hwstack = 120 $baud = 57600 $sim Dim Zeit_long As Long Dim Zeit_string As String * 12 Declare Function Unixzeit(byval _tag As Byte , Byval _monat As Byte , _ Byval _jahr As Word , Byval _stunde As Byte , _ Byval _minute As Byte , Byval _sekunde As Byte) As Long Declare Function Zeit(byval _unixzeit As Long) As String Declare Function Schaltjahr(byval _jahr As Word) As Byte Do Zeit_long = Unixzeit(19 , 10 , 2010 , 13 , 35 , 00) Print Space(12) ; "19.10.2010 13:35:00" ; Space(4); Print "UnixZeit: " ; Zeit_long Zeit_string = Zeit(zeit_long) Print "Zeitstring: " ; Zeit_string Zeit_long = Unixzeit(17 , 09 , 1976 , 11 , 11 , 11) Print Space(12) ; "17.09.1976 11:11:11" ; Space(4); Print "UnixZeit: " ; Zeit_long Zeit_string = Zeit(zeit_long) Print "Zeitstring: " ; Zeit_string Zeit_long = Unixzeit(30 , 11 , 2010 , 09 , 10 , 30) Print Space(12) ; "30.11.2010 09:10:30" ; Space(4); Print "UnixZeit: " ; Zeit_long Zeit_string = Zeit(zeit_long) Print "Zeitstring: " ; Zeit_string Loop End Function Unixzeit(byval _tag As Byte , Byval _monat As Byte , _ Byval _jahr As Word , Byval _stunde As Byte , _ Byval _minute As Byte , Byval _sekunde As Byte) As Long 'http://de.wikipedia.org/wiki/Unixzeit Local _jahre As Byte Local _schaltjahre As Single Local _term1 As Single , _term2 As Single , _term3 As Single Local _unix_zeit As Long Local _help_long As Long Local _help_byte As Byte Local _help_b1 As Byte , _help_b2 As Byte , _help_b3 As Byte _stunde = _stunde - 2 'Sommerzeit und UTC _jahre = _jahr - 1970 _term1 = _jahr - 1 _term1 = _term1 - 1968 _term1 = _term1 / 4 _term2 = _jahr - 1 _term2 = _term2 - 1900 _term2 = _term2 / 100 _term3 = _jahr - 1 _term3 = _term3 - 1600 _term3 = _term3 / 400 _schaltjahre = _term1 - _term2 _schaltjahre = _schaltjahre + _term3 _schaltjahre = Int(_schaltjahre) _unix_zeit = _sekunde _help_long = 60 * _minute _unix_zeit = _unix_zeit + _help_long _help_long = 3600 * _stunde _unix_zeit = _unix_zeit + _help_long _help_byte = _monat - 1 _help_long = Lookup(_help_byte , Tage_bis_monatsanfang) _help_long = _help_long + _tag _help_long = _help_long - 1 _help_long = _help_long * 86400 _unix_zeit = _unix_zeit + _help_long _help_byte = _schaltjahre _help_long = _jahre * 365 _help_long = _help_long + _help_byte _help_long = _help_long * 86400 _unix_zeit = _unix_zeit + _help_long _help_b1 = _jahr Mod 4 _help_b2 = _jahr Mod 100 _help_b3 = _jahr Mod 400 If _help_b2 <> 0 Or _help_b3 = 0 Then If _help_b1 = 0 And _monat > 2 Then _unix_zeit = _unix_zeit + 86400 Unixzeit = _unix_zeit End Function Tage_bis_monatsanfang: Data 0& , 31& , 59& , 90& , 120& , 151& , 181& , 212& , 243& , 273& , 304& , 334& Function Zeit(byval _unixzeit As Long) As String 'Start: 01.01.1970 00:00 Uhr UTC Local _dauer_tage As Long Local _dauer_stunden As Long Local _dauer_minuten As Long Local _dauer_sekunden As Long Local _tage As Byte Local _monate As Byte Local _jahre As Word Local _help_word As Word Local _help_byte As Byte Local _anzahl_tage_im_monat As Byte Local _ausgabestring As String * 30 _unixzeit = _unixzeit + 7200 'Korrektur auf Sommerzeit und UTC _dauer_tage = _unixzeit \ 86400 _unixzeit = _unixzeit Mod 86400 _dauer_stunden = _unixzeit \ 3600 _unixzeit = _unixzeit Mod 3600 _dauer_minuten = _unixzeit \ 60 _dauer_sekunden = _unixzeit Mod 60 _jahre = 1970 'Startwert _monate = 01 'Startwert ' _tage = 1 Do _anzahl_tage_im_monat = Lookup(_monate , Monatslaenge) _help_byte = Schaltjahr(_jahre) If _monate = 2 And _help_byte = 1 Then _anzahl_tage_im_monat = 29 If _dauer_tage > _anzahl_tage_im_monat Then Incr _monate _dauer_tage = _dauer_tage - _anzahl_tage_im_monat If _monate > 12 Then Incr _jahre _monate = _monate - 12 End If End If Loop Until _dauer_tage <= _anzahl_tage_im_monat Incr _dauer_tage 'damits nicht am 00.01.1970 startet _ausgabestring = Str(_dauer_tage) + "." + Str(_monate) + "." + Str(_jahre) _ausgabestring = _ausgabestring + " " + Str(_dauer_stunden) + ":" + Str(_dauer_minuten) + ":" + Str(_dauer_sekunden) Zeit = _ausgabestring End Function Monatslaenge: Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 Function Schaltjahr(byval _jahr As Word) As Byte Local _durch4 As Word Local _durch100 As Word Local _durch400 As Word Local _schaltjahr As Byte : _schaltjahr = 0 _durch4 = _jahr Mod 4 _durch100 = _jahr Mod 100 _durch400 = _jahr Mod 400 If _durch4 = 0 Then _schaltjahr = 1 If _durch100 = 0 Then _schaltjahr = 0 If _durch400 = 0 Then _schaltjahr = 1 Schaltjahr = _schaltjahr End Function
obiger Code funtioniert zwar für die eingefügten Testdaten, allerdings schon nicht mehr, wenn man das morgige Datum zurückrechnen möchte.
Dies fiel mir eben in einem anderen Test auf - und zeigt mir, wie schwierig es ist, auch jeden Fall vorher abzuklopfen.
korrigiert sieht es nun so aus:
Code:$regfile = "m128def.dat" $crystal = 16000000 $framesize = 120 $swstack = 120 $hwstack = 120 $baud = 57600 $sim Dim Zeit_long As Long Dim Zeit_string As String * 12 Declare Function Unixzeit(byval _tag As Byte , Byval _monat As Byte , _ Byval _jahr As Word , Byval _stunde As Byte , _ Byval _minute As Byte , Byval _sekunde As Byte) As Long Declare Function Zeit(byval _unixzeit As Long) As String Declare Function Schaltjahr(byval _jahr As Word) As Byte Do Zeit_long = Unixzeit(30 , 11 , 2010 , 09 , 10 , 30) Print Space(12) ; "30.11.2010 09:10:30" ; Space(4); Print "UnixZeit: " ; Zeit_long Zeit_long = Zeit_long + 86400 'einen Tag draufaddieren Zeit_string = Zeit(zeit_long) Print "Zeitstring: " ; Zeit_string Loop End Function Unixzeit(byval _tag As Byte , Byval _monat As Byte , _ Byval _jahr As Word , Byval _stunde As Byte , _ Byval _minute As Byte , Byval _sekunde As Byte) As Long 'http://de.wikipedia.org/wiki/Unixzeit Local _jahre As Byte Local _schaltjahre As Single Local _term1 As Single , _term2 As Single , _term3 As Single Local _unix_zeit As Long Local _help_long As Long Local _help_byte As Byte Local _help_b1 As Byte , _help_b2 As Byte , _help_b3 As Byte _stunde = _stunde - 2 'Sommerzeit und UTC _jahre = _jahr - 1970 _term1 = _jahr - 1 _term1 = _term1 - 1968 _term1 = _term1 / 4 _term2 = _jahr - 1 _term2 = _term2 - 1900 _term2 = _term2 / 100 _term3 = _jahr - 1 _term3 = _term3 - 1600 _term3 = _term3 / 400 _schaltjahre = _term1 - _term2 _schaltjahre = _schaltjahre + _term3 _schaltjahre = Int(_schaltjahre) _unix_zeit = _sekunde _help_long = 60 * _minute _unix_zeit = _unix_zeit + _help_long _help_long = 3600 * _stunde _unix_zeit = _unix_zeit + _help_long _help_byte = _monat - 1 _help_long = Lookup(_help_byte , Tage_bis_monatsanfang) _help_long = _help_long + _tag _help_long = _help_long - 1 _help_long = _help_long * 86400 _unix_zeit = _unix_zeit + _help_long _help_byte = _schaltjahre _help_long = _jahre * 365 _help_long = _help_long + _help_byte _help_long = _help_long * 86400 _unix_zeit = _unix_zeit + _help_long _help_b1 = _jahr Mod 4 _help_b2 = _jahr Mod 100 _help_b3 = _jahr Mod 400 If _help_b2 <> 0 Or _help_b3 = 0 Then If _help_b1 = 0 And _monat > 2 Then _unix_zeit = _unix_zeit + 86400 Unixzeit = _unix_zeit End Function Tage_bis_monatsanfang: Data 0& , 31& , 59& , 90& , 120& , 151& , 181& , 212& , 243& , 273& , 304& , 334& Function Zeit(byval _unixzeit As Long) As String 'Start: 01.01.1970 00:00 Uhr UTC Local _dauer_tage As Long Local _dauer_stunden As Long Local _dauer_minuten As Long Local _dauer_sekunden As Long Local _tage As Byte Local _monate As Byte Local _jahre As Word Local _help_word As Word Local _help_byte As Byte Local _anzahl_tage_im_monat As Byte Local _ausgabestring As String * 30 _unixzeit = _unixzeit + 7200 'Korrektur auf Sommerzeit und UTC _dauer_tage = _unixzeit \ 86400 _unixzeit = _unixzeit Mod 86400 _dauer_stunden = _unixzeit \ 3600 _unixzeit = _unixzeit Mod 3600 _dauer_minuten = _unixzeit \ 60 _dauer_sekunden = _unixzeit Mod 60 _jahre = 1970 'Startwert _monate = 01 'Startwert Incr _dauer_tage 'damits nicht am 00.01.1970 startet Do _anzahl_tage_im_monat = Lookup(_monate , Monatslaenge) If _monate = 2 Then _help_byte = Schaltjahr(_jahre) If _help_byte = 1 Then _anzahl_tage_im_monat = 29 End If If _dauer_tage > _anzahl_tage_im_monat Then Incr _monate _dauer_tage = _dauer_tage - _anzahl_tage_im_monat If _monate > 12 Then Incr _jahre _monate = _monate - 12 End If End If _anzahl_tage_im_monat = Lookup(_monate , Monatslaenge) Loop Until _dauer_tage <= _anzahl_tage_im_monat _ausgabestring = Str(_dauer_tage) + "." + Str(_monate) + "." + Str(_jahre) _ausgabestring = _ausgabestring + " " + Str(_dauer_stunden) + ":" + Str(_dauer_minuten) + ":" + Str(_dauer_sekunden) Zeit = _ausgabestring End Function Monatslaenge: Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 Function Schaltjahr(byval _jahr As Word) As Byte Local _durch4 As Word Local _durch100 As Word Local _durch400 As Word Local _schaltjahr As Byte : _schaltjahr = 0 _durch4 = _jahr Mod 4 _durch100 = _jahr Mod 100 _durch400 = _jahr Mod 400 If _durch4 = 0 Then _schaltjahr = 1 If _durch100 = 0 Then _schaltjahr = 0 If _durch400 = 0 Then _schaltjahr = 1 Schaltjahr = _schaltjahr End Function
Hallo Forum,
ich muss mein Rechenproblem mal etwas aufsplitten - denn ich hab bemerkt, dass meine Bascom-Umsetzung des Algorithmus auf http://de.wikipedia.org/wiki/Unixtime nicht perfekt funktioniert.
Zum Testen habe ich nachfolgenden Code auf einen ATMega geladen und die Ausgaben im Terminal mitgeschrieben und per Excel verglichen.
Resultat: es werden alle Daten seit 01.01.1970 an die Funtion zur Umrechnung in den Zeitstempel gegeben (der Einfachheit halber jeweils zur Uhrzeit 00:00:00) und das Ergebnis mit einer Variablen deren Wert sich bei jedem Durchlauf um 86400 (24 Stunden) erhöht verglichen.
Folgendes läßt sich feststellen:
- im Zeitraum 01.01.1970 - 31.12.2004 sind die Ergebnisse korrekt
- im Zeitraum 01.01.2005 - 31.12.2036 stimmt das Folgejahr nach einem Schaltjahr nicht (1 Tage Differenz)
- im Zeitraum 01.01.2037 - ... sind die 2 auf das Schaltjahre folgenden Jahre um 1 Tag verschoben.
Es wurde keinerlei Korrektur vorgenommen - die stimmenden Jahre dazwischen haben sich durch den selben Programmcode ergeben.
wer kann den Fehler finden?
Code:$regfile = "m16def.dat" $crystal = 8000000 $framesize = 120 $swstack = 120 $hwstack = 120 $baud = 57600 '$sim Dim Zeit_long As Long Dim Zeit_inkr As Long : Zeit_inkr = 0 Dim Differenz As Single Dim Tag As Byte : Tag = 01 Dim Monat As Byte : Monat = 01 Dim Jahr As Word : Jahr = 1970 Dim Stunde As Byte : Stunde = 00 Dim Minute As Byte : Minute = 00 Dim Sekunde As Byte : Sekunde = 00 Dim Help_byte As Byte Declare Function Unixzeit(byval _tag As Byte , Byval _monat As Byte , _ Byval _jahr As Word , Byval _stunde As Byte , _ Byval _minute As Byte , Byval _sekunde As Byte) As Long Declare Function Schaltjahr(byval _jahr As Word) As Byte Wait 10 Zeit_long = Unixzeit(31 , 12 , 2004 , 0 , 0 , 0) Print "31.12.2004 = " ; Zeit_long Zeit_long = Unixzeit(1 , 1 , 2005 , 0 , 0 , 0) Print "01.01.2005 = " ; Zeit_long Do Print Tag ; "." ; Monat ; "." ; Jahr ; Chr(9) ; Stunde ; ":" ; Minute ; ":" ; Sekunde ; Chr(9); Zeit_long = Unixzeit(tag , Monat , Jahr , Stunde , Minute , Sekunde) Differenz = Zeit_long - Zeit_inkr If Differenz <> 0 Then Print "Fehler: " ; Tag ; "." ; Monat ; "." ; Jahr ; " Differenz : " ; Differenz ; " Sek = "; Differenz = Differenz / 86400 Print Differenz ; " Tage"; 'Wait 5 End If Print Incr Tag Zeit_inkr = Zeit_inkr + 86400 Help_byte = Lookup(monat , Monatslaenge) If Monat = 2 Then Help_byte = Schaltjahr(jahr) If Help_byte = 1 Then Help_byte = 29 Else Help_byte = 28 End If If Tag > Help_byte Then Tag = 1 Incr Monat If Monat > 12 Then Monat = 1 Incr Jahr End If End If Loop End Function Unixzeit(byval _tag As Byte , Byval _monat As Byte , _ Byval _jahr As Word , Byval _stunde As Byte , _ Byval _minute As Byte , Byval _sekunde As Byte) As Long 'http://de.wikipedia.org/wiki/Unixzeit Local _jahre As Byte Local _schaltjahre As Single Local _term1 As Single , _term2 As Single , _term3 As Single Local _unix_zeit As Long Local _help_long As Long Local _help_byte As Byte Local _help_b1 As Byte , _help_b2 As Byte , _help_b3 As Byte _jahre = _jahr - 1970 _term1 = _jahr - 1 _term1 = _term1 - 1968 _term1 = _term1 / 4 _term2 = _jahr - 1 _term2 = _term2 - 1900 _term2 = _term2 / 100 _term3 = _jahr - 1 _term3 = _term3 - 1600 _term3 = _term3 / 400 _schaltjahre = _term1 - _term2 _schaltjahre = _schaltjahre + _term3 _schaltjahre = Int(_schaltjahre) _unix_zeit = _sekunde _help_long = 60 * _minute _unix_zeit = _unix_zeit + _help_long _help_long = 3600 * _stunde _unix_zeit = _unix_zeit + _help_long _help_byte = _monat - 1 _help_long = Lookup(_help_byte , Tage_bis_monatsanfang) _help_long = _help_long + _tag _help_long = _help_long - 1 _help_long = _help_long * 86400 _unix_zeit = _unix_zeit + _help_long _help_byte = _schaltjahre _help_long = _jahre * 365 _help_long = _help_long + _help_byte _help_long = _help_long * 86400 _unix_zeit = _unix_zeit + _help_long If _monat > 2 Then _help_byte = Schaltjahr(_jahr) If _help_byte = 1 Then _unix_zeit = _unix_zeit + 86400 End If Unixzeit = _unix_zeit End Function Tage_bis_monatsanfang: Data 0& , 31& , 59& , 90& , 120& , 151& , 181& , 212& , 243& , 273& , 304& , 334& Monatslaenge: Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 Function Schaltjahr(byval _jahr As Word) As Byte Local _durch4 As Word Local _durch100 As Word Local _durch400 As Word Local _schaltjahr As Byte : _schaltjahr = 0 _durch4 = _jahr Mod 4 If _durch4 = 0 Then _schaltjahr = 1 _durch100 = _jahr Mod 100 _durch400 = _jahr Mod 400 If _durch100 = 0 Then _schaltjahr = 0 If _durch400 = 0 Then _schaltjahr = 1 Else _schaltjahr = 0 End If Schaltjahr = _schaltjahr End Function
Besten Dank
BoGe-Ro
Lesezeichen