Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Problema con operaciones con fechas (https://www.clubdelphi.com/foros/showthread.php?t=93878)

Angel.Matilla 17-04-2019 19:25:24

Problema con operaciones con fechas
 
No sé si esto tendría que ir aquí o en el foro de FB porque es sobre una base de datos de este motor. A ver:

Tengo una aplicación en la que se pide al entrar usuario y clave de acceso, que están guardados en sendas tablas, una para los usuarios y otra para las claves porque le tengo puesta fecha de caducidad a las mismas. Una vez que se introduce y valida la clave ejecuto este código para comprobar su validez:
Código:

fMenu->Auxiliar->Close();
fMenu->Auxiliar->SQL->Text = "SELECT B.Caduca, B.Caduca - CURRENT_DATE FROM Usuarios A, Claves B WHERE A.Nombre = :Nombre AND A.Nombre = B.Nombre AND B.Clave = :Clave";
fMenu->Auxiliar->ParamByName("Nombre")->AsString = NombreUser;
fMenu->Auxiliar->ParamByName("Clave")->AsString  = ClaveUser;
fMenu->Auxiliar->Open();

if (fMenu->Auxiliar->Fields->FieldByNumber(2)->AsInteger < 11)
{
    cAux = "Su clave caduca el " + fMenu->Auxiliar->FieldByName("Caduca")->AsDateTime.FormatString("ddddd");

    if (fMenu->Auxiliar->Fields->FieldByNumber(2)->AsInteger < 1)
    {
          Mensaje(3, cAux + ".\nDebe cambiar la clave de acceso al sistema.", "Continuar");

          Application->CreateForm(__classid(TfCamCla), &fCamCla);
          fCamCla->Tag = 1;
          fCamCla->Nombre->Text = NombreUser;
          fCamCla->ShowModal();

          if (fCamCla->Tag < 0)
          {
              TipoInstalacion = fCamCla->Tag;
              delete fCamCla;
              Mensaje(1, "No se ha modificado la clave. Sistema desconectado.", "Terminar");
              Application->Terminate();
              return TipoInstalacion;
          }
          delete fCamCla;
    }
    else
          Mensaje(4, cAux, "Continuar");
}

Y la tabla en que se guardan las claves es esta:
Código:

CREATE TABLE Claves (Nombre VARCHAR(15), Clave VARCHAR(12), Fecha DATE, Caduca DATE, CONSTRAINT PK_Claves PRIMARY KEY (Nombre, Clave))
No voy a entrar si el código podía ser más sencillo o no; no es el problema. EL problema es que en todas las máquinas que está corriendo la aplicación, incluida la mía, ese query SELECT B.Caduca, B.Caduca - CURRENT_DATE... funciona a la perfección, menos en una que usa Windows 10 y que TODOS los días le obliga al usuario a cambiar la clave. Había pensado que estuviera mal la fecha del sistema pero acabo de comprobar que es correcta.
Por poner un ejemplo, con el usuario que está dando error este es el último registro que hay en esa tabla:
Cita:

Nombre: JOSEMIGUEL
Clave: DINGO47
Fecha: 09/04/2019
Caduca: 09/06/2019
Como veis la fecha tope está en el rango en que no debería saltar el error, pero no hay forma de que ejecute bien ese trozo de código y empiezo a pensar que tiene que ver con el sistema operativo.

Casimiro Notevi 17-04-2019 19:57:52

Mira en la configuración de windows, "regional" para ver qué formato de fecha tiene, vaya a ser diferente al resto de equipos.

Javierus 17-04-2019 20:03:48

¿Has comprobado los valores específicos que devuelve la query en ese ordenador y caso concreto? ¿Qué devuelve?

lbuelvas 20-04-2019 19:31:40

Será que los registros con el nombre de usuaio y/o contraseña no están en la base de datos ?

La parte del
Código Delphi [-]
if (fMenu->Auxiliar->Fields->FieldByNumber(2)->AsInteger < 1)
puede fallar si el query no retorna registros.

Prueba que otro usuario trate de ingresar en esa máquina.

Angel.Matilla 23-04-2019 09:44:41

Gracias por las respuestas.
Cita:

Empezado por lbuelvas (Mensaje 531584)
Será que los registros con el nombre de usuaio y/o contraseña no están en la base de datos ?

La parte del
Código Delphi [-]
if (fMenu->Auxiliar->Fields->FieldByNumber(2)->AsInteger < 1)
puede fallar si el query no retorna registros.

Prueba que otro usuario trate de ingresar en esa máquina.

Si el usuario y/o clave no están en la base de datos devuelve un mensaje de error de Firebird.
Cita:

Your user name and password are not defined. Ask your database administrator to set up a Firebird login
Cita:

Empezado por Casimiro Notevi (Mensaje 531548)
Mira en la configuración de windows, "regional" para ver qué formato de fecha tiene, vaya a ser diferente al resto de equipos.

Eso no lo he comprobado. Lo miraré en cuanto pueda esta mañana.
Cita:

Empezado por Javierus (Mensaje 531549)
¿Has comprobado los valores específicos que devuelve la query en ese ordenador y caso concreto? ¿Qué devuelve?

Hice la prueba el otro día y devolvía valores coherentes.

Javierus 23-04-2019 10:02:21

Cita:

Empezado por Angel.Matilla (Mensaje 531617)
Hice la prueba el otro día y devolvía valores coherentes.

Cuando la cosa está así, no ves qué falla, y tienes que correrlo en casa del cliente, yo recurro al OutputDebugString: le metes entre cada línea de código y la siguiente un ODS diciendo que estás ahí y los valores que importen. Luego en el cliente, corres p.ej. el DebugView de Microsoft (quizás como administrador), y ejecutas tu programa, verificando los valores que aparecen.

Con frecuencia suele ser alguna tontería, que al ver esa "traza" queda clara.

Angel.Matilla 23-04-2019 19:39:57

Cita:

Empezado por Javierus (Mensaje 531618)
Cuando la cosa está así, no ves qué falla, y tienes que correrlo en casa del cliente, yo recurro al OutputDebugString: le metes entre cada línea de código y la siguiente un ODS diciendo que estás ahí y los valores que importen. Luego en el cliente, corres p.ej. el DebugView de Microsoft (quizás como administrador), y ejecutas tu programa, verificando los valores que aparecen.

Con frecuencia suele ser alguna tontería, que al ver esa "traza" queda clara.

Gracias por la sugerencia. No conocía esa herramienta; la investigaré. Lo que más me mosquea es que sólo ocurre en un ordenador que tiene W10. en los demás, con W7, funciona sin problema. Acabo de estar viendo en remoto la pantalla del cliente (está a 140 km. de donde estoy yo) y le puse que sacara un mensaje con tres datos: Cuando caduca la clave, la fecha del sistema y los días que faltan (B.Caduca - CURRENT_DATE).

Si lo corro en mi máquina me da bien los datos (dos fechas y la diferencia entre ambas) pero en esa "maldita" máquina la fecha de caducidad me da una hora (00:00:00) y en la base de datos esa fecha está bien grabada. He estado viendo como me indicó Casimiro la configuración regional y está bien. Cada vez lo entiendo menos porque es el único sitio de los que usan fechas que ocurre esto. No sé si "forzando" a que devuelva una fecha con un CAST se puede solucionar.

Casimiro Notevi 23-04-2019 20:02:31

A ver si tiene un firebird antiguo o uno nuevo con dialect 1 en lugar de 3

Angel.Matilla 23-04-2019 20:22:17

Cita:

Empezado por Casimiro Notevi (Mensaje 531633)
A ver si tiene un firebird antiguo o uno nuevo con dialect 1 en lugar de 3

No seguro. El motor es la versión 2.7; la instalé yo con TeamViewer. Y el dialecto en el arranque fuerzo que sea el 3.

Casimiro Notevi 23-04-2019 20:45:01

Pues entonces tan sólo te queda asegurarte de los valores que retorna cada apartado.

Angel.Matilla 25-04-2019 10:54:13

He dado un paso más. A la vista de los valores que me devolvía el query lo modifiqué así:
Código PHP:

SELECT CAST(B.Caduca AS DATECaducaCAST(B.Caduca AS DATE) - CURRENT_DATE 
FROM Usuarios A
Claves B 
WHERE A
.Nombre = :Nombre AND A.Nombre B.Nombre AND B.Clave = :Clave 

y puse que me mostrara esto en pantalla:
Código PHP:

ShowMessage("Caduca: " fMenu->Auxiliar->FieldByName("Caduca")->Value 
            
"\nFaltan: " fMenu->Auxiliar->Fields->FieldByNumber(2)->Value); 

He comprobado que en mi máquina y una de las del usuario, que tenemos W7, el mensaje sí me devuelve un valor (por ejemplo: Caduca: 09/06/2019 Faltan: 45). Sin embargo en el otro equipo del usuario, que tiene W10, al ejecutar ese ShowMessage da un error:
Código PHP:

Could no convert variant of type (Nullinto type (String) 

Cada vez estoy más convencido que el problema está asociado al sistema operativo. Y no se me ocurre como solventarlo. :mad:

Casimiro Notevi 25-04-2019 11:03:10

A ver si no devuelven ningún dato o no hay registros con esos valores y devuelve null.

Angel.Matilla 27-04-2019 10:29:08

Registros sí hay; la base de datos ahora mismo es igual la que tengo yo que la del usuario.

Casimiro Notevi 27-04-2019 11:06:40

Mira "por separado" qué devuelve cada apartado de la consulta y lo comparas con tu equipo y con el del cliente, algo así:
Código SQL [-]
SELECT CAST(B.Caduca AS DATE) Caduca
Código SQL [-]
select current_date from rdb$dabatase
Código SQL [-]
select CAST(B.Caduca AS DATE) - CURRENT_DATE
etc...

Angel.Matilla 27-04-2019 11:16:36

Gracias por la sugerencia. El lunes haré la prueba.

Angel.Matilla 29-05-2019 09:06:36

Bueno después de unos cuantos días en que tuve abandonado este tema lo retomé ayer. Lo primero que he hecho es comprobar la configuración del PC donde aparece el problema. Es esta:

Siguiendo vuestras sugerencias he modificado algo el código. Ahora está así:
Código:

fMenu->Auxiliar->Close();
fMenu->Auxiliar->SQL->Text = "SELECT CURRENT_DATE FROM RDB$DATABASE";
fMenu->Auxiliar->Open();
TDateTime dFecha = fMenu->Auxiliar->FieldByName("CURRENT_DATE")->AsDateTime;

fMenu->Auxiliar->Close();
fMenu->Auxiliar->SQL->Text = "SELECT CAST(B.Caduca AS DATE) Caduca FROM Usuarios A, Claves B WHERE A.Nombre = :Nombre AND A.Nombre = B.Nombre AND B.Clave = :Clave";
fMenu->Auxiliar->ParamByName("Nombre")->AsString = NombreUser;
fMenu->Auxiliar->ParamByName("Clave")->AsString  = ClaveUser;
fMenu->Auxiliar->Open();
int nDias = fMenu->Auxiliar->FieldByName("Caduca")->AsDateTime - dFecha;

if (nDias < 11)
{
    cAux = "Su clave caduca el " + fMenu->Auxiliar->FieldByName("Caduca")->AsDateTime.FormatString("ddddd");

    if (nDias < 1)
    {
          Mensaje(3, cAux + ".\nDebe cambiar la clave de acceso al sistema.", "Continuar");

          Application->CreateForm(__classid(TfCamCla), &fCamCla);
          fCamCla->Tag = 1;
          fCamCla->Nombre->Text = NombreUser;
          fCamCla->ShowModal();

          if (fCamCla->Tag < 0)
          {
              TipoInstalacion = fCamCla->Tag;
              delete fCamCla;
              Mensaje(1, "No se ha modificado la clave. Sistema desconectado.", "Terminar");
              Application->Terminate();
              return TipoInstalacion;
          }
          delete fCamCla;
    }
    else
          Mensaje(4, cAux, "Continuar");
}

Sin embargo a pesar de todo me sigue mostrando la fecha como una hora; es decir: en la frase cAux = "Su clave caduca el..., en vez de poner por ejemplo Su clave caduca el 30/06/2019 me pone Su clave caduca el 00:00:00. Y reitero que es el único equipo en que lo hace y además es el único con Windows 10, por eso intuyo que es un problema del sistema operativo.

Casimiro Notevi 29-05-2019 09:27:29

Pero esto estará mal:
AsDateTime.FormatString("ddddd");
Será algo así como "dd-mm-yyyy"

Angel.Matilla 29-05-2019 17:44:32

Cita:

Empezado por Casimiro Notevi (Mensaje 532225)
Pero esto estará mal:
AsDateTime.FormatString("ddddd");
Será algo así como "dd-mm-yyyy"

Según la ayuda de Builder:
Cita:

ddddd Displays the date using the format given by the ShortDateFormat global variable.
No obstante no me cuesta nada poner la forma tradicional. Cierto es que como en ningún sitio me ha dado problemas...

Angel.Matilla 30-05-2019 10:00:36

Estaba dándole vueltas al problema y lo de usar el formato dd/mm/yyyy en vez de ddddd afecta únicamente a la presentación y no a los cálculos internos que lleve a cabo la máquina, aunque he de decir que todavía no he podido probar el cambio.


La franja horaria es GMT +2. Ahora son las 12:54:14.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi