2013-02-20 8 views
8

Sembra non v'è alcun modo per assegnare NULL (una " valore assegnato" per TDateTime variabiliDelphi: come determinare e valore TDateTime vuoto

L'unico modo che ho immaginato sta usando. qualcosa di simile:

function isNull(aDate : TDateTime) : boolean; 
const NullDate = 0.0; 
var aNullDate : TDatetime; 
    ms : Int64; 
begin 
    aNullDate := NullDate; 
    ms := MilliSecondsBetween(aDate,aNullDate); 
    result := (ms = Int64(0)); 
end; 

c'è qualcuno fuori che conosce meglio soluzione ciò che non si sovrappone il valore 0 data

Are neg? ative TDateTime valori pericolosi? (Come risorsa abile per scopi precedenti)

+0

Se si intende utilizzare questa funzione, penso che sia, sicuramente 'NullDate' dovrebbe essere una costante globale? –

+0

Ho riscontrato problemi durante il confronto di una variabile TDateTime con valore assegnato zero al valore const 0. Un _semplice_ ** se ** come questo non ha verificato la condizione 'var v_datetime: TDatetime;' 'v_datetime: = 0; ' ' if (v_datetime = 0) then actionToTake' – xsubira

+3

Ciò è dovuto al fuzz a virgola mobile. Usa 'Math.IsZero'. –

risposta

9

Come già scritto da Andreas, il tipo TDateTime è in realtà double e quindi non "nullable". Uso

const 
    c_UnassignedDate = -693594; 

per un valore di data vuota come questo rappresenta una data impossibile 00/00/0000. Ma per esempio DevExpress utilizza

NullDate = -700000; 
InvalidDate = NullDate + 1; 

Quindi ci sembra non essere concordato Vale standard, si dovrebbe scegliere uno che si adatta alle vostre necessità.

+2

Non esiste una data in cui ** giorno ** e ** mese ** sono 0 (zero). Nel database, se la data non è assegnata, si deve usare 'NULL', non una data magica. – ain

+1

Sì, mi dispiace. Riprendendo, stavo guardando solo la parte dell'anno di quella data ... Beh, se il valore di una certa colonna data ora sarà 'NULL' e dovrei memorizzare questo valore rigorosamente in un campo' TDateTime', I probabilmente useresti il ​​tuo valore costante 'c_UnassignedDate'. [+1] – TLama

+0

Come si calcola che -693594 rappresenti la data 0/0/0000? –

9

Per prima cosa è necessario definire cosa intendi per "valore vuoto TDateTime".

Un valore TDateTime A è un doppio con la data codificata nella parte intera e il tempo codificato nella parte frazionaria. Quindi, la cosa più vicina a una "data nulla" che è possibile ottenere è probabilmente 0.

Quindi, prova semplicemente ADate <> 0 per verificare se la data è "nulla".

Ma attenzione: se si dichiara una variabile locale TDateTime, non sarà necessariamente =0 prima di assegnargli un valore. Può essere qualsiasi cosa. Naturalmente, la stessa cosa vale per le variabili di tipo integer, double, boolean, ...

Inoltre, credo che un TDateTime con un valore 0 codifica la data 1899-12-30.

Infine, i valori negativi TDateTime sono perfettamente normali. Ad esempio, -5000 corrisponde a 1886-04-22.

Non capisco il punto del tuo codice. Se si desidera utilizzare 0 come valore 'non assegnato' (che è male se siete interessati a date vicine 1899-12-30), perché non fare semplicemente

function IsUnassigned(ADate: TDateTime): boolean; 
begin 
    result := ADate = 0; 
end; 

o, forse (ma non in modo equivalente!),

function IsUnassigned(ADate: TDateTime): boolean; 
begin 
    result := IsZero(Date); 
end; 

Nella sua risposta, ain ha dato un paio di scelte più ragionevoli per il valore di 'data non assegnato'.

+0

Le date a tempo negativo diventano insignificanti alla fine, quando il calendario si interrompe. –

+0

@David: buon punto. Quindi ci sono molte scelte plausibili per il valore "non assegnato". –

+1

Non sarebbe utile usare NaN come valore esplicito qui? È quindi possibile utilizzare IsNaN per verificare la condizione. –

1

Utilizzare PDateTime invece TDateTime e inviare come valore nullo. Se nessun puntatore ha valore, non restituisce alcun valore.

Per controllare uso valore ptr Assigned:

MyDatePointer := nil; 
if (Assigned(MyDatePointer)) then ... 
1

tDateTime è definito per i valori tra 0 e -1 che significa che una tDateTime di -0.5 è un valore indefinito ed utile per una data nullo in alternativa a NaN. DateTimeToString mostrerà -0.5 come +0.5;