karhatsu / hirviurheilu

Hirviurheilu - tulospalvelu Metsästäjäliiton urheilulajeille
http://www.hirviurheilu.com
4 stars 1 forks source link

Aikavyöhykeongelmien korjaus #76

Closed karhatsu closed 13 years ago

karhatsu commented 13 years ago

Oleellisin asia on korjata ongelma siitä, että kun tallennetaan esim. start_time 12:00 (Suomen aikaa), niin kantaan menee 12:00 mutta UTC-aikaa. Oikeasti pitäisi mennä 10:00 UTC eli 12:00 Hki.

Sen sijaan rails itse hoitaa sen, että updated_at-sarake menee oikein. Tästä seuraa kuitenkin se, että jos kannassa on 10:00:00 UTC, niin tulossivun otsikkoon tulostuu 10:00:00. Toistaiseksi ongelma kierretty siten, että printtaus tehdään aika.time_to_zone('Helsinki'), jolloin otsikkoon tulee 12:00:00.

karhatsu commented 13 years ago

Time vs. datetime

Tämä ongelma johtuu siitä, että start/arrival_time-kentät (series, competitor, relay, relay_competitor) ovat tietokannassa muotoa time eikä datetime. Syy time-kentän käyttöön on se, että mahdolliset muutokset race.start/end_date-parametreissa ovat helpompia käsitellä. Jos nimittäin kenttien muoto olisi datetime ja kilpailun pvm:t vaihtuisivat, niin sitten pitäisi erikseen muuttaa kaikkien aikakenttien arvoa. Nyt time-tyyppi yhdessä start_day-sarakkeen kanssa antaa mahdollisuuden ajatella aikoja suhteellisina kilpailun pvm:iin verrattuna.

Joka tapauksessa time-tyyppi tarkoittaa sitä, että railsin automaattinen aikavyöhykekonversio ei ole käytössä:

Sinänsähän tuossa ei ole mitään ongelmaa niin kauan kuin ei tehdä mitään aikavertailuja. Mutta heti jos ryhdytään vertaamaan Time.now- tai Time.zone.now-aikaa tuohon 12:00 UTC:hen, niin tulee virhe.

Virheen sijainti

Näin ollen itse virhe paljastuikin series.running?- ja relay.active?-metodeista ja niiden yksikkötesteistä. Nimittäin tämä testi meni läpi:

it "should be false when start time in future" do
  Factory.build(:series, :start_time => Time.now + 10).should_not be_running
end

Mutta tämäpäs ei enää mennytkään:

it "should be false when start time in future" do
  Factory.build(:series, :start_time => (Time.now + 10).strftime('%H:%M:%S')).should_not be_running
end

Tuo jälkimmäinen on se tapa, jolla tietoa kantaan syötetään. Ja jos kello on nyt 18:30:00, niin kantaan menee silloin 1.1.2000 18:30:10. Sehän ei ole tulevaisuudessa, vaikka testin kuvaus niin väittääkin. Sen sijaan ensimmäisessä testissä kantaan menee 2.4.2011 18:30:10, joka on tulevaisuudessa tuolla hetkellä.

Korjaus

Tämä kaikki tarkoittaa siis sitä, että tietokantaan ei tarvitse tehdä mitään muutoksia.

Sen sijaan täytyy korjata noita kahta metodia niin, että ne tarkastavat kolme asiaa:

  1. Onko kilpailu tänään käynnissä (today vs. race.start/end_date) mutta ei päättynyt (race.finished)?
  2. Onko sarja/viesti tälle päivälle (start_day vs. race_day)?
  3. Onko lähtöaika jo ohitettu (start_time vs. klo nyt)?

Tämän korjauksen jälkeen pystyy sitten muuttamaan tuloskehää fiksummaksi.

karhatsu commented 13 years ago

Metodit korjattu, tässä series.running?-speksit:

#running?
  should return true when the series is today and started but the race not finished yet
  should return true when the series was yesterday but the race is not finished yet
  should return false when the race will start in the future
  should return false when the race has started but the series is not today
  should return false when the series is today but has not started yet
  should return false when the race is finished

Vastaavat myös viestille paitsi että siinä katsotaan viestin eikä kilpailun päättymistä.

karhatsu commented 13 years ago

Nimesin vielä series.running?-metodin active?:ksi. Lisäksi tein series/relay.start_datetime-metodin, jota hyödynsin uusissa tulos-skenaarioissa.