delphi date operator-overloading const tdatetime

Declare un TDateTime como un Const en Delphi



operator-overloading (9)

¿Lo único? posible, pero probablemente no sea lo que está buscando:

const {$J+} Expire: TDateTime = 0; {$J-} initialization Expire := EncodeDate(2009, 3, 23);

Por lo que yo sé, no hay forma de hacerlo, pero voy a preguntarlo en caso de que alguien más sepa cómo hacerlo. ¿Cómo puedo declarar una fecha como const en Delphi?

La única solución que he encontrado es utilizar el equivalente numérico, que es un poco difícil de mantener porque no es legible para el ser humano.

const Expire : TDateTime = 39895; // Is actually 3/23/2009

Lo que me gustaría poder hacer es algo como esto:

const Expire : TDateTime = TDateTime (''3/23/2009'');

o

const Expire : TDateTime = StrToDate(''3/23/2009'');

Así que avíseme si esta es una solicitud de función o si me perdí la forma de hacerlo (sí, sé que parece una cosa extraña que desear ...)


Bueno, mi reacción es un poco tarde, pero aquí hay una solución para los nuevos Delphi.

Utiliza sobrecargas de clases implícitas para que los registros de este tipo se puedan usar como si fueran variables TDateTime.

TDateRec = record year,month,day,hour,minute,second,millisecond:word; class operator implicit(aDateRec:TDateRec):TDateTime; class operator implicit(aDateTime:TDateTime):TDateRec; // not needed class operator implicit(aDateRec:TDateRec):String; // not needed class operator implicit(aDateRec:String):TDateRec; // not needed end;

Implementación:

uses DateUtils; class operator TDateRec.Implicit(aDateRec:TDateRec):TDateTime; begin with aDateRec do // Yeah that''s right you wankers. I like "with" :) Result := encodeDateTime(Year,Month,Day,Hour,Minute,Second,Millisecond); end; class operator TDateRec.Implicit(aDateTime:TDateTime):TDateRec; begin with Result do DecodeDateTime(aDateTime,Year,Month,Day,Hour,Minute,Second,Millisecond); end; class operator TDateRec.Implicit(aDateRec:TDateRec):String; begin Result := DateTimeToStr(aDateRec) end; class operator TDateRec.Implicit(aDateRec:String):TDateRec; begin Result := StrToDateTime(aDateRec) end;

Ahora puedes declarar tus fechas así:

const Date1:TDateRec=(Year:2009;month:05;day:11); Date2:TDateRec=(Year:2009;month:05;day:11;hour:05); Date3:TDateRec=(Year:2009;month:05;day:11;hour:05;minute:00);

Para ver si funciona, ejecuta lo siguiente:

ShowMessage(Date1); // it can act like a string ShowMessage(DateToStr(Date1)); // it can act like a date

Si realmente desea reemplazar todas sus variables TdateTime con esto, probablemente necesite sobrecargar también a otros operadores (Agregar, restar, explícito, ...).


Creo que la mejor solución disponible para ti es declarar:

ArmisticeDay: TDateTime = 6888.0 + (11.0/24.0); //Nov 11, 1918 11 AM

y solo acéptalo.

Mi intento Nº1

Expire = EncodeDate(2009, 3, 23);

[Error] Espera expresión constante

Mi intento Nº2

Expire: TDateTime = EncodeDate(2009, 3, 23);

[Error] Espera expresión constante

Por lo tanto, aunque son constantes y deterministas (es decir, no dependen de ninguna información de localización), aún no funcionan.


La respuesta de Rob Kennedy muestra que la solución StrToDate es inherentemente inadmisible ya que no quiere que su código se rompa si está compilado en Europa.

Estoy de acuerdo en que debería haber alguna manera de hacer EncodeDate, pero no es así.

En lo que a mí respecta, el compilador simplemente debe compilar y ejecutar cualquier código que encuentre en una asignación constante y almacenar el resultado en la constante. Dejaría que el programador se asegure de que el código no sea sensible a su entorno.


No hay forma de hacer esto porque la interpretación de una fecha literal en sí misma no es determinista, depende de la convención / localidad que sigas.
''1/4/2009'' no está en enero para ninguna persona francesa, por ejemplo, y tener el compilador traducido como el 4 de enero haría que fuera un compilador tonto ;-)
A menos que el compilador implemente alguna función biyectiva "mágica" (bien documentada) para emparejar un valor de fecha y una representación de visualización ... Y de todos modos, a la mitad del planeta no le gustaría.
La única forma no ambigua que veo ahora es proporcionar el valor, incluso si parece un dolor ... ... mi $ 0.02


No, Delphi no lo admite.

Su primera idea sería una solicitud de literales de fecha y hora distintos de los literales de coma flotante ordinarios. Encontré QC 72000 , que trata de mostrar los valores TDateTime como fechas en el depurador, pero nada sobre su solicitud particular. Aunque no es como si nadie lo hubiera mencionado antes. Es un tema perenne en los grupos de noticias; Simplemente no puedo encontrar nada en QC al respecto.

Su segunda idea requeriría que StrToDate sea ​​evaluable en tiempo de compilación. No veo ninguna entrada en QC al respecto tampoco, pero por lo que vale, C ++ está obteniendo esa característica para las funciones que tienen las cualidades necesarias. StrToDate no cumpliría esos requisitos, sin embargo, porque es sensible a la configuración de fecha de la configuración regional actual.


Tiendo a simular fechas const con una función. Técnicamente, son un poco más constantes que los const de tipo "pseudo-constante" asignables.

function Expire: TDateTime; begin Result := EncodeDate(2009, 3, 23); end;

TENGA EncodeDate CUENTA el uso de EncodeDate lugar de StrToDate . StrToDate se ve afectado por las configuraciones regionales, lo que significa que no hay garantía de que se interprete una cadena como se esperaría.

Por ejemplo, ¿sabía usted que hay un extraño grupo de personas que piensan que tiene sentido "mezclar" las partes de fecha en un orden inconsistente de importancia? Usan la parte media, luego la menos, luego la más significativa (p. Ej., ''3/23/2009'') <sonrisa descarada> . El único momento en que la lógica tiene sentido es cuando cumplas 102 años, entonces puedes reclamar que tu edad es 021.

Para los optimizadores prematuros que existen, si la función se llama con tanta frecuencia que los nano segundos necesarios para codificar una fecha se convierten en un problema: usted tiene un problema mucho mayor que esta ineficiencia menor en el nombre del código legible y mantenible.


Una fecha Delphi es el número de días desde el 30 de diciembre de 1899 . Por lo tanto, probablemente se te ocurra una fórmula matemática elaborada para expresar una fecha como una const. Entonces podrías formatearlo de manera muy extraña, para enfatizar las partes legibles por humanos. Mi mejor intento está abajo, pero está muy incompleto; por un lado, supone que todos los meses tienen 30 días.

Mi ejemplo es principalmente por diversión. En la práctica, esto es bastante ridículo.

const MyDate = (( 2009 //YEAR - 1900) * 365.25) + (( 3 //MONTH - 1) * 30) + 24 //DAY ;


Una solución sería crear una lista de constantes durante años, otra para compensaciones mensuales y luego compilarla sobre la marcha. Tendría que ocuparse de los años bisiestos añadiendo 1 a cada constante resultante. A continuación algunos para que comiences ... :)

Const Leap_Day = 1; // use for clarity for leap year dates beyond feb 29. Year_2009 = 39812; // January 1, 2009 Year_2010 = Year_2009 + 365; // January 1, 2010 Year_2011 = Year_2010 + 365; // January 1, 2011 Year_2012 = Year_2011 + 365; // January 1, 2012 (is leap year) Year_2013 = Year_2012 + Leap_Day + 365; // January 1, 2013 Const Month_Jan = -1; // because adding the day will make the offset 0. Month_Feb = Month_Jan + 31; // 31 days more for the first day of Feb. Month_Mar = Month_Feb + 28; // 28 days more for the first day of Mar. Month_Apr = Month_Mar + 30; // 30 days more for the first day of Apr. Const Expire_Jan1 : tDateTime = Year_2009 + Month_Jan + 1; Expire : tDateTime = Year_2009 + Month_Mar + 23;

Si tiene un año bisiesto, debe agregar 1 a cualquier cosa más allá de febrero de ese año.

Const Expire : tDateTime = Year_2008 + Month_Mar + 23 + Leap_Day;

EDITAR

Se agregaron algunos años más para mayor claridad y se agregó una constante Leap_Day.