2011-05-19 13 views
12

Tengo que almacenar los valores de fecha (TDateTime) en un formato de cadena. ¿Cuál es la mejor manera de hacer esto? Mientras yo contemplaba los siguientes enfoques:¿Cuál es la mejor manera de almacenar valores de fecha en formato de cadena?

FloatToStr: pierde precisión, depende de la configuración regional

`FloatToStr' con ajustes de formato: pierde precisión

DateTimeToStr: depende de la configuración regional

DateTimeToStr con ajustes de formato :?

¿Hay alguna otra alternativa? ¿Cómo se comparan en términos de

  • Tamaño de la memoria
  • independencia de la configuración regional
  • precisión
+0

DateTimeToStr es probable que pierda más precisión que FloatToStr. – Misha

Respuesta

15

uso formato ISO-8601, como se detalla en http://en.wikipedia.org/wiki/ISO_8601

Si necesita ahorrar espacio de almacenamiento, puede utilizar el " diseño compacto, p. ej. '20090621T054523'.

Puede usar, p. FormatDateTime('yyyymmddThhnnss',aDateTime) para producirlo.

Acerca de zona de tiempo y de localización (de Wikipedia):

No hay designadores de zona horaria en ISO 8601. El tiempo sólo se representa como la hora local o en relación con UTC.

Si no se proporciona información de relación UTC con una representación de tiempo, se supone que la hora está en hora local. Si bien puede ser seguro asumir la hora local cuando se comunica en la misma zona horaria, es ambiguo cuando se usa para comunicarse a través de diferentes zonas horarias. Por lo general, es preferible indicar un huso horario (designador de zona) utilizando la notación del estándar.

Por lo tanto, conviene que convierta la hora en UTC, luego agregue 'Z' al final de la marca de tiempo. O use + hh/-hh según su zona horaria local. Los siguientes tiempos se refieren al mismo momento: "18: 30Z", "22: 30 + 04", "1130-0700" y "15: 00-03: 30".

Para una mejor resolución, puede agregar el tiempo en segundos agregando una fracción después de una coma o un carácter de punto: p. Ej.para indicar "14 horas, 30 minutos, 10 segundos y 500 ms", representarlo como "14: 30: 10,5", "143010,5", "14: 30: 10.5" o "143010.5". Puede agregar varios decimales para aumentar la resolución.

Si necesita rutinas de conversión rápida (ISO8601 trabajan con UTF-8 contenido), echar un vistazo a la parte correspondiente de SynCommons.pas. Es mucho más rápido que las funciones predeterminadas SysUtils.

PS:

si su propósito es sólo para almacenar TDateTime como texto en una aplicación Delphi puro, se puede utilizar un no estándar pero rápido:

function DateTimeToText(const aDateTime: TDateTime): string; 
begin 
    result := IntToStr(PInt64(@aDateTime)^); 
end; 

function TextToDateTime(const aText: string): TDateTime; 
begin 
    PInt64(@result)^ := StrToInt64Def(aText,0); 
end; 

Utilizando el Int64 binaria el diseño de la estructura de memoria TDateTime/double será más rápido que cualquier otra conversión relacionada con coma flotante.

+1

+1 para utilizar un estándar internacional y proporcionar información adicional relevante –

+1

+1 gran respuesta. ¡Gracias! – jpfollenius

0

cómo mucha precisión qué necesita? Podría tomar, por ejemplo, la cantidad de milisegundos desde, digamos, 1/1/1970, y simplemente almacenar eso como un número convertido a una cadena. Si el espacio es realmente estrecho, podrías basar64 ese valor. El inconveniente sería que ninguno de los dos sería legible para los humanos.

+0

¿De qué sirve guardar un valor entero como una cadena que no sea perder el espacio y dificultar la lectura de las máquinas (porque deben volver a convertir la cadena en un entero adecuado)? – 0xC0000022L

+1

Porque, el OP dice: "Tengo que almacenar los valores de fecha (TDateTime) en un formato de cadena". Ya conozco tu punto porque es obvio, pero estaba respetando la restricción del OP. –

+1

Solo para agregar, convertir a entero elimina la posibilidad de valores de fecha no válidos como "2/30/2011". –

6

En general yo recomendaría para almacenar datetimes en formato ISO como cadena: aaaa-mm-dd hh: nn: ss.mmmm

EDIT: si desea reducir al mínimo el espacio, se puede dejar de lado todos los separadores y formato que le gusta: yyyymmddhhnnssmmmm

+1

¿De qué formato "ISO" estás hablando? El diseño que propone es ** no ** compatible con ISO-8601. –

+0

Coincide con el formato definido para los literales de marca de tiempo definidos en ISO 9075-2: 2003 –

+0

Del mundo SQL, por lo que es para el lado de la consulta, no para el lado de almacenamiento ... Creo que el formato aaaammddhhnnss no es compatible con ISO 9075. –

3

FormatDateTime ('yyyymmddhhnnss.zzz', ahora)

+3

Sugeriría utilizar aaaammddhhnnss.zzz como la cadena de formato. De esta forma, será independiente de la configuración regional y, además de eso, podrá realizar la clasificación en ellos. – HeartWare

+1

HeartWare tiene razón, no es una buena idea * almacenar * fechas con 'dd/mm' al principio. Quizás sea mejor para mostrar en países que no son inglés, pero menos lógico para el punto de vista de la computadora. –

+0

Editado para reflejar los comentarios anteriores. Por cierto, siempre almaceno las horas como UTC veces. – Misha

Cuestiones relacionadas