[gelöst] Programm bekommt die Zeitumstellung nicht mit

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 169
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64 x86_64-linux-gtk2
CPU-Target: i386, win64, arm

[gelöst] Programm bekommt die Zeitumstellung nicht mit

Beitrag von willi4willi »

Hallo!

In dieser Nacht wurde wieder auf Sommerzeit umgeschaltet.

Mein Programm lief die Nacht durch und hatte heute morgen noch die alte Zeit.
Wenn man das Programm beendet und wieder neu startet, dann ist die Zeitanzeige in Ordnung.

Wie kann einem laufenden Programm die Zeitumstellung mitgeteilt werden?

Offensichtlich wird die Variable TzSeconds nur beim Programmstart initialisiert.
Zuletzt geändert von willi4willi am Mo 31. Mär 2014, 13:16, insgesamt 1-mal geändert.
 

Viele Grüße

Willi4Willi

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

BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von BeniBela »

Nah, da ist kein Bug, das Programm ist nur vernünftig.

Die Sommerzeit ist überflüssiger Quatsch und sollte abgeschafft werden!

Vielleicht hilft es wenn jeder dein Programm einsetzt

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von mschnell »

Da kann man aber durchaus anderer Ansicht sein. Ich finde es höchst angenehm, dass es abends länger hell ist. :D

Bezüglich Programmierung, bin ich der Ansicht, ein Programm sollte intern grundsätzlich in UTC arbeiten. Nur das User-Interface sollte eine Umrechnung anhand von Locale machen. Soweit ich weiß, stellt die FPC RTL für diese Umrechnung (hin und zurück) zur Verfügung.

-Michael

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von Christian »

78% der Deutschen sind nicht deiner Ansicht ;)
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 169
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64 x86_64-linux-gtk2
CPU-Target: i386, win64, arm

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von willi4willi »

Hallo,

nachdem ich jetzt viel herumprobiert habe, konnte ich die Ursache selbst finden.

Unter Windows funktionierte es einwandfrei. Unter Linux gab es das Problem.
Es ist offensichtlich in der Funktion "GetLocalTimeOffset" ein Bug?

Stellt man das System-Datum auf 30.03.2014 01:59:55 und startet dann folgendes kleine Programm:

Code: Alles auswählen

 
...
 
implementation
 
uses lazutf8sysutils,dateutils;
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  memo1.Lines.Add('Universal Time: '+DateTimeToStr(nowUTC()));
  memo1.Lines.Add('Local Time: '+DateTimeToStr(UniversalTimeTolocal(nowUTC(),GetLocalTimeOffset)));
  memo1.Lines.Add('Local Time: '+DateTimeToStr(UniversalTimeTolocal(nowUTC())));
  memo1.Lines.Add('Local Time: '+DateTimeToStr(now()));
  memo1.Lines.Add('Local TimeOffset: '+inttostr(GetLocalTimeOffset));
  memo1.Lines.Add('-----');
end;
...
 
 
Dann macht es unter Windows das:

Code: Alles auswählen

 
---
Universal Time: 30-3-14 00:59:59
Local Time: 30-3-14 01:59:59
Local Time: 30-3-14 01:59:59
Local Time: 30-3-14 01:59:59
Local TimeOffset: -60
-----
Universal Time: 30-3-14 01:00:00
Local Time: 30-3-14 03:00:00
Local Time: 30-3-14 03:00:00
Local Time: 30-3-14 03:00:00
Local TimeOffset: -120
-----
Universal Time: 30-3-14 01:00:01
Local Time: 30-3-14 03:00:01
Local Time: 30-3-14 03:00:01
Local Time: 30-3-14 03:00:01
Local TimeOffset: -120
-----
Universal Time: 30-3-14 01:00:02
Local Time: 30-3-14 03:00:02
Local Time: 30-3-14 03:00:02
Local Time: 30-3-14 03:00:02
Local TimeOffset: -120
-----
 
und unter Linux das:

Code: Alles auswählen

 
---
Universal Time: 30-3-14 00:59:59
Local Time: 30-3-14 01:59:59
Local Time: 30-3-14 01:59:59
Local Time: 30-3-14 01:59:59
Local TimeOffset: -60
-----
Universal Time: 30-3-14 01:00:00
Local Time: 30-3-14 02:00:00
Local Time: 30-3-14 02:00:00
Local Time: 30-3-14 02:00:00
Local TimeOffset: -60
-----
Universal Time: 30-3-14 01:00:01
Local Time: 30-3-14 02:00:01
Local Time: 30-3-14 02:00:01
Local Time: 30-3-14 02:00:01
Local TimeOffset: -60
-----
Universal Time: 30-3-14 01:00:02
Local Time: 30-3-14 02:00:02
Local Time: 30-3-14 02:00:02
Local Time: 30-3-14 02:00:02
Local TimeOffset: -60
-----
 
 
Wenn man das Linux-Programm beendet und neu startet, ist die Welt wieder in Odnung.
 

Viele Grüße

Willi4Willi

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

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von Mathias »

Die Sommerzeit ist überflüssiger Quatsch und sollte abgeschafft werden!
Ich währe eher dafür, die Winterzeit abzuschaffen, dann hätte man im Winter wenigstens am Abend 1 Stunde länger hell.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von mschnell »

Mathias hat geschrieben:
Die Sommerzeit ist überflüssiger Quatsch und sollte abgeschafft werden!
Ich währe eher dafür, die Winterzeit abzuschaffen, dann hätte man im Winter wenigstens am Abend 1 Stunde länger hell.
Das nützt ja wohl gar nichts, da sich die Leute dann anpassen und nach einigen Jahren ist alles beim alten nur "nominal" eine Stunde verschoben.

Meine Lieblings-Variante ist diese:
- Momentan ist die "Normal"-Zeit (nicht Sommerzeit) daran festgemacht, dass zu einer bestimmten Zeit (12:00 Mittags) an einem bestimmten Ort in einer Zeitzone die Sonne im Zenit steht.
- Mein Wunsch wäre, dass man definiert, dass die Sonne immer zu einer bestimmten Zeit an einem bestimmten Ort in einer Zeitzone untergehgt. Der Breitengrad des Ortes sollte so gewählt werden, dass die Tageslänge (zwischen Sonnenaufgang und Sonnenuntergang) an diesem Ort um (z.B.) 3 Stunden variiert.

Dann hatte man keine jährliche "Zeit-Umstellung" und trotzdem bleibt die Stunde des Sonnenuntergangs überall einigermaßen konstant.

Fände ich höchst angenehm. Die langsam floatenden Tageslänge ist aber technisch natürlich nicht so leicht zu realisieren.

-Michael

grl
Beiträge: 36
Registriert: Fr 17. Okt 2008, 19:24
OS, Lazarus, FPC: Debian X64, Lazarus 1.1, FPC 2.7.1
CPU-Target: x86, ARM

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von grl »

BeniBela hat geschrieben:Die Sommerzeit ist überflüssiger Quatsch und sollte abgeschafft werden!
Grundsätzlich bin ich ja auch der Meinung - aber das löst das Problem nicht. Und ich hab genau das gleiche Problem und wäre daher an einer Lösung ebenfalls interessiert - vor allem weil in meinem Fall das Programm als Daemon auf einem Server rennt und daher ein Neustart extrem unelegant ist...

Gruß
GRL

Benutzeravatar
willi4willi
Lazarusforum e. V.
Beiträge: 169
Registriert: Sa 1. Nov 2008, 18:06
OS, Lazarus, FPC: Lazarus 3.8 FPC 3.2.2 x86_64-win64-win32/win64 x86_64-linux-gtk2
CPU-Target: i386, win64, arm

Re: Programm bekommt die Zeitumstellung nicht mit

Beitrag von willi4willi »

Hallo,

danke für die vielen tollen Tipps. ;-)

Doch ich muss ehrlich gestehen, keine dieser Lösungen habe ich nachverfolgt. Weder die Abschaffung der Sommerzeit, noch eine ständige Sommerzeit oder eine geniale Zeit, bei der es ein Mittel zwischen Sommerzeit und Normalzeit gibt, konnte ich umsetzen. Sollen das mal die Politiker machen!

Für grl habe ich mich noch einmal zu Wort gemeldet, um meine funktionierende (aber nicht so geniale) Lösung zu hinterlassen:

Code: Alles auswählen

 
unit Localtime;
{$mode objfpc}{$H+}
 
interface
 
uses  Classes, SysUtils;
 
 function GetLocalTimeOffset: Integer;           //< Zeitunterschied zur Universalzeit in Minuten
 function UTCToLocal(UT: TDateTime): TDateTime;  //< wandelt UTC in lokale Zeit
 function LocalToUTC(LT: TDateTime): TDateTime;  //< wandelt lokale Zeit in UTC
 function UTC:TDateTime;                         //< gibt die UTC zurück
 
implementation
 
uses {$IFDEF MSWINDOWS} windows {$ENDIF} {$IFDEF UNIX} process{$ENDIF};
 
{$IFDEF UNIX}
function RufeKommando(kdo:string):string;
var   process : TProcess;
      slOutput : TStringList;
         ErgStr : String;
begin
  process := TProcess.Create(nil);
  try
    slOutput := TStringList.Create;
    try
      process.CommandLine := kdo;
      process.Options := process.Options + [poWaitOnExit, poUsePipes];
      process.Execute;
      slOutput.LoadFromStream(process.Output);
      if slOutput.Count > 0 then Result:=slOutput[0]
                                     else result := '';
    finally
      FreeAndNil(slOutput);
    end;
  finally
    FreeAndNil(process);
  end;
end;
{$ENDIF}
 
function GetLocalTimeOffset: Integer;
{$IFDEF UNIX}
var kdoErg : String;
begin
  kdoErg:=RufeKommando('date +%z');
  if kdoErg<>'' then Result:=-StrToInt(copy(kdoErg,1,1)+IntToStr(StrToInt(copy(kdoErg,2,2))*60+StrToInt(copy(kdoErg,4,2))))
                     else Result:=0;
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
var  BiasType: Byte;
          TZInfo: TTimeZoneInformation;
const  BS_TYPE_UKNOWN = 0 ;
       BS_TYPE_STANDARD = 1 //< Normalzeit ;
        BS_TYPE_DAYLIGHT = 2 //< Sommerzeit ;
begin
  Result := 0;
  BiasType := GetTimeZoneInformation(TZInfo);
  if (BiasType=BS_TYPE_UKNOWN) then Exit;
  if (BiasType=BS_TYPE_DAYLIGHT) 
    then   Result := TZInfo.Bias + TZInfo.DaylightBias
     else if (BiasType=BS_TYPE_STANDARD) then
        Result := TZInfo.Bias + TZInfo.StandardBias;
end;
{$ENDIF}
 
function UTCToLocal(UT: TDateTime): TDateTime;
var  LT: TDateTime;
  TZOffset: Integer;
begin
  LT := UT;
  TZOffset := GetLocalTimeOffset;
  if (TZOffset > 0) 
     then  LT := UT - EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)
     else if (TZOffset = 0) 
               then   LT := UT
               else if (TZOffset < 0) 
                     then LT := UT + EncodeTime(Abs(TZOffset) div 60, Abs(TZOffset) mod 60, 0, 0);
  Result := LT;
end;
 
function LocalToUTC(LT: TDateTime): TDateTime;
var  UT: TDateTime;
  TZOffset: Integer; 
begin
  UT := LT;
  TZOffset := GetLocalTimeOffset;
   if (TZOffset > 0) 
     then  UT := LT + EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)
     else if (TZOffset = 0) 
             then UT := LT
             else if (TZOffset < 0) 
                    then  UT := LT - EncodeTime(Abs(TZOffset) div 60, Abs(TZOffset) mod 60, 0, 0);
  Result := UT;
end;
 
function UTC:TDateTime;
{$IFDEF UNIX}
var kdoErg   : String;
  Systemzeit : TSystemTime;
begin
  kdoErg:=RufeKommando('date -u +%Y%m%d%H%M%S%N');
  if kdoErg<>'' then
  begin
    SystemZeit.Year        := StrToInt(copy(kdoErg,1,4));
    SystemZeit.Month       := StrToInt(copy(kdoErg,5,2));
    SystemZeit.Day         := StrToInt(copy(kdoErg,7,2));
    SystemZeit.Hour        := StrToInt(copy(kdoErg,9,2));
    SystemZeit.Minute      := StrToInt(copy(kdoErg,11,2));
    SystemZeit.Second      := StrToInt(copy(kdoErg,13,2));
    SystemZeit.MilliSecond := StrToInt(copy(kdoErg,15,3));
    Result:=SystemTimeToDateTime(Systemzeit);
  end
  else Result:=0;
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
  begin
    Result:=LocalToUTC(now);
  end;
{$ENDIF}
end.
 
 
Vielleicht hilft dieses weiter.
 

Viele Grüße

Willi4Willi

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

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: [gelöst] Programm bekommt die Zeitumstellung nicht mit

Beitrag von mse »

Wenn ich mich recht erinnere, wurde das Linux/Unix-Problem auf der FPC Mailinglist des Langen und Breiten diskutiert und alle vorgeschlagenen Lösungen verworfen - dies geschieht in FPC ab und zu ;-).
Die MSEgui Variante von now(), nowlocal()/nowutc() berücksichtigt die automatische Sommerzeit-Umstellung.

Antworten