Archiv verlassen und diese Seite im Standarddesign anzeigen : Unix-Zeit in menschenlesbare Zeitdarstellung
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:
$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:
$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?
$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
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.