[DELPHI] datetimestamp probleem

Pagina: 1
Acties:
  • 133 views sinds 30-01-2008
  • Reageer

  • JozyDaPozy
  • Registratie: December 2002
  • Laatst online: 24-09 20:28
Ik moet in een xml-bericht de huidige datum/tijd in een bepaald formaat wegschrijven.
Echter ontbreekt er documentatie en ik begrijp niet helemaal hoe ik het moet oplossen.

Een voorbeeld-stamp is deze:
2004-12-24T10:56:05.3824672+01:00

Het probleem is dat ik hier met de normale formatdatetime niet uitkom. volgens mij zijn de getallen na de sec. namelijk geen ms (die ik met 'z' zou kunnen maken), maar decimale waardes van de secondes. Hoe kan ik dit in Delphi voor elkaar krijgen.

Ik heb nu deze code:
code:
1
    result := formatdatetime('yyyy-mm-dd',now) + 'T' + formatdatetime('hh:nn:ss',now) + '+01:00';

maar daar ontbreekt dus nog de waarde achter de secondes.

  • Paul
  • Registratie: September 2000
  • Laatst online: 18:18
Maakt het heel veel uit wat je er neerzet? Of moeten het slechts 7 cijfers zijn en is alles kleiner dan een duizendste niet van belang?

In je code zit trouwens een bug: Je vraagt 2x Now() op. Je kunt dus, in het (minieme :P) geval dat net de datum verspringt tussen de eerste en de 2e keer, een dag achterlopen.

Het lijkt overigens verdacht veel op de ISO notatie, maar daar zie ik zo 123 niets kleiners dan secondes staan?

Delphi:
1
2
3
4
function CreateDateTimeString(When: TDateTime; TimeZone: Float): String;
begin
  Result := FormatDateTime('YYYY-MM-DD"T"HH":"NN":"SS":"ZZZ0000', When) + FormatFloat('"+"00.00;"-"00.00', TimeZone);
end;

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • The Fox NL
  • Registratie: Oktober 2004
  • Laatst online: 10:15
Komen die cijfers achter de komma echt zo nauw?

Anders doe je gewoon dit:

Delphi:
1
Result := FormatDateTime('yyyy-mm-dd"T"hh:nn:zzz', Now) + '0000+01:00');


De laatste vier cijfers zijn dan altijd 0, maar voor de rest klopt het wel.

edit: wat Paul Nieuwkamp zegt dus

[ Voor 9% gewijzigd door The Fox NL op 05-01-2007 19:19 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:04
Welke Delphi gebruik je ?

https://fgheysels.github.io/


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01-12 21:29

Tomatoman

Fulltime prutser

FormatDateTime maakt altijd gebruik van een ingebouwde computerklok, die nogal onnauwkeurig is. Het is niet ongebruikelijk dat de computerklok minimaal een minuut per dag afwijkt (en vervolgens automatisch weer gesynchroniseerd wordt door Windows). Je moet je dan ook niet blindstaren op die milliseconden - de kans is groot dat de klok minimaal een paar seconden afwijkt van de 'echte' tijd.

Vind je het idee van de vorige reacties om eenvoudigweg 0000 te gebruiken voor de microseconden niet geweldig, dan kun je overwegen daar een random getal voor in te vullen. Maar realiseer je dan wel dat als je een tijd genereert en direct daarachteraan een tweede tijd genereert, die tweede tijd door het random getal eerder kan zijn dan de eerste tijd!

Dan de tijdzone. Zie hier voor meer informatie om te achterhalen in welke tijdzone je computer werkt. In het Engels heet de afwijking (+01.00) als gevolg van de tijdzone 'bias'.
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uses
  Windows;

function CreateDateTimeString(const When: TDateTime): string;
var
  DateTimeStr, BiasSign, BiasStr: string;
  TimeZoneInfo: TTimeZoneInformation;
begin
  DateTimeStr := FormatDateTime('YYYY-MM-DD"T"HH":"NN":"SS":"ZZZ0000', When);
  GetTimeZoneInformation(TimeZoneInfo);
  if TimeZoneInfo.Bias > 0 then
    BiasSign := '-'
  else
    BiasSign := '+';
  BiasStr := FormatDateTime('HH.NN', TimeZoneInfo.Bias/(24*60));
  Result := DateTimeStr + BiasSign + BiasStr;
end;

Een goede grap mag vrienden kosten.


  • Paul
  • Registratie: September 2000
  • Laatst online: 18:18
tomatoman schreef op zaterdag 06 januari 2007 @ 10:45:
FormatDateTime maakt altijd gebruik van een ingebouwde computerklok
Bedoel je niet Now ? FormatDateTime gebruikt de aangeleverde TDateTime.

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 01-12 21:29

Tomatoman

Fulltime prutser

Paul Nieuwkamp schreef op zaterdag 06 januari 2007 @ 15:47:
[...]
Bedoel je niet Now ? FormatDateTime gebruikt de aangeleverde TDateTime.
Je hebt helemaal gelijk :)

Een goede grap mag vrienden kosten.


  • AVee
  • Registratie: Oktober 2006
  • Laatst online: 09-11 20:54
Het is ISO en kleiner dan secondes mag zoveel als je nodig vindt, mits beide partijen het daar over eens zijn. Wikipedia heeft een hoop info en de spec is er ook in PDF.
Ik vermoed dat je er best mee weg komt als je wat minder cijfers achter de komma meestuurt. Sowieso haal je met een normale PC klok dat soort nauwkeurigheid niet. Als het vooral gaat om het uniek maken van het getal zou je er GetTickCount() mod 1000 achter kunnen plakken.

Overigens kan ik me van Delphi 6 herinneren dat TDateTime een beetje een naar ding was als het om nauwkeurigheid gaat. Dat is intern een floating point getal, met de bijbehorende afrondingsproblemen, ik weet niet of het echt uit maakt, maar je bent in elk geval gewaarschuwd.

Verwijderd

Een TDateTime is intern een double, waarbij de datum voor de komma staat, en de tijd erachter. Prima formaat om een tijdstip in op te slaan, en afrondingsproblemen krijg je pas vanaf de zoveelste milliseconde.

  • AVee
  • Registratie: Oktober 2006
  • Laatst online: 09-11 20:54
Verwijderd schreef op maandag 08 januari 2007 @ 00:47:
Een TDateTime is intern een double, waarbij de datum voor de komma staat, en de tijd erachter. Prima formaat om een tijdstip in op te slaan, en afrondingsproblemen krijg je pas vanaf de zoveelste milliseconde.
Inderdaad, en op willekeurige momenten als uitkomsten van berekeningen vergelegen worden, of zo af en toe komt een timestamp net even anders terug dan dat ie de database in gegegaan is en meer van dat soort grappen. Probeer dan maar eens te ontdekken wat er precies gebeurt...
Het is verder offtopic hier, maar floats gebuiken voor het oplslaan van een tijd is, hoe mooi het ook lijkt, een vreselijk dom idee.

  • Paul
  • Registratie: September 2000
  • Laatst online: 18:18
Tijd zelf is sowieso al een heel dom iets om met een =-operator te vergelijken, dus dat gaat ook niet echt op :P Als je aan een mens vraagt "is het 7 uur?" dan zal deze na een blik op zijn horloge het hele stuk tussen, zeg, 06:54 en 07:06, en 18:54 en 19:06" of zelfs groter, bevestigend antwoorden. Een computer zegt in 99,9999999999999999999999% van die gevallen keihard nee. Tijd zelf (en zeker generated timestamps) zijn dus zelden (voor een computer) te ==-en.

Daarnaast komt er uit een EncodeTime met dezelfde parameters keer op keer op keer exact dezelfde uitkomt en slaan databases het intern ofwel op als integer-iets, of er wordt aangegeven met welke precisie de float werkt. MSSQL 2000 heeft een precisie van 3,33 ms bijvoorbeeld.

Het is dus iets om rekening mee te houden, maar dat geld altijd en overal voor floating point getallen. Als ik jouw redenatie doortrek (vergelijken met andere waardes, in een database zetten, zijn typische dingen om met variabelen te doen, dat deze ene nu net een tijd uitdrukt is van ondergeschikt belang) is het uberhaupt gebruiken van floats dus een vreselijk dom idee :?

[ Voor 18% gewijzigd door Paul op 08-01-2007 10:55 ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • AVee
  • Registratie: Oktober 2006
  • Laatst online: 09-11 20:54
Het gebruiken van floats voor dingen die je exact kunt opslaan is inderdaad altijd een dom idee. Dat geld voor tijdstippen waarvan je de nauwkeurigheid gewoon weet, maar bijvoorbeeld ook voor prijzen en dergelijke. Een floating point gebruik je als de decimale punt moet kunnen verschuiven, dus als je zowel extreem grote als extreem kleine getallen wilt kunnen gebruiken. Tijd is prima af te handelen op een vaste nauwkeurigheid, bijvoorbeeld in ms. De meeste programeertalen doen dat ook, en dat is niet voor niets.

Verwijderd

AVee schreef op maandag 08 januari 2007 @ 10:25:
Inderdaad, en op willekeurige momenten als uitkomsten van berekeningen vergelegen worden, of zo af en toe komt een timestamp net even anders terug dan dat ie de database in gegegaan is en meer van dat soort grappen. Probeer dan maar eens te ontdekken wat er precies gebeurt...
Doubles in Delphi hebben de eigenaardige eigenschap om hardnekkig dezelfde waarde te houden wanneer ze eenmaal gezet zijn. Wanneer een timestamp anders uit de database terugkomt dan dat je 'm erin gestopt had (of dacht te hebben), moet je het zoeken in je data access layer, en niet in het feit dat Borland voor een float gekozen heeft voor het opslaan van tijdstippen.

Of je kiest voor een integer-oplossing (met dan een beperking in het aantal cijfers achter de komma bij millisecs) of een float (met afrondingsverschillen in datzelfde stuk achter de komma) is een design kwestie, maar de ene benadering is niet beter of slechter dan de andere.
Pagina: 1