Autor Téma: TDate má "skrytý" čas  (Přečteno 511 krát)

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3228
  • Karma: 30
    • Verze Delphi: XE7 professional
TDate má "skrytý" čas
« kdy: 04-02-2018, 10:53:30 »

Kód: Text [Vybrat]
  1. FLastDateFocInYear: TDate;
  2. FLastDateFocInYear := EndOfTheMonth(oGlobalVar.LastDateFoc);  // Funkcia vracia TDateTime. V premennej mi ukáže TDate
  3. // Parameter pre SQL
  4. Fqry_UI.ParamByName('LASTDATE').AsDate := FLastDateFocInYear; // V parametri mám TDateTime - včítane času
  5.  
Nerozumiem, prečo sa v parametri objaví aj čas.
Vyriešil som si to nepoužitím funkcie EndOfTheMonth
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Morrison

  • Plnoletý
  • ***
  • Příspěvků: 205
  • Karma: 7
    • Verze Delphi: D5, XE2
Re:TDate má "skrytý" čas
« Odpověď #1 kdy: 04-02-2018, 12:54:42 »
Protože TDate = TTime = TDateTime = double
nil

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2059
  • Karma: 104
    • Verze Delphi: D2007, XE3, DX10
Re:TDate má "skrytý" čas
« Odpověď #2 kdy: 04-02-2018, 13:10:34 »
Nerozumiem, prečo sa v parametri objaví aj čas.
Vyriešil som si to nepoužitím funkcie EndOfTheMonth
1. Jak psal Morrison, interne neni rozdil mezi TDate, TTime a TDateTime: vsechnoje double, v cele casti pocet dni od 31.12.1899 a v desetinne pomerna cas dne
2. Funkce EndOfTheMonth vypada takhle (taky ses tam mohl mrknout)
Kód: Delphi [Vybrat]
  1. Result := EndOfTheDay(EncodeDate(LYear, LMonth, DaysInAMonth(LYear, LMonth)));
a to EndOfTheDay takhle:
Kód: Delphi [Vybrat]
  1.   Result := RecodeTime(AValue, 23, 59, 59, 999);
3. Takze pokud chces jen datum, musis odbourat desetinnou cast
Kód: Delphi [Vybrat]
  1.   FLastDateFocInYear := trunc(EndOfTheMonth(oGlobalVar.LastDateFoc));



Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3228
  • Karma: 30
    • Verze Delphi: XE7 professional
Re:TDate má "skrytý" čas
« Odpověď #3 kdy: 04-02-2018, 13:15:19 »
Ja som sa na funkciu EndOfTheDay pozrel. Funkciu Trunc som aj niekde použil a potom vyhodil, lebo sa mi nepáčila :) Nebolo to v spojitosti s EndOfTheDay. Ale nejaká obkľuka.
Ďakujem.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 781
  • Karma: 35
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:TDate má "skrytý" čas
« Odpověď #4 kdy: 04-02-2018, 20:57:25 »
Ja som sa na funkciu EndOfTheDay pozrel. Funkciu Trunc som aj niekde použil a potom vyhodil, lebo sa mi nepáčila :) Nebolo to v spojitosti s EndOfTheDay. Ale nejaká obkľuka.
Ďakujem.

Tvuj sloupec LASTDATE totiz neni typu DATE. Kdyby byl typu DATE, FireDAC by se snazil DBMS predat jen datum. Funguje to jednoduse. Parametru definujes datovy typ bud mapovanim, manualne, nebo akcesorem As<T> (cimz se jeho datovy typ urci) a ulozis do nej hodnotu. FireDAC pak pri spousteni SQL prikazu zjisti datovy typ sloupce do ktereho se hodnota predava a provede vhodnou konverzi hodnoty podle typu parametru a sloupce (metodou ConvertRawData).

No a pokud mas datovy typ sloupce napr. TIMESTAMP, pak pomoci akcesoru AsDate sice nadefinujes parametr typu dtDate, nicmene protoze je sloupec typu dtDateTimeStamp, FireDAC provede patricnou konverzi a Ty ve vysledku dostanes datum i cas.

Pokud pro ten svuj datumocasovy sloupec chces predat parametrem hodnotu s vynulovanou casovou casti, muzes, jak uz bylo zmineno pouzit Trunc, nebo snad o neco lepe DateOf.
« Poslední změna: 04-02-2018, 21:07:30 od Delfin »
I'm a soldier, so don't panic!

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3228
  • Karma: 30
    • Verze Delphi: XE7 professional
Re:TDate má "skrytý" čas
« Odpověď #5 kdy: 04-02-2018, 21:06:45 »
Lenže LASTDATE nie je môj stĺpec ale parameter a ten porovnávam s nejakým poľom, ktoré je vo FB definované ako Date.
Mal som sa pozrieť aj na RecodeTime. Ja som akosi ticho predpokladal, že čas vo vrátanej hodnote nebude.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 781
  • Karma: 35
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:TDate má "skrytý" čas
« Odpověď #6 kdy: 04-02-2018, 21:47:15 »
Lenže LASTDATE nie je môj stĺpec ale parameter a ten porovnávam s nejakým poľom, ktoré je vo FB definované ako Date.
Mal som sa pozrieť aj na RecodeTime. Ja som akosi ticho predpokladal, že čas vo vrátanej hodnote nebude.

Vsak jsem psal jsem o parametrech. A i v pripade prikazu jako je tento je odpovednosti DBMS s pripravou prikazu klientovi vratit datovy typ parametru (v tomto pripade pro DATE sloupec datovy typ pro parametr SQL_TYPE_DATE):

Kód: MySQL [Vybrat]
  1. SELECT * FROM MyTable WHERE MyDate = :MyDate

A starosti FireDAC provest pripadnou konverzi. Firebird ve Tvem pripade musel udelat chybu.
« Poslední změna: 04-02-2018, 21:48:57 od Delfin »
I'm a soldier, so don't panic!

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3228
  • Karma: 30
    • Verze Delphi: XE7 professional
Re:TDate má "skrytý" čas
« Odpověď #7 kdy: 04-02-2018, 21:53:32 »
Citace
A starosti FireDAC provest pripadnou konverzi. Firebird ve Tvem pripade musel udelat chybu.
Odkiaľ mal FireDAC vedieť (žeby .AsDate), že má odrezať čas? Mňa miatlo to, že keď som kurzorom nabehol na premennú typu TDate, tak mi to čas nezobrazilo. Ale do parametra ho vrazilo.
To bola chyba. Lebo parameter mi vstupuje do podmienky a 31.1.2018 <> 31.1.2018:59:99:999. A už mi vrátilo prázdny dataset.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 781
  • Karma: 35
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:TDate má "skrytý" čas
« Odpověď #8 kdy: 04-02-2018, 22:14:22 »
Citace
A starosti FireDAC provest pripadnou konverzi. Firebird ve Tvem pripade musel udelat chybu.
Odkiaľ mal FireDAC vedieť (žeby .AsDate), že má odrezať čas? Mňa miatlo to, že keď som kurzorom nabehol na premennú typu TDate, tak mi to čas nezobrazilo. Ale do parametra ho vrazilo.
To bola chyba. Lebo parameter mi vstupuje do podmienky a 31.1.2018 <> 31.1.2018:59:99:999. A už mi vrátilo prázdny dataset.

Jak uz jsem psal. Ty pro FireDAC nadefinujes parametr (napr. pomoci AsDate urcis ze ma byt typu dtDate a ulozis do nej hodnotu). Pri spousteni dojde ke kompilaci prikazu na strane DBMS a na klienta se vrati seznam promennych (ve FireDAC reprezentovany pro Firebird tridou TIBVariable). Pri predavani hodnot do DBMS (v metode TFDPhysIBCommandBase.SetParamValue) pak dojde k pripadne konverzi hodnoty parametru z datoveho typu ktery jsi nadefinoval na datovy typ ktery popisuje promenna. Pokud souhlasi, ke konverzi nedojde.

Takze u Tebe doslo ke konverzi. On zkratka FireDAC nemuze predat Firebirdu napr. hodnotu DATE pokud pro spousteny prikaz Firebird pozaduje trebas promennou typu TIMESTAMP, proto ta konverze. Cili, i kdyz "orezes" casovou cast, do DBMS se stejne preda. Jen bude vynulovana a to kvuli konverzi pro promennou pozadovanou Firebirdem. Kdyby Firebird pozadoval promennou typu DATE (resp. SQL_TYPE_DATE), predal by se jen datum, protoze by ke konverzi nedoslo.
« Poslední změna: 04-02-2018, 22:25:00 od Delfin »
I'm a soldier, so don't panic!

Offline našinec

  • Hrdina
  • ****
  • Příspěvků: 362
  • Karma: 5
Re:TDate má "skrytý" čas
« Odpověď #9 kdy: 04-02-2018, 22:23:24 »
Obecně, co se týče Date, tak vrací datum a čas. Úprava výstupu se provádí formátováním.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 781
  • Karma: 35
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:TDate má "skrytý" čas
« Odpověď #10 kdy: 04-02-2018, 22:41:20 »
Obecně, co se týče Date, tak vrací datum a čas. Úprava výstupu se provádí formátováním.

Ne. Ne. Napr. Firebird vraci hodnoty datovym typem ISC_DATE jenz obsahuje jen datum. Jina vec je prevzeti hodnoty z TField (resp. TDateField). Ty nemaji AsDate akcesor.
« Poslední změna: 04-02-2018, 22:45:23 od Delfin »
I'm a soldier, so don't panic!

Online Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3228
  • Karma: 30
    • Verze Delphi: XE7 professional
Re:TDate má "skrytý" čas
« Odpověď #11 kdy: 05-02-2018, 09:27:26 »
Hm, niečo mi tam nesedí. Ak by som posielal hodnotu do poľa, tak nemám problém a všetko čo píšeš mi sedí.

Ale keď posielam hodnotu do parametra, tak ako vie DBMS čo je to za typ? Predsa typ parametra nie je nikde (mnou) definovaný. Ja ten parameter používam na viacerých miestach. A teoreticky oponenti (protistrana, pole) nemusia byť vždy rovnakého typu.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 781
  • Karma: 35
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:TDate má "skrytý" čas
« Odpověď #12 kdy: 05-02-2018, 09:52:10 »
Hm, niečo mi tam nesedí. Ak by som posielal hodnotu do poľa, tak nemám problém a všetko čo píšeš mi sedí.

Ale keď posielam hodnotu do parametra, tak ako vie DBMS čo je to za typ? Predsa typ parametra nie je nikde (mnou) definovaný. Ja ten parameter používam na viacerých miestach. A teoreticky oponenti (protistrana, pole) nemusia byť vždy rovnakého typu.

DBMS prikaz kompiluje pro spusteni (tzv. priprava dotazu) a pro takto pripraveny prikaz se da ziskat popis vstupnich promennych (napr. Interbase a Firebird k tomu pouziva API funkci isc_dsql_describe_bind).

A typ parametru je Tebou definovany - tim nastavenim hodnoty akcesorem AsDate nastavis parametru zaroven i datovy typ ftDate (omlouvam se za preklep v predchozich prispevcich, typ parametru nema prefix dt ale ft).

Jinymi slovy, ty reknes FireDAC, hele "chtel bych parametr typu ftDate s touto hodnotou". Pak prikaz spustis a pri jeho priprave si FireDAC ziska z DBMS informace o potrebnych vstupnich promennych. No a pri predavani hodnot se FireDAC podiva na datovy typ parametru ktery jsi proklamoval, na datovy typ promenne a pripadne provede konverzi.
I'm a soldier, so don't panic!

Offline našinec

  • Hrdina
  • ****
  • Příspěvků: 362
  • Karma: 5
Re:TDate má "skrytý" čas
« Odpověď #13 kdy: 05-02-2018, 14:48:02 »
Pod slovem obecně jsem měl na mysli bez ohledu na jazyk ve winOS. Uvedu příklad z PS a asi bude jasné, co ten dotaz ve mně evokoval:
 
PS>
$date = Get-Date
$date
$date.Date
$date = get-date -format d
$date

pondělí 5. února 2018 14:38:11
pondělí 5. února 2018 0:00:00
05.02.2018

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 781
  • Karma: 35
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:TDate má "skrytý" čas
« Odpověď #14 kdy: 05-02-2018, 16:45:25 »
Abych to me dlouhe povidani zkratil. Je na uzivateli, aby zvolil vhodny datovy typ parametru. Pokud se mu to nepodari presne, nebo DBMS nezvoli spravny (uzivatelem ocekavany) typ promenne, dojde implicitne diky FireDAC ke konverzi hodnoty.

Jina moznost je prikaz pripravit pomoci Prepare coz pripravi prikaz ke spusteni a naplni kolekci Params podle DBMS, nicmene v takovem pripade je treba dat si pozor na As<T> akcesory kterymi by se mohly upravit datove typy parametru, coz by v takovem pripade mohlo zpusobit chybu spusteni dotazu (chyba typu "Param [...] type changed from [...] to [...]. Query must be reprepared.").
« Poslední změna: 05-02-2018, 16:47:03 od Delfin »
I'm a soldier, so don't panic!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Kolik je šest plus čtyři (slovem):