14

(Il mio problema è più o meno lo stesso di described in this question, solo che la risposta non funziona nel mio caso.)Rails3/jQuery UI Datepicker - mese e giorno vengono invertiti su Salva


sto usando il jQuery UI Datepicker in un'applicazione Rails con db Postgres. L'implementazione predefinita utilizza un formato data mm/gg/aa per visualizzare la data selezionata, che è esattamente ciò che voglio. Tuttavia, dopo aver salvato il record nel database, il mese e il giorno vengono invertiti, quindi viene visualizzato come aa-gg-mm. Quindi selezionare 3/11/2012 tenta di salvare come 3 novembre anziché 11 marzo e una data come 31/3/2012 non viene salvata affatto, perché non esiste.

Sono andato giù 3 strade diverse finora cercando di risolvere questo problema:

1) Primo tentativo è stato quello di riformattare il campo di testo in modo che la visualizzazione sembrava come volevo:

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

Questo visualizzato 31/03/2012 inizialmente correttamente, ma ancora invertito durante il salvataggio.

2) Così dopo ho provato a cambiare il modo di default che le date sono memorizzate, pensando che avrebbe aggirare il problema. Come descritto nella risposta alla this question, ho aggiunto quanto segue al config/locali/en.yml:

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

Questo non ha fatto alcuna differenza a tutti. Poi ho trovato this question e cercato di creare config/initializers/date_formats.rb con queste righe:

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

Idem come sopra, nessuna differenza.

3) Dopo aver giocato con molte combinazioni, l'unica cosa che ho trovato che il lavoro DID stava specificando il formato aaaa-mm-g nella mia chiamata al plugin datepicker - è l'opposto di quello che volevo, ma almeno le date possono essere salvate correttamente. Quindi la chiamata datepicker simile a questo:

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

Selezione 31 marzo dal calendario popola il campo con 2012-03-31, e visualizza ancora come 2012-03-31 dopo il salvataggio.

Ma come diavolo posso ottenere il DatePicker di lavorare con un formato gg/mm/aa? Non riesco a immaginare che sia una cosa difficile da fare, ma cosa mi sfugge? Devo fare qualcosa con come sono archiviate le date in Postgres? (Sono specificati come la data, non datetime.)

+0

Per fermare colpire la testa contro il muro su questo, Ho appena passato i miei campi in "testo" anziché in "data". Non è l'ideale, ma risolve il problema piuttosto semplicemente. – ellawren

+0

alcune volte il passaggio è una buona soluzione, ideale o no. ma ancora per curiosità potresti voler conoscere il problema, potrebbe essere più tardi. –

+0

Rails 3.2.3, Postgresql e Ruby 1.9.3. Avevo il formato datapicker impostato su mm-dd-yy e funzionava da un po ', ma sto passando attraverso un refactoring e posso salvare alcune date senza problemi, ma una data in particolare non viene più salvata. Quindi ho intenzione di riformattare di nuovo a yy-mm-dd e vedrò cosa succede. Aggiornamento – thomasvermaak

risposta

3

Beh, dipende da come si memorizzano i dati nel database. Se vi capita di usare RAW query SQL è possibile utilizzare to_date('31 Mar 2012', 'DD Mon YYYY') nella query di inserimento.

Postgres' to_datereference

Ora, sul lato client, in data jquery selettore è possibile utilizzare

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

ho usato DD Mon AAAA perché sembra più chiaro.È possibile utilizzare il formato mm/dd/yy o altri formati in base alle esigenze. In questi casi, l'uso richiesto formato nella funzione di postgre to_date

nota gentile, io havent testati sopra il codice. Lascia i commenti in caso di problemi o di problemi.

Edit:

È possibile utilizzare Date.parse('2011-06-18') nelle rotaie visualizzare, prima di inserire i dati nel database e impostare formatDate-'yy-mm-dd' nel DatePicker.

+0

Forse non capisco cosa stai dicendo , ma ho provato a scrivere un metodo before_save per riorganizzare la data prima che sia inserita nel database. Sembrava funzionasse, ma per qualche ragione, ho ancora degli errori quando provo a salvare qualsiasi data con un numero di giorni superiore a 12. So che questo deve essere perché sta provando a cambiare giorno e mese, ma non posso capire dove sta accadendo. – ellawren

+0

visualizza nei registri la query generata dalle rotaie (e il valore della colonna della data). per sapere, da che parte il problema è in realtà –

0

Se si desidera cambiare il formato della data di default a livello globale per il cluster di database si può anche impostare la DateStyleGUC nel vostro postgresql.conf e ricaricare:

datestyle = 'iso, mdy' 

(Che dovrebbe essere il default comunque.)

Nota che questo non influenza il modo in cui le date sono visualizzate nella tua app. Proprio come PostgreSQL interpreta input ambigui e alcune opzioni di output di Postgres.


Se si seleziona l'impostazione datestyle in psql in un (ovviamente) diverso collegamento, che non prova nulla. L'app potrebbe impostare un diverso datestyle in connessione con le impostazioni locali. Dovresti controllare l'impostazione all'interno della tua connessione effettiva (non da psql).

Se l'impostazione datestyle è 'iso, mdy', allora dovrebbe funzionare come si vuole: data letterali sono interpretati mese prima del giorno. Considerate questo demo (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) 

enfasi è mia.

Per sapere, quali opzioni sono in realtà impostate la vostra applicazione, è possibile impostare

log_statement = all 

nel vostro postgresql.conf e ricaricare. Quindi avvia la tua app e salva una data. Ogni singolo comando verrà registrato. Non dimenticate di resettare e ricaricare dopo (o il vostro file di log possono crescere enorme):

log_statement = none 

Poi controllare i file di log db ciò che la vostra applicazione in realtà inviato al database.


Si può anche essere interessati a comando to_date(), che ti permette di letterali data di ingresso in qualsiasi formato che ti piace. Ma non dovresti averne bisogno.

+0

ho fatto 'show datestyle;' in psql e ho ottenuto ISO, MDY, quindi sembra che sia già corretto. – ellawren

+0

Il controllo di 'psql' in una connessione diversa non prova praticamente nulla. Ho aggiunto qualche altra informazione alla mia risposta. –

0

Mi sono imbattuto negli stessi problemi del poster originale. Dal momento che devo confrontare date/orari l'uno contro l'altro, non volevo modificare i campi DB in stringhe perché ciò richiederebbe codice aggiuntivo e conversioni successive.

ho finito per usare before_save e attr_accessor nel mio modello come questo:

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 linea a mio avviso è simile al seguente:

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