PDA

Ver la Versión Completa : Formato de fechas para DateTimePicker incompatible con SQLite


martini002
02-09-2012, 20:25:25
Saludos Amigos, donde quiera que se encuentren,

he estado lidiando con un problemita de formato para fechas
entre el DateTimePicker y el formato de una columna tipo Date de la base de datos,
si bien hay bastante informacion al respecto, aun no podido dar con la solucion,
la cuestion es la siguiente, el componente me toma los valores de una fecha
en el siguiente formato: dd/mm/yyyy y en la BD me lo muestra asi: yyyy-mm-dd
hasta ahora he intentado de todo, y no he tenido buenos resultados,
entre otros, intentando cambiar el formato de fecha del componente
cosa que me parece extraña porque me muestra la fecha de una manera incorrecta
y en el SQLite no he podido lograr cambiar el formato del campo Date,
necesito leer desde la BD el menor dia y luego cuando valla a hacer la consulta,
leer el valor del Picker para poder hacer la consulta,
he intentado tambien hacer la conversion desde la consulta,
inclusive usando otra variable auxiliar pero nada, Esto me comio!
si tienen alguna idea o solucion como siempre,
les estare infinitamente agradecido!

ecfisa
02-09-2012, 22:18:33
Hola martini002.

No he usado SQLite pero en esta página Datatypes In SQLite (http://www.sqlite.org/datatype3.html), encontré esto:

1.2 Date and Time Datatype

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions (http://www.sqlite.org/lang_datefunc.html) of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

...

También revisa si te sirve de guía el título "Reformat Date Strings from mm/dd/yyyy to the Standard SQLite Datestring Format of yyyy-mm-dd Using SELECT CASE" dentro de este enlace (http://sqlite.awardspace.info/syntax/sqlitepg09.htm).

Saludos.

martini002
03-09-2012, 00:38:26
Hola Ecfisa,

Bueno no creo que sea muy conveniente usar el Reformat Date Strings.

Ideally the dates in the column would have two digits for the month, two for the day and 4 digits for the year, in which case it would be a simple matter of using the SUBSTR function to extract the elements and rearrange them as shown below.

SUBSTR(date_field,7,4)||'-'||SUBSTR(date_field,1,2)||'-'||SUBSTR(date_field ,4,2)

Unfortunately in the example above, some of the values in the date column have only one digit for the month and or day. Using SELECT CASE and the CAST(substring AS INTEGER) function makes it possible to extract the value of the month and the day.

(SELECT SUBSTR(date_field,-4,4)) ||'-'||(SELECT CASE WHEN CAST(SUBSTR(date_field,1,2) AS INTEGER)>=10 THEN SUBSTR(date_field,1,2) ELSE '0'|| CAST(SUBSTR (date_field,1,2) AS INTEGER) END ) ||'-'|| (SELECT CASE WHEN CAST(SUBSTR(date_field,-7,3) AS INTEGER)>=10 THEN SUBSTR(date_field,-7,2) ELSE '0'|| CAST(SUBSTR(date_field,-6,2) AS INTEGER) END) AS 'date_field'

UPDATE table_name SET date_field = (select substr(date_field,-4,4)) ||'-'|| (SELECT CASE WHEN CAST(SUBSTR(date_field,1,2) AS INTEGER) >= 10 THEN SUBSTR(date_field,1,2) ELSE '0'|| CAST(SUBSTR (date_field,1,2) AS INTEGER) END ) ||'-'|| (SELECT CASE WHEN CAST(SUBSTR(date_field,-7,3) AS INTEGER)>=10 THEN SUBSTR(date_field,-7,2) ELSE '0'|| CAST(SUBSTR(date_field,-6,2) AS INTEGER) END);

NOTE: When doing a mass update in a table it is often a good idea to make a back up of the table before doing your changes.

Con respecto a lo otro voy a revisar sobre como colocar el formato a esto:
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

creo que podria ser lo mas adecuado sino se logra cambiar el formato de la fecha,
Saludos,
Gracias.

martini002
03-09-2012, 21:11:44
No he podido dar con un buen resultado aun,
si alguien mas tiene alguna idea para resolver esta incompatibilidad
entre el Picker y la BD le agradeceria muchisimo

Gracia

roman
03-09-2012, 21:42:58
he estado lidiando con un problemita de formato para fechas
entre el DateTimePicker y el formato de una columna tipo Date de la base de datos,


Estás buscando la solución a un problema que no existe. No hay tal cosa como incompatibilidad de formatos de fecha entre una base de datos y un datetimepicker, simplemente porque el almacenamiento (base de datos) y presentación (datetimepicker) son dos cosas distintas.

La pregunta correcta es ¿cómo insertar/leer valores de tipo DATE en una base de datos? Y fíjate que digo base de datos , así, en general, y no SQLite.

Aquí dos ejemplos, de inserción y de lectura, usando ZEOS:


procedure TForm1.btnAgregarClick(Sender: TObject);
begin
ZQuery1.SQL.Text := 'insert into perosnas (nombre, fecha) values (:nombre, :fecha)';
ZQuery1.ParamByName('nombre').AsString := txtNombre.Text;
ZQuery1.ParamByName('fecha').AsDate := dtpFecha.Date;
ZQuery1.ExecSQL;

txtNombre.Clear;
end;

procedure TForm1.btnBuscarClick(Sender: TObject);
begin
ZQuery1.Close;
ZQuery1.SQL.Text := 'select * from personas where fecha = :fecha';
ZQuery1.ParamByName('fecha').AsDate := dtpFecha.Date;
ZQuery1.Open;

if not ZQuery1.IsEmpty then
txtNombre.Text := ZQuery1['nombre'];
end;


Mientras uses parámetros, el componente se encargará de pner l fecha en el formato adecuado para cada base de datos.

// Saludos

martini002
03-09-2012, 23:23:32
Caramba, no lo puedo creer,
esto lo intente antes, pero entonces no se que haria mal,
porque estaba leyendo desde el picker AsDate pero entonces me daba un error
ahora que lo recuerdo, me decia que no reconocia el AsDate, entonces tenia que usar AsDateTime,
creo que alli es donde estaba el error entonces, oye Roman, Un millon de Gracias enserio, porque estuve 3 dias
con la moral caida y no habia podido hacer mas nada :')

lo acabo de ver, aqui lo tengo,
Ahora tengo el problemita en modo inverso, y asi es como estaba intentando


ZQuery2.Close;
ZQuery2.SQL.Text:= 'Select Min(Fecha) as FechaInicial From FacturaResumen';
ZQuery2.Open;
PFechaInicio.Date:= ZQuery2.FieldByName('FechaInicial').AsDateTime;


aqui puedes apreciar que el tipo es "AsDateTime" pero me dice que la fecha no es correcta.
un saludo, gracias!

roman
04-09-2012, 17:06:56
lo acabo de ver, aqui lo tengo,
Ahora tengo el problemita en modo inverso, y asi es como estaba intentando


ZQuery2.Close;
ZQuery2.SQL.Text:= 'Select Min(Fecha) as FechaInicial From FacturaResumen';
ZQuery2.Open;
PFechaInicio.Date:= ZQuery2.FieldByName('FechaInicial').AsDateTime;


aqui puedes apreciar que el tipo es "AsDateTime" pero me dice que la fecha no es correcta.
un saludo, gracias!

Tienes razón, y no creo que hya mucho qué hacer aquí debido al manejo de datos (innecesariamente pobre, diría yo) que hace SQLite y que ya mencionó ecfisa. Básicamente, SQLite ve cualquier dato como una cadena de caracteres.

Sin embargo, tampoco es difícil leer ese valor:


var
FS: TFormatSettings;

begin
ZQuery1.Open;
FS.ShortDateFormat := 'y-m-d';
FS.DateSeparator := '-';
DateTimePicker1.Date := StrToDate(ZQuery1.FieldByName('fecha').AsString, FS);
end;


// Saludos

martini002
05-09-2012, 07:36:58
Interesante esa solucion Roman,
pero he decidido hacer caso omiso a ese requerimiento,
para no complicar las cosas con esa BD he preferido
mostar los datos desde los ultimos 30 dias,
implementando este metodo:
y muerta la culebra por la cabeza :D
muchas gracias por la ayuda :)


PFechaInicio.Date:= Date - 30;