PDA

Ver la Versión Completa : Fechas y Datetimepicker en delphi5


zcatzz
11-05-2007, 04:43:03
Hola a todos ... como ya es mi costumbre sigo hablando del formato de idioma en los datetimepicker ... Despues de leerme muchos foros sobre ese tema he entendido la funcion de la variable ShortdateFormat... en este caso no me cambia el formato mis datetimepicker que al inicio eso pensaba... en uno foro lei que nuestro maestro Roman decia... pues tan sencillo como cambiar la propiedad Format y busque y busque y nunca le encontre :rolleyes: pero entonces me cayo el "20" que ha de ser que esa propiedad este en una version de delphi mas reciente... Estoy en lo correcto?

Si es asi.. mi pregunta es .. puedo jalar ese componente con todas esas maravillosas propiedades a delphi 5? o existe algun otro componente que me sirva igual .. es decir poner fechas en formato grafico y que pueda cambiarle el formato a mi conveniencia...

Tengo 2 proyectos en los que les agregue estas instrucciones:
Que segun entiendo es para cambiar el formato del Datetimepicker
Código Delphi [-]
// configura la fecha, pone dd/mm/yyyy el dia de hoy
S := FormatDateTime('dd/MM/yyyy',now);
FechaC.DateTime:= strtodatetime(s);
Formato := 'dd/MM/yyyy';
FechaC.Perform ( DTM_SETFORMAT,0,DWORD(Formato) );
(http://www.clubdelphi.com/foros/#)

Inicializo mi variable
ShortDateFormat:='dd/mm/yyyy';

Y de verdad que esta de insolito... en el 1er proyecto me hace lo que necesito que es poner la fecha actual en formato de dd/MM/yyyy y si abres el calendario si dice la fecha correcta..
En el 2do proyecto me escribe la fecha en ese formato pero cuando abro el calendario en realidad me lo puso al revez.. es decir hoy 10 de mayo me lo pone como 5 de Octubre:confused:

Los estoy calando en la misma computadora que tiene (que pena) windows xp en regional settings English (united states)

Como puede ser eso posible? por eso estoy vuelta loca, ya que en un programa trabaja tal cual quiero y en el otro se poner rebelde :mad:

Acepto cualquier comentario... Muchisimas gracias de antemano... Ya sea sobre si puedo migrar un componente parecido donde pueda cambiar su formato,, o alguna teoria del porque en un programa funciona y en otro no:eek:

BuenaOnda
11-05-2007, 06:03:03
Hola...
Aqui te dejo un componente, espero que te sirva...:D

cHackAll
11-05-2007, 06:20:19
No comprendo del todo, el problema es que en Delphi 5 no hay la funcion Format? si es así pues por que no intentas copiar lo necesario de la unidad SysUtils de una version reciente?

Si no es así explicame un poco mejor.

Suerte.

zcatzz
11-05-2007, 07:29:17
No comprendo del todo, el problema es que en Delphi 5 no hay la funcion Format? si es así pues por que no intentas copiar lo necesario de la unidad SysUtils de una version reciente?

Si no es así explicame un poco mejor.

Suerte.
Asi es ...en Delphi 5 no existe la propiedad Format en el Datetimepicker...

Ahora si que peco de ignorante, pero como se hace lo de copiar de la unidad SysUtils a Delphi 5 :(... Me podrias explicar por favor:p

zcatzz
11-05-2007, 07:29:52
Hola...
Aqui te dejo un componente, espero que te sirva...:D

Muchas Gracias voy a revisarlo ahora mismo

zcatzz
11-05-2007, 07:57:44
Hola...
Aqui te dejo un componente, espero que te sirva...:D

Disculpa me pide 2 dcu:confused:

es el types.dcu en el calendar

y el DateUtils.dcu ... los tienes por ahi.. (disculpa nuevamente)

roman
12-05-2007, 02:08:27
zcatzz, si bien puedes intentar con otras componentes, yo creo que lo mejor sería primero ver porque está fallando el control estándar.

Ya has visto que ShortDateFormat no te va a servir, lo cual está explicado en la ayuda de Delphi:


TDateTimePicker formats date and time values according to the date and time settings in the Regional Settings of the Control panel on the user’s system. Because TDateTimePicker is a wrapper for a Windows control, these formats can’t be changed by changing the formatting variables in the SysUtils unit. However, you can use the Windows API call DateTime_SetFormat to programmatically specify these settings.


Así, pues, vayamos olvidándonos de esa parte del código.

Como ves, la misma ayuda menciona el uso de DateTime_SetFormat, que básicamente es lo que ya tienes con Perform, aunque veo un poco rara la forma en que lo usas, ¿qué tipo de datos tiene tu variable Formato?

Por otra parte, no entiendo por qué asignas la fecha al datetimepicker con una doble conversión:

datetime -> string -> datetime

cuando puedes hacerlo directamente. Los valores Date o DateTime no dependen del formato que se use para mostrarlos.

Así pues, yo primero que nada intentaría- a falta de la propiedad Format que, por lo visto, no viene en Delphi 5- usar el Perform:


var
Fmt: String;

begin
Fmt := 'dd/MM/yyyy';

FechaC.DateTime := Now;
FechaC.Perform(DTM_SETFORMAT, 0, Integer(PChar(Fmt)));
end;


// Saludos

BuenaOnda
12-05-2007, 04:29:47
es una pena.. eso quiere decir que el componente solo esta disponible para una version mas reciente de delphi... bueno.. apenas tenga alguna solucion te la informare... suerte..

cHackAll
12-05-2007, 20:44:07
:o Dime zcatzz, que formato de fecha necesitas y te doy una funcion sencilla al caso.

zcatzz
13-05-2007, 00:56:35
:o Dime zcatzz, que formato de fecha necesitas y te doy una funcion sencilla al caso.

Muchas gracias por tu ayuda:D .. Mira lo que necesito es que no importa el que lenguaje en la configuracion regional del sistema windows xp este,, en los datetimepicker me aparezca en formato dd/mm/yyyy pero que cuando ya lo vaya a utilizar .. (aparte de la visualizacion me refiero).. ya cuando vaya a manejarlo el valor si este en ese formato... porque si me lo muestra en el datetimepicker bien pero ya cuando lo voy a convertir a formato yyyy-mm-dd para insertarlo en la tabla (utilizo informix y delphi 5) esta en mm/dd/yyyy (si estoy en conf. regional de ingles)...

Ahorita estoy haciendo unas pruebas con los consejos de nuestro maestro Roman.. pero todavia no termino .. mas tarde les cuento .. pero se aceptan mas sugerencias ..

Muchisimas gracias y estamos en contacto:D

cHackAll
13-05-2007, 02:52:30
Puesto que prefiero "controlar" mis aplicaciones con funciones propias simplificadas mías, hago lo de siempre... usar APIs: así que te dejo la (como siempre digo) "esencia" de lo que las funciones como el "Format" se valen. Acá están tus tres formatos...

function IntTo2(Value: Word): string;
begin
Str(Value, Result);
if Value < 10 then
Result := '0' + Result;
end;

procedure TForm1.FormCreate(Sender: TObject);
var SystemTime: TSystemTime;
begin
GetLocalTime(SystemTime);
with SystemTime do
Caption := IntTo2(wDay) + '/' + IntTo2(wMonth) + '/' + IntTo2(wYear) + ' - ' +
IntTo2(wYear) + '-' + IntTo2(wMonth) + '-' + IntTo2(wDay) + ' y ' +
IntTo2(wMonth) + '/' + IntTo2(wDay) + '/' + IntTo2(wYear);
end;

y para conversiones al con el TDateFormat usa las funciones:

SystemTimeToDateTime
DateTimeToSystemTime

Disfrútalas!

roman
13-05-2007, 06:48:44
zcatzz, ¿cómo estás insertando los datos en la base? Normalmente, las componentes de acceso deben encargarse de colocar los datos en el formato de fecha adecuado usando las propiedades AsDate o AsDateTime del campo correspondiente o parámetro si usas una consulta SQL. Muchos problemas de fechas vienen por que uno intenta construir la cadena sql intercalando directamente el valor de la fecha como un string, y claro, viene el problema del formato. Pero si utilizas los parámetros adecuadamente, los valores los pasas, no como cadenas, sino como valores Date, que no dependen del formato.

Por ejemplo, suponiendo que usas un Query:


Query.SQL.Text := 'select * from tabla where fecha = :fecha';
Query.SQL.ParamByName('fecha').AsDate := Trunc(DateTimePicker1.Date);
Query.Open;


Esto debería poner correctamente el valor, sin necesidad de ninguna conversión de formatos.

// Saludos

zcatzz
15-05-2007, 06:57:18
Me ha pasado una cosa curiosisima.. como les he comentado tengo 2 proyectos y he resuelto el problema de manera distinta en el 1er proyecto lo he dejado asi:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
Fmt := 'dd/MM/yyyy';

FechaC.DateTime := Now;
FechaC.Perform(DTM_SETFORMAT, 0, Integer(PChar(Fmt)));




como el maestro Roman me ha dicho para simplificar me convertidero anterior..
Esto funciona perfectamente en el 1ero.

En el 2do proyecto tuve que agregarle la comparacion en el que identifique que lenguaje de sistema tiene el sistema antes de insertar la fecha en la tabla:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
if idioma='080A' then // si el formato esta en espanol
fecha:=conversionfechaparatablaespanol(fechan.text)
else if idioma='0409' then // si el formato esta en ingles
fecha:=conversionfechaparatablaingles(fechan.text);
inserta en la tabla el campo fecha





Y Ya de esta manera dependiendo del idioma lo cambio al formato con las
funciones que implemente a: yyyy-mm-dd.

zcatzz
15-05-2007, 07:03:26
zcatzz, ¿cómo estás insertando los datos en la base? Normalmente, las componentes de acceso deben encargarse de colocar los datos en el formato de fecha adecuado usando las propiedades AsDate o AsDateTime del campo correspondiente o parámetro si usas una consulta SQL. Muchos problemas de fechas vienen por que uno intenta construir la cadena sql intercalando directamente el valor de la fecha como un string, y claro, viene el problema del formato. Pero si utilizas los parámetros adecuadamente, los valores los pasas, no como cadenas, sino como valores Date, que no dependen del formato.

Por ejemplo, suponiendo que usas un Query:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
Query.SQL.Text := 'select * from tabla where fecha = :fecha';
Query.SQL.ParamByName('fecha').AsDate := Trunc(DateTimePicker1.Date);
Query.Open;





Esto debería poner correctamente el valor, sin necesidad de ninguna conversión de formatos.

// Saludos

Hola :
Con respecto a su pregunta.. la respuesta es si:( .. lo convierto en string
para manipularlo..

Estuve intentando su sugerencia... pero me marca el siguiente error:

undeclared identifier parambyname

cambie la linea de esta manera:

query.parameters.ParamByName('fecha').AsDate := Trunc(Fecha.Date);

pero me dice:

undeclared identifier asdate

Sera acaso porque uso delphi 5? o me faltara declarar alguna unidad?

Nota: Estos programas hago pruebas en mysql5 pero son para informix
asi me trae la jefa a falta de otra solucion:rolleyes: eso me complica un poquitin mas la existencia

Muchas gracias por toda la ayuda a todos .. Saludos

roman
15-05-2007, 10:08:08
zcatzz,

Vamos a ver si nos aclaramos un poco, porque lo que funciona en un proyecto debe funcionar en el otro.

Tú tienes dos problemas:


Formato para mostrar las fechas
Formato para introducir las fechas en la base


Lo primero ya lo tienes resuelto con el uso de DTM_SETFORMAT que viene a suplir la propiedad Format, faltante en Delphi 5. Y eso es válido para cualquier configuración regional que tengas en el equipo, porque DTM_SETFORMAT lo que hace es precisamente saltarse dicha configuración. Así que debe funcionar bien en ambos proyectos.

El segundo problema es distinto, porque tiene que ver, no con el formato en que se muestran las fechas en la computadora, sino con el formato que la base de datos requiere para introducir fechas.

Desconozco como es en Informix, pero MySQL espera el formato:

yyyy-mm-dd

No me queda claro de qué fechas estás partiendo, pero dado que hablas de un DateTimePicker, imagino que haces algo como:


fecha := DateToStr(DateTimePicker.Date);


El problema es que una función como DateToStr basa su conversión en la configuración regional de la computadora, de manera que según la que tengas, obtendrás cadenas en formato dd/mm/yy (México) o m/d/yyyy (EU).

Dado que tú, en cualquier caso, necesitas el formato yyyy-mm-dd para pasarlo a MySQL, requieres distintas funciones de conversión, según la configuración regional:

dd/mm/yyyy --> yyyy-mm-dd (México)
m/d/yyyy --> yyyy-mm-dd (EU)

De ahí las dos funciones que estás usando. Aquí es donde valdría usar ShortDateFormat, para instruir a DateToStr al formato deseado y evitar así dos funciones de conversión distintas:


ShortDateFormat := 'yyyy-mm-dd';
fecha := DateToStr(DateTimePicker.Date);


Lo anterior convierte la fecha del DateTimePicker a una cadena yyyy-mm-dd sin importar qué configuración se tenga en la PC.

Pero, todo esto es innecesario y propenso a errores. Así como te funciona para MySQL, podría no funcionarte para Informix. Por ello es que lo mejor es hacer uso de parámetros en las consultas SQL y dejar que el driver correspondiente haga las conversiones requeridas.

Hasta ahora creo que no has mencionado qué componentes estás usando, pero, por el uso de Parameters y la falta de la propiedad AsDate, imagino que esta usando ADO.

En ADO hay que especificar explícitamente cuál es el tipo de datos de los parámetros:


ADOQuery.Parameters.ParamByName('fecha').DataType := ftDate;
ADOQuery.Parameters.ParamByName('fecha').Value := DateTimePicker.Date;


Observa entonces que tomamos ya directamente el valor del DateTimePicker, sin recurrir a ninguna conversión. Será el propio driver de MySQL (o de Informix) el que haga la conversión.

Quizá sea algo distinto en Delphi 5, no recuerdo, pero lo importante es que debes especificar el tipo de datos del campo.

Y, en resumen, el punto que yo destacaría es:

No recurrir nunca a proporcionar fechas/horas a una base de datos como cadenas de caracteres. Hacerlo siempre con los valores de tipo Date, Time o DateTime que no dependen para nada de la configuración regional, y dejar que los drivers hagan su trabajo.

// Saludos

zcatzz
15-05-2007, 23:07:37
zcatzz,

Vamos a ver si nos aclaramos un poco, porque lo que funciona en un proyecto debe funcionar en el otro.

Tú tienes dos problemas:

Formato para mostrar las fechas
Formato para introducir las fechas en la base
Lo primero ya lo tienes resuelto con el uso de DTM_SETFORMAT que viene a suplir la propiedad Format, faltante en Delphi 5. Y eso es válido para cualquier configuración regional que tengas en el equipo, porque DTM_SETFORMAT lo que hace es precisamente saltarse dicha configuración. Así que debe funcionar bien en ambos proyectos.

El segundo problema es distinto, porque tiene que ver, no con el formato en que se muestran las fechas en la computadora, sino con el formato que la base de datos requiere para introducir fechas.

Desconozco como es en Informix, pero MySQL espera el formato:

yyyy-mm-dd

No me queda claro de qué fechas estás partiendo, pero dado que hablas de un DateTimePicker, imagino que haces algo como:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
fecha := DateToStr(DateTimePicker.Date);





El problema es que una función como DateToStr basa su conversión en la configuración regional de la computadora, de manera que según la que tengas, obtendrás cadenas en formato dd/mm/yy (México) o m/d/yyyy (EU).

Dado que tú, en cualquier caso, necesitas el formato yyyy-mm-dd para pasarlo a MySQL, requieres distintas funciones de conversión, según la configuración regional:

dd/mm/yyyy --> yyyy-mm-dd (México)
m/d/yyyy --> yyyy-mm-dd (EU)

De ahí las dos funciones que estás usando. Aquí es donde valdría usar ShortDateFormat, para instruir a DateToStr al formato deseado y evitar así dos funciones de conversión distintas:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
ShortDateFormat := 'yyyy-mm-dd';
fecha := DateToStr(DateTimePicker.Date);





Lo anterior convierte la fecha del DateTimePicker a una cadena yyyy-mm-dd sin importar qué configuración se tenga en la PC.

Pero, todo esto es innecesario y propenso a errores. Así como te funciona para MySQL, podría no funcionarte para Informix. Por ello es que lo mejor es hacer uso de parámetros en las consultas SQL y dejar que el driver correspondiente haga las conversiones requeridas.

Hasta ahora creo que no has mencionado qué componentes estás usando, pero, por el uso de Parameters y la falta de la propiedad AsDate, imagino que esta usando ADO.

En ADO hay que especificar explícitamente cuál es el tipo de datos de los parámetros:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
ADOQuery.Parameters.ParamByName('fecha').DataType := ftDate;
ADOQuery.Parameters.ParamByName('fecha').Value := DateTimePicker.Date;





Observa entonces que tomamos ya directamente el valor del DateTimePicker, sin recurrir a ninguna conversión. Será el propio driver de MySQL (o de Informix) el que haga la conversión.

Quizá sea algo distinto en Delphi 5, no recuerdo, pero lo importante es que debes especificar el tipo de datos del campo.

Y, en resumen, el punto que yo destacaría es:

No recurrir nunca a proporcionar fechas/horas a una base de datos como cadenas de caracteres. Hacerlo siempre con los valores de tipo Date, Time o DateTime que no dependen para nada de la configuración regional, y dejar que los drivers hagan su trabajo.

// Saludos

Primeramente una disculpa porque se me olvido explicar en todo momento que efectivamete estoy utilizando Ado.

De verdad que con esta gran explicacion me has aclarado muchas cosas.. como uno malmente hace muchas veces incorrecta la programacion haciendo conversiones innecesarias. Definitivamente voy a checar esto ultimo que me has explicado en el programa "rebelde" , hare pruebas con informix y con mysql y expondré los resultados.. :p

zcatzz
15-05-2007, 23:16:50
Muchisimas gracias de verdad !! estoy super contenta , gracias al ultimo comentario del maestro Roman se ha logrado el objetivo... definitivamente reitero lo de mi ultimo comentario.. Mal programar ocasiona muchos problemas.. nunca mas vuelvo a convertir a string los formatos date.

1era prueba : Ha funcionado sin ningun problema, sin importar en que configuracion regional este la insercion correcta a la tabla en mysql de un datetimepicker..

En cuanto lo pueda probar en informix les digo los resultados..:D