Valmistautuminen ohjelmointihaastatteluihin · Oppitunti

Aikavyöhykkeet ja aikaleimat

UTC-ajan tallentaminen, aikavyöhykkeiden muuntaminen ja haastatteluissa esiin nousevat aikaleimojen sudenkuopat.

Oppitunti 4/413 vaihetta

Aikavyöhykkeet ja aikaleimat on ilmainen Valmistautuminen ohjelmointihaastatteluihin-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Valmistautuminen ohjelmointihaastatteluihin-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Valmistautuminen ohjelmointihaastatteluihin-kurssilla on yhteensä 4 oppituntia.

Miksi aikavyöhykkeet kompastuttavat ehdokkaita

Aikavyöhykkeet ovat kohta, jossa itsevarmatkin ehdokkaat kompastuvat, joten haastattelijat testaavat niiden avulla ymmärryksen syvyyttä. Peruskysymys on aina: "miten tallennatte ja vertaatte aikaleimoja eri alueilla?"

Ammattilaisen vastaus on toimintaperiaate, ei funktio: tallentakaa kaikki UTC-aikaan ja muuntakaa aika paikalliseksi vain esitysvaiheessa. Kun tallennusmalli on kunnossa, useimmista kyselyistä tulee yksinkertaisia.

  • timestamp vs timestamptz
  • Aikavyöhykkeiden väliset muunnokset
  • UTC totuuden lähteenä

timestamp vs timestamptz

PostgreSQL:ssä on kaksi aikaleimatyyppiä, ja niiden sekoittaminen on yleinen virhe haastatteluissa.

  • timestamp (ilman aikavyöhykettä): seinäkelloarvo, johon ei ole liitetty aikavyöhykettä. Se tallentaa täsmälleen annetun arvon.
  • timestamptz (aikavyöhykkeen kanssa): tallennetaan sisäisesti UTC-aikana; syötettäessä arvo muunnetaan istunnon aikavyöhykkeestä ja tulostettaessa takaisin.

Nimestään huolimatta timestamptz ei tallenna aikavyöhykettä, vaan tarkan UTC-aikaisen hetken. Tämä yksityiskohta tekee vaikutuksen haastattelijoihin.

CREATE TABLE events (
  id          bigint,
  occurred_at timestamptz   -- recommended: an absolute instant
);

Tallenna UTC-aikana, muunna rajapinnoilla

Kultainen sääntö: tallenna ajanhetket pysyvästi UTC-aikaan (käytä tyyppiä timestamptz) ja muunna aika paikalliselle aikavyöhykkeelle vain käyttäjälle esittämistä varten. Tämä poistaa kesäaikaan siirtymiseen liittyvän epäselvyyden ja varmistaa, että aikajärjestys on kaikkialla oikein.

Jos kysytään "miksi UTC?", vastatkaa: UTC:ssä ei ole kesäaikaan siirtymisiä, joten sama seinäkelloaika ei toistu eikä jää välistä, toisin kuin paikallisajassa.

-- Display a UTC instant in a user's zone (Postgres)
SELECT occurred_at AT TIME ZONE 'America/New_York' AS local_time
FROM events;

AT TIME ZONE -lausekkeen kaksi merkitystä

AT TIME ZONE on ovela ja aiheuttaa usein yllätyksiä, koska se tekee syötteen tyypin mukaan kahta vastakkaista asiaa:

  • Kun sitä käytetään timestamptz-arvoon, se muuntaa absoluuttisen ajanhetken kyseiseen aikavyöhykkeeseen ja palauttaa tavallisen timestamp-arvon eli kyseisen paikan paikallisen kellonajan.
  • Kun sitä käytetään tavalliseen timestamp-arvoon, se tulkitsee kyseisen paikallisen kellonajan kyseisessä aikavyöhykkeessä olevaksi ja palauttaa timestamptz-arvon.

Ratkaisevaa on tietää, kumpaan suuntaan muunnos tehdään.

-- timestamptz -> local wall clock (returns timestamp)
SELECT TIMESTAMPTZ '2024-03-01 12:00:00+00'
         AT TIME ZONE 'Asia/Tokyo';        -- 2024-03-01 21:00:00

-- plain timestamp interpreted in a zone (returns timestamptz)
SELECT TIMESTAMP '2024-03-01 12:00:00'
         AT TIME ZONE 'Asia/Tokyo';        -- 2024-03-01 03:00:00+00

Nykyisen ajanhetken hakeminen

Tuntekaa "now"-funktiot. NOW() ja CURRENT_TIMESTAMP palauttavat Postgresissa timestamptz-arvon. Ne palauttavat transaktion aloitushetken, eivät yksittäisen SQL-lauseen aloitushetkeä, millä on merkitystä pitkissä transaktioissa.

Jos UTC-aika halutaan nimenomaisesti, tehkää muunnos: NOW() AT TIME ZONE 'UTC'. MySQLissä UTC_TIMESTAMP() palauttaa UTC-ajan suoraan.

SELECT
  NOW()                       AS tx_start_tz,
  NOW() AT TIME ZONE 'UTC'    AS utc_walltime;

Kesäaika on todellinen vihollinen

Haastattelijat pitävät kesäajan siirtymiin liittyvistä reunatapauksista. Kun kellot siirtyvät keväällä eteenpäin, paikallisen kellonajan tuntia ei ole olemassa; kun kellot siirtyvät syksyllä taaksepäin, tunti toistuu. Paikallisajan tallentaminen tekee näistä tilanteista epäselviä tai virheellisiä.

UTC:n tallentaminen ohittaa tämän kokonaan: jokainen ajanhetki on yksikäsitteinen ja monotonisesti etenevä. Alueen, kuten 'America/New_York', nimeäminen kiinteän siirtymän, kuten -05:00, sijaan antaa tietokannalle mahdollisuuden soveltaa kesäaikasääntöjä oikein minä tahansa päivänä.

-- Region name applies DST automatically for the given date
SELECT TIMESTAMPTZ '2024-07-01 12:00:00+00'
         AT TIME ZONE 'America/New_York' AS summer, -- EDT (-04)
       TIMESTAMPTZ '2024-01-01 12:00:00+00'
         AT TIME ZONE 'America/New_York' AS winter; -- EST (-05)

Ryhmittely paikallisen päivän mukaan eri aikavyöhykkeillä

Realistinen ongelma on laskea "päivittäin aktiiviset käyttäjät kunkin käyttäjän paikallisessa ajassa". Jos UTC-aikaleima katkaistaan suoraan, vuorokauden vaihtumiskohdat ovat väärät muilla kuin UTC-aikavyöhykkeillä oleville käyttäjille.

Muunna aika käyttäjän aikavyöhykkeeseen ennen päivän tarkkuuteen katkaisemista. Muunnos siirtää paikallista kellonaikaa niin, että päivän rajat kohdistuvat paikallisesti oikein.

SELECT
  DATE_TRUNC('day', occurred_at AT TIME ZONE u.tz) AS local_day,
  COUNT(DISTINCT e.user_id)                         AS dau
FROM events e
JOIN users u ON u.id = e.user_id
GROUP BY 1
ORDER BY 1;

Aikaleimojen turvallinen vertailu

Kun timestamptz-saraketta suodatetaan, vertailkaa sitä nimenomaiseen ajanhetkeen, mieluiten UTC-literaaliin tai siirtymän sisältävään timestamptz-arvoon. Paljas merkkijono voi tulkintatavasta riippuen käyttää istunnon arvaamatonta aikavyöhykettä.

Näin vertailu pysyy yksiselitteisenä riippumatta siitä, kuka kyselyn suorittaa.

SELECT *
FROM events
WHERE occurred_at >= TIMESTAMPTZ '2024-03-01 00:00:00+00'
  AND occurred_at <  TIMESTAMPTZ '2024-04-01 00:00:00+00';

Epoch- ja Unix-aikaleimat

Monet järjestelmät tallentavat ajan Unix-epochina eli sekunteina vuoden 1970-01-01 UTC-ajasta. Haastattelija voi antaa käsiteltäväksi kokonaislukusarakkeen ja pyytää tulkitsemaan sen.

  • Postgres: TO_TIMESTAMP(epoch_seconds) palauttaa timestamptz-arvon.
  • Takaisin epoch-arvoksi: EXTRACT(EPOCH FROM occurred_at).
  • MySQL: FROM_UNIXTIME() ja UNIX_TIMESTAMP().

Epoch-arvot ovat luonnostaan UTC-aikaa, mikä on yksi syy niiden suosioon tallennuksessa.

SELECT
  TO_TIMESTAMP(1709294400)               AS as_ts,   -- from epoch
  EXTRACT(EPOCH FROM NOW())::bigint        AS as_epoch; -- to epoch

Aikavyöhykkeitä koskevia huomioita eri SQL-murteissa

Tässä on nopea yhteenveto, jonka avulla osaatte toimia sujuvasti eri ympäristöissä:

  • Postgres: timestamptz ja AT TIME ZONE tarjoavat kattavimman tuen.
  • MySQL: TIMESTAMP muunnetaan automaattisesti istunnon time_zone-asetuksen kautta; CONVERT_TZ(t, from, to) tekee muunnoksen nimenomaisesti. DATETIME ei tunne aikavyöhykkeitä.
  • SQL Server: datetimeoffset tallentaa siirtymän; AT TIME ZONE 'name' tekee muunnoksen Windowsin aikavyöhykkeiden nimien avulla.
-- MySQL explicit conversion
SELECT CONVERT_TZ(event_dt, 'UTC', 'Europe/Istanbul') AS local_dt
FROM events;

Syvällisempi esimerkki: keskiyön yli jatkuvat istunnot

Hienovarainen raportointikysymys on laskea istunnot paikallisen kalenteripäivän mukaan, kun istunto voi jatkua keskiyön yli. Ratkaisu noudattaa samaa periaatetta: muunnetaan aika paikalliseksi ja jaetaan se sitten jaksoihin.

Tallentakaa alku ja loppu muodossa timestamptz; johtakaa raportointia varten paikallinen päivä muunnetusta alkuajasta. Jos istunto on jaettava kahdelle päivälle, mukaan pitäisi liittää päiväulottuvuus eli day spine. Tämä on hyvä jatkokysymyksen aihe haastattelussa.

SELECT
  DATE_TRUNC('day', started_at AT TIME ZONE 'Europe/Istanbul') AS local_day,
  COUNT(*) AS sessions
FROM sessions
GROUP BY 1
ORDER BY 1;

Pikatarkistus

Vahvistakaa suositeltu tallennusstrategia ja sen perustelut.

Kertaus: aikavyöhykkeet ja aikaleimat

Tärkeimmät periaatteet ovat:

  • Tallentakaa UTC muodossa timestamptz; muuntakaa aika nimettyyn aikavyöhykkeeseen vain näyttämistä varten.
  • timestamptz tallentaa UTC-ajanhetken, ei aikavyöhykettä, nimestään huolimatta.
  • AT TIME ZONE toimii molempiin suuntiin syötteen tyypin mukaan: se muuntaa timestamptz-arvon paikalliseksi kellonajaksi tai tulkitsee tavallisen timestamp-arvon tietyssä aikavyöhykkeessä olevaksi.
  • Käyttäkää alueiden nimiä, kuten 'America/New_York', jotta kesäaika otetaan automaattisesti huomioon; välttäkää kiinteitä siirtymiä.
  • Muuntaa aika paikalliseksi ennen päivän tarkkuuteen katkaisemista ja verratkaa sarakkeita nimenomaisiin UTC-ajanhetkiin.
Aloita maksutta

Opi Valmistautuminen ohjelmointihaastatteluihin tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
90
Oppitunnit
360

Usein kysytyt kysymykset

Onko oppitunti ”Aikavyöhykkeet ja aikaleimat” ilmainen?

Kyllä – oppitunnin ”Aikavyöhykkeet ja aikaleimat” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Valmistautuminen ohjelmointihaastatteluihin-kurssin, päivitä CoddyKit PROhon. Valmistautuminen ohjelmointihaastatteluihin-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Aikavyöhykkeet ja aikaleimat”?

UTC-ajan tallentaminen, aikavyöhykkeiden muuntaminen ja haastatteluissa esiin nousevat aikaleimojen sudenkuopat. Harjoittelet Valmistautuminen ohjelmointihaastatteluihin-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Valmistautuminen ohjelmointihaastatteluihin-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Valmistautuminen ohjelmointihaastatteluihin-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Aikavyöhykkeet ja aikaleimat”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Valmistautuminen ohjelmointihaastatteluihin-oppitunnilla?

Kyllä. Jokainen Valmistautuminen ohjelmointihaastatteluihin-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Päivämääräaritmetiikka ja aikavälit
  2. Päivämäärien katkaisu ja ryhmittely
  3. Merkkijonojen jäsentäminen ja muotoilu
  4. Aikavyöhykkeet ja aikaleimat
← Takaisin: Valmistautuminen ohjelmointihaastatteluihin