Sommer- und Normalzeitermittlung

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Sommer- und Normalzeitermittlung

      Ich sehe gerade den Wald trotz vieler Bäume nicht.

      Ich habe folgendes Problem.
      Ich habe eine Hardware mit RTC die nur fallweise eingeschaltet wird (die RTC läuft ja mit der Pufferbatterie weiter kann aber keine eigene Sommerzeitsteuerung wie viele derartige Chips auch).

      Da das Gerät aber nicht ständig in Betrieb ist, kann es sein, dass dieses eben lange nach dem eigentlichen Umschaltezeitpunkt aktiviert wird.
      Es kann also sein, dass die eigentliche Umschaltung bereits z.B. bis zu mehreren Tagen (oder mit "Pech" auch Wochen und Monate) vorbei ist.
      Daher möchte ich bei der Aktivierung des Gerätes feststellen ob eine derartige Umstellung fällig ist, die Uhr umstellen und mir eben merken, dass umgestellt wurde.
      Es ist also nicht einfach nur das +/- eine Stunde stellen sondern wenn der Umschaltzeitpunkt "blöd" liegt, muss ja auch Tag, Monat und Jahr dabei berücksichtigt werden.
      Als ersten Ansatz mache ich das auch so in einem groben Raster. Geht das auch einfacher.
      Weil was jetzt noch fehlt ist die genauere Abhandlung des tatsächlichen Umschaltzeitpunkt (also die Zeit bis zum letzten Sonntag im März um 2 Uhr oder zum letzten Sonntag im Oktober um 3 Uhr)

      Mein Ansatz schaut erstmal so aus:

      BASCOM-Quellcode

      1. Function SwitchSummertime() As Byte
      2. Local fH As Byte
      3. Local fM As Byte
      4. Local fD As Byte
      5. Local fWD As Byte
      6. Local fX As Byte
      7. Local fY As Byte
      8. Local fZ As Byte
      9. Local fW As Word
      10. fH = 255
      11. fM = 255
      12. fD = 255
      13. fY = 255
      14. fWD = 255
      15. fW = AppConfig(AppConfig_Century) * 100
      16. fW = fW + _year
      17. If AppConfig(AppConfig_IsSummertime) = 0 Then ' Normalzeit aktiv
      18. If _Month > 3 And _Month < 10 Then ' jedenfalls SZ
      19. fH = _hour + 1
      20. If fH > 23 Then
      21. fH = 0
      22. fX = MonthDayCount(fW , _Month)
      23. fD = _day + 1
      24. fWD = RTC_Weekday
      25. fWD = fWD + 1
      26. If fWD > 7 Then
      27. fWD = 1
      28. End If
      29. If fD > fX Then
      30. fD = 1
      31. fM = _Month + 1
      32. If fM > 12 Then
      33. fM = 1
      34. fY = _year + 1
      35. If fY > 99 Then
      36. fY = 0
      37. End If
      38. End If
      39. End If
      40. End If
      41. AppConfig(AppConfig_IsSummertime) = 1
      42. End If
      43. Else ' Sommerzeit aktiv
      44. If _Month > 10 And _Month < 3 Then ' jedenfalls NZ
      45. fH = _hour - 1
      46. If fH > 23 Then
      47. fH = 23
      48. fZ = _Month - 1
      49. If fZ = 0 Then
      50. fZ = 12
      51. fM = 1
      52. fY = _year - 1
      53. If fY > 99 Then
      54. fY = 99
      55. End If
      56. End If
      57. fX = MonthDayCount(fW , fZ)
      58. fD = _day - 1
      59. fWD = RTC_Weekday
      60. fWD = fWD - 1
      61. If fWD > 7 Then
      62. fWD = 7
      63. End If
      64. If fD = 0 Then
      65. fD = fX
      66. fM = fZ
      67. End If
      68. End If
      69. AppConfig(AppConfig_IsSummertime) = 0
      70. End If
      71. End If
      Alles anzeigen

      BASCOM-Quellcode

      1. Function MonthDayCount(ByVal pMonth As Byte , _
      2. ByVal pYear As Word) As Byte
      3. Local fX As Byte
      4. Local fM As Word
      5. fM = &B0001010110101010
      6. If pMonth = 2 Then ' Februar
      7. fX = Is_Leapyear(pYear)
      8. fX = 28 + fX
      9. Else ' alle anderen Monate
      10. If pMonth = 0 Or pMonth > 12 Then
      11. fX = 255
      12. Else
      13. fX = 30 + fM.pMonth
      14. End If
      15. End If
      16. MonthDayCount = fX
      17. End Function
      Alles anzeigen


      BASCOM-Quellcode

      1. Function Is_Leapyear(ByVal pYear As Word) As Byte
      2. Local fW As Word
      3. Local fYear As Word
      4. Local fR As Byte
      5. fR = 0
      6. If pYear < 1000 Then
      7. fYear = AppConfig(AppConfig_Century) * 100
      8. fYear = fYear + pYear
      9. Else
      10. fYear = pYear
      11. End If
      12. fW = fYear Mod 4
      13. If fW = 0 Then
      14. fW = fYear Mod 100
      15. If fW <> 0 Then
      16. fR = 1
      17. Else
      18. fW = fYear Mod 400
      19. If fW = 0 Then
      20. fR = 1
      21. End If
      22. End If
      23. End If
      24. Is_Leapyear = fR
      25. End Function
      Alles anzeigen
    • Ich würde die RTC mit einer festen Zeit fahren und die Sommerzeit on the fly einfach dazurechnen.
      Also Bascom mit Softclock laufen lassen, die Zeit in einem Long speichern und bei Sommerzeitbedarf einfach 3600 Sekunden drauf rechnen. Aus dem Long dann wieder die Ausgabe konvertieren.
      Die RTC macht den Kram mit 29 Januar eigentlich selber schon richtig.
    • Schau mal hier, da gibt es die Regelung der Zeitumstellung.
      Aber ich denke, das Jahr brauchst du nicht mit berücksichtigen bei der Umstellung. Es reicht wenn du den Monat abfragst in dem sich die RTC gerade befindet und dann bestimmst ob umgestellt werden muss oder nicht.
      Zum speichern reicht ja ein Flag.
      Hier im Forum gab es ja auch schon mal ein Thema darüber Die Sommerzeit naht und da gibt es auch ein paar Beispiele

      Vielleicht hilft dir das weiter :)
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • djmsc schrieb:

      Schau mal hier, da gibt es die Regelung der Zeitumstellung.
      Die Bedingungen an sich sind ja klar. Nur muss dazu das Gerät auch ständig aktiv sein, was es nicht ist.
      Per Default kann es sein, dass das Gerät während der Sommerzeitphaxe aktiviert war (und sich das auch mit einem Flag merkte) und das nächste mal aber einige Zeit nach Umstellung auf Normalzeit wieder aktiviert wird. An der Stelle will ich die RTC "korrigieren".
      Dazu ist es eben notwendig vom jeweils aktuellen Zeitpunkt zu wissen ob eben Sommerzeit oder Normalzeit vorherrscht.
      Auch das Jahr ist IMHO wichtig.
      Wenn man annimmt, dass das Gerät laut RTC z.B. am 01.01.2020 um 00:30 aktiviert wird und der letzte Status Sommerzeit war, wird neben der Stunde auch der Tag mit Wochentag, das Monat und auch das Jahr verändert. Dies deshalb weil durch das abziehen einer Stunde an der Stelle der 31.12.2019 23:30 wird.

      Das Problem hat man eben nicht, wenn ein Gerät ständig aktiv wäre und man eben am letzten Sonntag um 2:00 eben nur eine Stunde hinzufügen oder am letzten Sonntag im Oktober um 3:00 Uhr eine Stunde abziehen muss.
    • Deine rtc lässt du halt mit Winterzeit laufen, durch das Datum kannst du erkennen, ob Sommerzeit zu zeigen wäre, oder nicht. Verwenden tust du dann eine 2. Zeit, die entsprechend korrigiert ist. an der rtc würde ich dann nix umstellen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Die 2. Zeit ist dann die von der softclock. Wenn dein Gerät startet, musst du die softclock sowieso stellen. Normalerweise nimmt man die Zeit von der rtc, in deinem Fall wird diese dann eben je nach Datum mit +1 für Sommerzeit oder mit +0 für den Normalzeitraum korrigiert.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Irgendwie in diese Richtung wird es wohl gehen müssen.
      Nur allein am Datum hängt es ja nicht.
      Es muss vom aktuellen Datum aus der Bereich letzter Sonntag im März 2:00 Uhr bis letzter Sonntag im Oktober 3:00 Uhr ermittelt werden weil das ist IMHO der Sommerzeitbereich.
      Und da stehe ich im Moment am Schlauch. Ich werde mal darüber schlafen, eventuell schlägt ja morgen der Blitz ein :D .
      Ich habe bisher nur Webseiten gefunden die das Start- und Endedatum berechnen, nur die zugrundeliegende Formel welche vom aktuellen Jshr aus berechnet noch nicht.
    • Ich denke @Cable hat hier Die Sommerzeit naht schon die Formel gezeigt, die du brauchst. Nur das settime musst du weg lassen, dass du dir deine rtc nicht verstellst. Natürlich darfst du auch nicht eine Stunde abziehen, es geht ja nur darum, die Sommerzeit zu berücksichtigen. Die rtc hat ja die Winterzeit/Normalzeit. Obwohl, wenn du beide Zeilen drin lässt, wird zur Sommerzeit nur die erste Formel aktiv und zählt die Stunde dazu. Bist du im Winterzeitzeitraum in der 2. Jahreshälfte, wird erst mal eine Stunde addiert, aber dann gleich wieder abgezogen, passt also.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • Nachdem ich jetzt eine Nacht darüber geschlafen habe meine ich, dass es mit dem einfachen hinzufügen einer Stunde im Sommerzeitfall und einer "Schattenuhr" nicht einfach getan ist.
      Wenn es blöd hergeht, und die Wahrscheinlichkeit ist da z.B. in meinem Projekt hoch weil das Gerät alle 100 Stunden (±45 Minuten, abhängig von der Umgebung) aktiviert wird. es ja durchaus sein kann, dass das ganze ausgerechnet rund um Mitternacht und zum anderem noch zusätzlich an einem Monatsende oder Monatsanfang stattfindet. Dann stimmt zwar die Zeit, aber nicht mehr der Tag und Wochentag und am Monatswechsel eben auch der Monat und dann wiederum wenn es ganz blöd hergeht auch das Jahr nicht mehr.

      Es ist erst mal kein Problem die eindeutigen Monate mit Sommer- (April bis September und <25. Oktober) und Winterzeit (Jänner, Februar und <25. März sowie November bis Dezember) abzuprüfen.
      Problematischer aber nicht unmöglich erscheint mir aber bisher festzustellen, was der letzte Sonntag im März und Oktober ist ausgehend vom gerade aktuellen Datum beim Anlagenstart. Also eine Funktion in etwa welcher Wochentag ist am xx.xx.xxxx oder eben eine Art ewiger Kalender in Bascom.
      Da fehlt mir im Moment irgendwie der Ansatz dazu.
    • Ich versteh' dein Problem noch nicht. Deine rtc hat doch alles parat, Normalzeit und Datum mit Wochentag und Jahr. Schaltjahre werden von der rtc doch auch berücksichtigt. Also muss dein Programm beim Starten doch nur checken, ist aktuell Sommerzeit, oder nicht. Gut, und das halt im laufenden Betrieb alle Stunde, um den möglichen Wechsel nicht zu verschlafen. Ähnliches werde ich auch haben, wenn ich die Zeit von GPS hole, die ist ja UTC.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Das Problem ist folgendes.
      Das ganze ist eine Alarmanlage mit dem Vorzug im "scharfen" Zustand absolut keinen Strom zu verbrauchen.
      Da fließen nur wenige µA für einen Langzeittimer (der auf einen 7555 und CD4020 besteht) der alle ca. 100 Stunden die Anlage aufweckt um einen Statusbericht per SMS zu senden oder im Auslösungsfall eben dann ein entsprechendes SMS abzusetzen.
      An der Stelle wo diese Anlage verwendet wird gibt es keinen Netzanschluss. Daher wird die mit einem 12V Pb Akku versorgt.

      Im Auslösefall (egal ob Alarm durch Kontakt oder Status durch Langzeittimer) wird die Anlage mit Strom versorgt und von der RTC Datum und Uhrzeit genommen.
      Nun kann es aber eben sein, dass in der Zeit zwischen den Auslösungen die Sommerzeitumschaltung war und die Berichtszeit nicht mehr stimmt.
      In der ersten Version musste man die RTC mangels Platz im Flash immer zweimal im Jahr anpassen was wiederum nur durch aktiven hingehen zur Anlage möglich ist weil die in ihrer Ruhephase ja nicht erreichbar ist.
      In der neuen Version habe ich aber ausreichend Flash um das zu automatisieren.
      Die Justierung kann aber nur bei der jeweiligen Aktivierung der Anlage erfolgen und muss daher bei jeder Aktivierung entsprechend geprüft werden.
      Wenn man sich den Zustand in einem Flag merkt ist das Setzen dann auch nur zweimal, die Prüfung aber bei jedem Einschalten.
      Bei Uhren die ständig stromversorgt sind, ist das ja kein Problem, da weiß man ja das aktuelle Datum immer und wartet einfach auf den letzten Sonntag im März 2:00 Uhr und schaltet um. Das ist ja kein Problem und habe ich schon mehrmals so angewendet.
      Dies funktioniert aber bei dem Funktionsprinzip der Anlage eben so nicht weil diese zum Umschaltzeitpunkt ziemlich sicher nicht zufällig aktiv sein wird.
      Das geht aber bei diesem Projekt so nicht, daher muss ich eben zum jeweiligen Aktivierungszeitpunkt entsprechende Maßnahmen treffen wenn die Zeit (und auch das Datum) stimmen soll
    • Wo ist denn jetzt das Problem?

      Die RTC läuft mit Normalzeit.

      Der Alarmfall tritt ein, dein AVR holt sich die Normalzeit aus der RTC und rechnet die Sommerzeit dazu.
      Dann Daten senden und wieder schlafen.

      Die Sommerzeit wechselt nicht um Mitternacht, also spielt das Datum keine Rolle, es stimmt trotzdem.

      Im Nicht-Schlafen Fall lässt du den AVR einfach jede Sekunde das ganze neu ausrechnen, dann passt es auch im Fall der Umschaltung.
    • Ein Beispiel:
      Die Anlage wird geweckt (wie oben erklärt ist das ein beliebiger nicht beeinflussbarer Zeitpunkt), es sei in der RTC 23:45 Normalzeit, das Datum sei Mittwoch, 12.06.19.
      Ich addiere zur Stunde +1 (da nach dem aktuellen Datum auf jeden Fall Sommerzeit vorherrschen muss, die Spezialitäten im März und Oktober beachte ich hier noch nicht mal), die Zeit wird somit auf 00:45 geändert, das Datum ist aber immer noch 12:06:19 und nicht Donnerstag der 13.06.19 was somit eben nicht korrekt ist.
      Das zu sendende Informationstelegramm würde somit mit 00:45 vom Mittwoch den 12.06.19 erstellt obwohl es eigentlich ein Tag später ist.

      Ist das Problem jetzt verständlich?

      Der "Nicht-Schlafen-Fall ist im ungünstigsten Fall ca. 30 Sekunden an (solange bis das GSM-Modul betriebsbereit ist und eine SMS abgesetzt hat, im Alarmfall solange bis der Alarm mit Sirene u.s.w. inklusive entschärfen abgehandelt wird.
      Anschließend schaltet die Anlage jedenfalls wieder komplett ab.
    • Also gut, dann eben nicht nur einfach + 1 Stunde zur Zeit sondern +3600 zur aktuellen sysec addieren. Aus der aktualisierten sysec kann dann die aktualisierte Zeit und auch das aktualisierte Datum entnommen werden. Dann passt doch wieder alles.

      Erstmal sysec holen, durch die Zeiten aus der rtc:
      Syntax
      Target = SYSSEC()
      Target = SYSSEC(bSecMinHour)
      Target = SYSSEC(strTime, strDate)
      Target = SYSSEC(wSysDay)
      Remarks
      TargetA Variable (LONG), that is assigned with the System-Second
      BSecMinHourA Byte, which holds the Sec-value followed by Min(Byte), Hour (Byte), Day(Byte), Month(Byte) and Year(Byte)
      StrTimeA time-string in the format „hh:mm:ss"
      StrDateA date-string in the format specified in the Config Date statement
      wSysDayA variable (Word) which holds the System Day (SysDay)



      dann Sommerzeit prüfen und gegebenenfalls +3600 und dann für die softclock wieder die Zeit und das Datum zurück rechnen lassen

      Syntax
      bSecMinHour = Time(lSecOfDay)
      bSecMinHour = Time(lSysSec)
      bSecMinHour = Time(strTime)
      strTime = Time(lSecOfDay)
      strTime = Time(lSysSec)
      strTime = Time(bSecMinHour)
      Remarks
      bSecMinHourA BYTE – variable, which holds the Second-value followed by Minute (Byte) and Hour (Byte)
      strTimeA Time – String in Format „hh:mm:ss"
      lSecOfDayA LONG – variable which holds Second Of Day (SecOfDay)
      lSysSecA LONG – variable which holds System Second (SysSec)



      Syntax
      bDayMonthYear = Date(lSysSec)
      bDayMonthYear = Date(lSysDay)
      bDayMonthYear = Date(strDate)
      strDate = Date(lSysSec)
      strDate = Date(lSysDay)
      strDate = Date(bDayMonthYear)
      Remarks
      StrDateA Date-String in the format specified in the
      CONFIG DATE statement
      LsysSecA LONG – variable which holds the System Second (SysSec = TimeStamp)
      LsysDayA WORD – variable, which holds then System Day (SysDay)
      BDayMonthYearA BYTE – variable, which holds Days, followed by Month (Byte) and Year (Byte). You can use a byte array, or 3 bytes dimensioned after each other.

      oder halt auf ein Datumsüberlauf prüfen. Den kann es ja nur in der Sommerzeit geben, da ja die rtc mit Winterzeit/Normalzeit läuft.

      Ok, ok, der Wochentag bedarf auch noch der Prüfung, der ist bei sysec nicht dabei X/
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von tschoeatsch ()

    • Zitronenfalter schrieb:

      die Zeit wird somit auf 00:45 geändert, das Datum ist aber immer noch 12:06:19 und nicht Donnerstag der 13.06.19 was somit eben nicht korrekt ist.

      tschoeatsch schrieb:

      sondern +3600 zur aktuellen sysec addieren
      Ich hatte das in der ersten Antwort, also in Beitrag Nr.2 bereits geschrieben.
      In Beitrag Nr.11 hat es Six1 nochmals angesprochen.
      Tschoeatsch hat es jtzt hoffentlich verständlich erklärt.
    • @Zitronenfalter dein Problem hab' ich, glaub' ich erkannt, und finde es auch ganz interessant, es zu lösen. Eben, weil ich ja mal probieren will, die Zeit aus dem GPS zu holen. Wenn ich damit eine Uhr bauen möchte, dann will ich ja auch eine zeitnahe (genaue) Umschaltung auf Sommer/Winterzeit. Also muss ich dann entsprechend die vom GPS gelieferte UTC in die Ortszeit umrechnen. Auch wird ja kein Wochentag von GPS übermittelt (glaub' ich zumindest bis jetzt, muss ich noch prüfen), also muss man sich selbst drum kümmern. Das sollte aber durch sysec relativ leicht möglich sein. sysec fängt bei '2000-01-01 at 00:00:00 starts with 0' an. Jetzt such man sich den Wochentag dazu raus. Das ist dann der Stichwochentag. Wenn man jetzt die aktuellen sysec durch die Sekunden-einer-Woche teilt, dann hat man den gleichen Wochentag wie der Stichwochentag und die Restsekunden sind der Zeitraum bis zur aktuellen Zeit. Diese Restsekunden durch Sekunden-für-einen-Tag geteilt ergibt die Tage nach dem Stichwochentag und damit kann man bis zum aktuellen Wochtag zählen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

    • tschoeatsch schrieb:

      Ok, ok, der Wochentag bedarf auch noch der Prüfung, der ist bei sysec nicht dabei
      Das nicht, wird aber mit DayOfWeek (da aber nullbasierend) ausgegeben.

      Jetzt muss ich mir nur mehr überlegen wie ich den Bereich abprüfe in dem die Sommerzeit exakt vorherrscht um dann auch die 3600 Sekunden zu addieren.
      Und die ganzen Routinen gehören dann auch verändert, weil ja Time$, Date$ und das GetDateTime so nicht mehr stimmen. Aber das ist das geringste Problem



      Michael schrieb:

      Tschoeatsch hat es jetzt hoffentlich verständlich erklärt.
      Zumindest in die richtige Richtung "gestuppst" (gestern war es schon spät ^^ ).