23. januar 2002 - 19:55
Der er
45 kommentarer og 3 løsninger
Sekunder siden 1970-01-01 00:00:00
I forbindelse med at skrive noget i en MySql database, skal jeg bruge en funktion i Delphi, der kan konvertere dag dato klokken nu til antal sekunder siden 1970-01-01 00:00:00. Findes der ikke en smart funktion i Delphi til dette formål? /Torsten
Annonceindlæg tema
Offentlig digitalisering
Fra effektivisering til digital suverænitet. Hvordan skaber det offentlige en digital fremtid med AI, sikkerhed og kontrol i centrum?
23. januar 2002 - 19:59
#1
Jeg bruger denne kode som jeg fandt på en eller anden side: unixtime := (YourDateTime-EncodeDate(1970,1,1)) * SecsPerDay;
23. januar 2002 - 20:01
#2
SecsPerDay := 86400; Mener jeg det er (24*60*60).
23. januar 2002 - 20:02
#3
Hvis du bruger tabel komponent kan du bruge AsDateTime, den kaster for dig Hvis du bruger Query er der et eksempel neden under, AlDate er af typen Date, og alTime er af typen time DateTimeToString(TestAlDate,'yyyy-mm-dd',Now); TestAlTime := Now; QueryMakeAl := TmySQLQuery.Create(Self); if MyDB.Connected then with QueryMakeAl do begin Database := MyDB; Close; SQL.Text := 'SELECT MAX(ID) as NextID FROM aldb'; Open; NextId := FieldByName('NextID').AsInteger + 1; DisableControls; SQL.Clear; SQL.Add('INSERT INTO aldb (Id, AppNo, AlType, AlDate, AlTime, AlText) ' + ' VALUES ('''+ IntToStr(NextId)+ ''','''+ '1'','''+ ''+ IntToStr(TestAlType) +''','''+ ''+ TestAlDate + ''',''' + ''+ TimeToStr(TestAlTime) + ''',''' + 'Test alarm nr: ' +IntToStr(TestAlNo)+''')'); MessageMemo.Lines.Add(sql.text); ExecSQL; EnableControls; end; Inc(TestAlNo); QueryMakeAl.Free; end;
23. januar 2002 - 20:04
#4
Hmm.. Så vil jeg da mene at den metode jeg har fundet er lidt nemmere. O_o
23. januar 2002 - 20:07
#5
det kan jeg ikke afvise :)
23. januar 2002 - 20:09
#6
Hæhæ. Jeg sad og arbejdede med at gennemskue den, og var inde på noget af det rigtige.. Til sidst opgav jeg og fandt denne funktion. Lille og simpel. :o)
23. januar 2002 - 20:10
#7
Men hvis det er et tabelkomponent kan han jo gemme direkte MySqlTabel.FieldByName('DatoFelt').AsDateTime := Now
23. januar 2002 - 20:12
#8
Hmm.. Ja det er jo rigtigt nok. :o) Min var mere generelt. :o)
23. januar 2002 - 20:26
#9
Ok, UnixTime er af typen extended. Bruger jeg unixtime := (EncodeDate(2002,1,1)-EncodeDate(1970,1,1)) er værdien af unixtime = 0 ?? nogen logisk forklaring, og hvordan konverterer jeg efterfølgende unixtime til en string?
23. januar 2002 - 20:30
#10
Men EncodeDate er af typen datetime procedure TForm1.Button1Click(Sender: TObject); var UnixTime : TDateTime; begin UnixTime := (EncodeDate(2002,1,1)-EncodeDate(1970,1,1)); ShowMessage(DateTimeToStr(UnixTime)); end;
23. januar 2002 - 20:33
#11
Hvis du bruger D6 er der en indbugget functione til det secondsbetween Husk at tilføje dateutils i uses procedure TForm1.Button1Click(Sender: TObject); begin showmessage('Sekunder siden 1970: ' +inttostr(secondsbetween(now, 01-01-1970 ))); end; Stoney
23. januar 2002 - 20:40
#12
Desværre, jeg bruger Delphi 5. Men nu har jeg så forskellen i variablen UnixTime, men hvordan får jeg så at vide hvor mange sekunder, det er?
23. januar 2002 - 20:42
#13
Det skrev jeg altså også. Gang tallet du får med antallet af sekunder på et døgn.. unixtime := (EncodeDate(2002,1,1)-EncodeDate(1970,1,1)) * 86400;
23. januar 2002 - 20:42
#14
Du ganger det vel bare sammen (antalår*365+antaldage)*24*60*60
23. januar 2002 - 20:45
#15
morten_s>> hvad når det er skudår ? Stoney
23. januar 2002 - 20:45
#16
DateTime indeholder antallet af dage siden, et eller andet tidspunkt.
23. januar 2002 - 20:46
#17
Jep The integral part of a TDateTime value is the number of days that have passed since 12/30/1899
23. januar 2002 - 20:48
#18
Men hvordan viser jeg så resultatet på f.eks. på en messagebox?
23. januar 2002 - 20:50
#19
Hmm.. Du kan jo konvertere tiden til en int og så bruge IntToStr. :o)
23. januar 2002 - 20:52
#20
Jeg forstår stadig ikke hvorfor den skal over i sekunder, når du kan typecaste til din MySql db sådanher MySqlTabel.FieldByName('DatoFelt').AsDateTime := Now;
23. januar 2002 - 20:54
#21
morten_s: Jeg mente når du ville gange med 365. Jeres løsning giver stadig ikke et nøjagtigt resultat. Hvis du i dag kl. 14 og kl. 16 spørger hvor mange sekunder der er gået siden i går kl. 18, vil Tdatetime sige 1 dag * 86400 uanset om det er kl 14 eller 16. Håber du forstår hvad jeg mener. Stoney
23. januar 2002 - 20:56
#22
stoney> forstår ikke hvorfor omregningen skal foretages når der findes funktioner til at gemme i db'en uden at regne om ?
23. januar 2002 - 20:56
#23
TDateTime indeholder et decimaltal der *vil* give det nøjagtige tal når det ganges med 86400.
23. januar 2002 - 20:57
#24
angelod: Sådan helt præcist, det med jonglering mellem typer er ikke lige min stæke side :-( morten_s: fordi at det så vidt jeg ved skal skrives som sekunder i INSERT statementet.
23. januar 2002 - 20:59
#25
morten_s: Jeg er heller ikke helt med, men mon ikke AABOE skal poste antal sekunder siden 1970 samtidig. angelod: gider du uddybe dit sidste indlæg, den er jeg kke helt med på. Stoney
23. januar 2002 - 21:01
#26
Jeg skriver det aldrig som sekunder, jeg har normalt opdelt dato og tid i hver sin række. et insert statement laver jeg sådan her DateTimeToString(TestAlDate,'yyyy-mm-dd',Now); TestAlTime := Now; DisableControls; SQL.Clear; SQL.Add('INSERT INTO aldb (Id, AppNo, AlType, AlDate, AlTime, AlText) ' + ' VALUES ('''+ IntToStr(NextId)+ ''','''+ '1'','''+ ''+ IntToStr(TestAlType) +''','''+ ''+ TestAlDate + ''',''' + ''+ TimeToStr(TestAlTime) + ''',''' + 'Test alarm nr: ' +IntToStr(TestAlNo)+''')'); ExecSQL; EnableControls; Værdierne bliver altså overført til MySql som strenge
23. januar 2002 - 21:01
#27
unixtime := Int((EncodeDate(2002,1,1)-EncodeDate(1970,1,1)) * 86400);
23. januar 2002 - 21:03
#28
for overskuelighedens skyld: DateTimeToString(TestAlDate,'yyyy-mm-dd',Now); TestAlTime := Now; DisableControls; with myQuery do begin SQL.Clear; SQL.Add('INSERT INTO MinTabel (AlDate, AlTime) ' + ' VALUES ('''+ TestAlDate + ''',''' + ''+ TimeToStr(TestAlTime) +''')'); ExecSQL; EnableControls; end;
23. januar 2002 - 21:04
#29
Og jeg er sikker på at du kan gøre det samme med et DateTime felt alt overføres som strenge til MySql databasen
23. januar 2002 - 21:08
#30
angelod: Problemet er bare at UnixTime stadig SKAL være en extended. Hvordan hiver jeg antal sekunder ud fra denne og f.eks. præsenterer det på en showmessage. Tak for tålmodigheden . . .
23. januar 2002 - 21:12
#31
aaboe> Det med sekunderne er en blindgyde, gør som jeg viser dig ovenover du undgår konverteringsproblemerne, og koden virker hos mig
23. januar 2002 - 21:12
#32
unixtime := Round((EncodeDate(2002,1,1)-EncodeDate(1970,1,1)) * 86400); Sådan.. Har testet det, og det virker. :o)
23. januar 2002 - 21:15
#33
Hvorfor Round, ryger der ikke et par sekunder i svinget :)
23. januar 2002 - 21:19
#34
Nix. Ikke et eneste. Har testet.
23. januar 2002 - 21:20
#35
angelod: cool, nu har jeg så det i sekunder, hvordan konverterer jeg den til en streng, som jeg kan skrive i databasen. morten_s: Jeg synes stadig at angelods er simplest, men hvis jeg ikke kan få det til at virke, kan det være jeg giver dit eksempel en chance :-)
23. januar 2002 - 21:22
#36
IntToStr(unixtime); :o)
23. januar 2002 - 21:23
#37
Der er ingen tvivl om at angelod eks. virker, men med en fejlmargen på mellem 0 og 86399 sekunder. i den mest extreme situation. :-) Stoney
23. januar 2002 - 21:26
#38
Stoney> Det er da rimelig præcist ramt inden for 23 timer og 59 sek.
23. januar 2002 - 21:29
#39
Der er ingen fejlmargen da.. Hvis han bruger EncodeDate så får han kun for dagen, ja.. Men han kan altså bruge Now som vil give det nøjagtige resultat..
23. januar 2002 - 21:32
#40
EncodeDate giver kun dagen uanset om der bruges Now eller ej, den indeholder ikke tiden, så de sekunder der er gået i det pågældende døgn går tabt
23. januar 2002 - 21:34
#41
Argh!! Fat det dog! unixtime := Round((Now-EncodeDate(1970,1,1)) * 86400); Dette vil give UNIX tiden for lige nu.
23. januar 2002 - 21:45
#42
angelod> du er galt på den, round piller dine sekunder af now. Sekunderne står nemelig bag kommaet. Hvis du ikke vil tro det så prøv nedenstående eksempel, du kan sætte et breakpoint på den sidste showmessage og aflæse de to værdier med og uden round procedure TForm1.Button1Click(Sender: TObject); var MinTidMedRound : TDateTime; MinTidUdenRound : TDateTime; begin MinTidMedRound := Round(Now); ShowMessage(DateTimeToStr(MinTidMedRound)); MinTidUdenRound := Now; ShowMessage(DateTimeToStr(MinTidUdenRound)); end;
23. januar 2002 - 21:52
#43
angelod> Bemærk i øvrigt at round(now) lige runder op så det er den 24 i dag, det øger din fejmargin til 47 timer og 59 sek. :-0
23. januar 2002 - 21:53
#44
Hey, hov.. Vent nu lige lidt! Round afrunder det der står inde i parantesen, altså: (Now-EncodeDate(1970,1,1)) * 86400
23. januar 2002 - 22:01
#45
Hvis der ingen sekunder skal mistes så må rest i nedenstående vel være 0 ? Prøv selv Rest := Frac( (Now-EncodeDate(1970,1,1)) * 86400);
23. januar 2002 - 22:04
#46
Pis.. Der var noget der.. Hmm, havde testet de forkerte tal.. Underligt, må ha lavet en fejl i forhold til den funktion jeg fandt.. Den virkede nemlig.. Hmm.. :/
23. januar 2002 - 23:07
#47
Så virker det! Jeg fik angelods løsning til at virke, og det spiller bare. Dog skulle jeg trække 3600 sekunder fra resultatet, hvilket må skyldes noget med vinter/sommertid. Jeg havde ingen problemer med at der var noget, der blev rundet forkert af. Tidspunkterne passer helt perfekt. Tak for alle de gode forslag, og tålmodigheden :-).
23. januar 2002 - 23:10
#48
Takker :o)
Kurser inden for grundlæggende programmering