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