14

(Mi problema es más o menos lo mismo que described in this question, solo que la respuesta no funciona en mi caso.)Rails3/jQuery UI DatePicker - mes y el día se invierten en guardar


estoy usando el jQuery UI Datepicker en una aplicación Rails con un Postgres db. La implementación predeterminada usa un formato de fecha mm/dd/aa para mostrar la fecha seleccionada, que es exactamente lo que quiero. Sin embargo, después de guardar el registro en la base de datos, el mes y el día se invierten; a continuación, se muestra como yy-dd-mm. Por lo tanto, al seleccionar el 3/11/2012 se intenta guardar como el 3 de noviembre en lugar del 11 de marzo, y una fecha como 3/31/2012 no se guarda en absoluto, porque no existe.

He ido abajo de 3 vías diferentes en lo que va tratar de solucionar este problema:

1) primer intento fue volver a formatear el campo de texto para que la pantalla se veía lo que quería:

<%= f.text_field :foo, :value => (@model.foo.blank? ? '' : @model.foo.strftime('%m/%d/%Y')), class: "datepicker" %> 

Esta muestra 31/03/2012 correctamente al principio, pero aún se invierte al guardar.

2) A continuación probé cambiando la forma predeterminada en que se almacenan las fechas, pensando que eso solucionaría el problema. Como se describe en la respuesta a this question, añadí lo siguiente para config/lugares/en.yml:

# config/locales/en.yml 
en: 
    date: 
    formats: 
     default: "%m/%d/%Y" 

Esto no hace ninguna diferencia en absoluto. Siguiente me encontré this question y trató de crear config/inicializadores/date_formats.rb con estas líneas:

Date::DATE_FORMATS[:default]="%m/%d/%Y" 
Time::DATE_FORMATS[:default]="%m/%d/%Y %H:%M" 

Igual que el anterior, no hay diferencia.

3) Después de jugar con muchas combinaciones, lo único que encontré que DID trabajo era especificar el formato aaaa-mm-dd en mi llamada al plugin datepicker - es lo contrario de lo que quería, pero al menos las fechas se pueden guardar con éxito. Así que la llamada planificador de evento es el siguiente:

$(".datepicker").datepicker({ dateFormat: 'yy-mm-dd' }); 

Selección 31o marzo, desde el calendario rellena el campo con 2012-03-31, y todavía se muestra como 2012-03-31 después de guardar.

Pero, ¿cómo demonios puedo hacer que el marcador de fecha funcione con un formato mm/dd/aa? No me puedo imaginar que sea algo difícil de hacer, pero ¿qué me estoy perdiendo? ¿Tengo que hacer algo con la forma en que se almacenan las fechas en Postgres? (Se especifican como date, not datetime.)

+0

Para detener golpear la cabeza contra la pared sobre esto, Acabo de cambiar mis campos a 'texto' en lugar de 'fecha'. No es ideal, pero resuelve el problema de forma bastante simple. – ellawren

+0

algunas veces el cambio es una buena solución sea ideal o no. pero aún por curiosidad puede querer saber el problema, puede ser más tarde. –

+0

Rails 3.2.3, Postgresql y Ruby 1.9.3. Tenía el formato datepicker configurado en mm-dd-yy y estaba funcionando por un tiempo, pero estoy pasando por una refactorización y puedo guardar algunas fechas sin problemas, pero una fecha en particular ya no se guarda. Así que voy a volver a formatear a yy-mm-dd y veré qué sucede. – thomasvermaak

Respuesta

3

Bueno, depende de cómo se almacenan los datos en su base de datos. Si usa consultas RAW sql, puede usar to_date('31 Mar 2012', 'DD Mon YYYY') en su consulta de inserción.

Postgres' to_datereference

Ahora, en su lado del cliente, en el selector de fechas jQuery puede utilizar

$.datepicker.formatDate('dd-M-yy', Yourdate); 

Solía ​​DD MES AAAA porque parece más clara.Puede usar el formato mm/dd/yy u otros formatos según las necesidades. En esos casos, el uso requerido formato en to_date función de postgre

nota Por favor, que no he probado el código anterior. Deja comentarios si hay algún problema o enfrentas algún problema.

Editar:

Puede utilizar Date.parse('2011-06-18') en sus rieles ver, antes de insertar datos en la base de datos y establecer formatDate-'yy-mm-dd' en el selector de fechas.

+0

Puede que no entienda lo que dices , pero traté de escribir un método before_save para reorganizar la fecha antes de insertarla en la base de datos. Esto sonó como si funcionara, pero por alguna razón, todavía tengo errores al intentar guardar cualquier fecha con un número de día mayor a 12. Sé que esto tiene que ser porque está tratando de cambiar el día y el mes, pero no puedo averiguar dónde está sucediendo eso. – ellawren

+0

vea en los registros la consulta generada por los rieles (y el valor de la columna de fecha). para saber, de qué lado el problema realmente es –

0

Si desea cambiar el formato de fecha por defecto a nivel mundial para el clúster de base de datos también se puede establecer el DateStyleGUC en su postgresql.conf y volver a cargar:

datestyle = 'iso, mdy' 

(¿Cuál debe ser el valor por defecto de todos modos.)

Tenga en cuenta que esto no influye en cómo se muestran las fechas en su aplicación. Exactamente cómo PostgreSQL interpreta la entrada ambigua y algunas opciones de salida de Postgres.


Si marca la configuración datestyle en psql en un (obviamente) conexión diferente, que no hace nada prueba. Su aplicación puede estar configurando un datestyle diferente en relación con la configuración local. Debería verificar la configuración dentro de su conexión real (no desde psql).

Si la configuración es datestyle 'iso, mdy', entonces debería funcionar como usted quiere: literales de fecha se interpretan meses antes del día. Considere esta demostración (usando PostgreSQL 9.1):

 
db=# set datestyle = 'ISO, MDY'; 
SET 
db=# select '1.12.2012'::date; 
    date 
------------ 
2012-01-12 
(1 row) 

db=# set datestyle = 'ISO, DMY'; 
SET 
db=# select '1.12.2012'::date; 
    date 
------------ 
2012-12-01 
(1 row) 

Énfasis mío.

Para saberlo, qué opciones están fijadas por la aplicación, se puede establecer

log_statement = all 

en su postgresql.conf y volver a cargar. Luego, inicie su aplicación y guarde una fecha. Cada comando se registrará. No se olvide de reiniciar y volver a cargar después (o los archivos de registro pueden crecer enorme):

log_statement = none 

A continuación, compruebe los archivos de registro db lo que su aplicación llega a enviar a la base de datos.


Usted puede también estar interesado en el comando to_date(), que permite a los literales de fecha de entrada en el formato que desee. Pero no deberías necesitar eso.

+0

, hice 'show datestyle;' en psql y obtuve ISO, MDY, por lo que parece que eso ya es correcto. – ellawren

+0

Verificar 'psql' en una conexión diferente apenas prueba nada. Agregué más información a mi respuesta. –

0

Tuve los mismos problemas que el póster original. Como tengo que comparar fechas/horas entre sí, no quería cambiar los campos de DB a cadenas porque eso requeriría código adicional y conversiones más adelante.

Terminé usando before_save y attr_accessor en mi modelo como este:

before_save :format_date 
attr_accessor :unformatted_date 

def format_date 
    self.inquiry_date = Date.strptime(self.unformatted_date, "%m/%d/%Y").to_time(:utc) 
end 

La línea en mi opinión se ve así:

f.text_field :unformatted_date, :value => (@foo.inquiry_date.blank? ? '' : @foo.inquiry_date.strftime('%m/%d/%Y)), :id => 'datepicker' 
Cuestiones relacionadas