2026-03-13

Wordpress

Rätt hantering av datum och tid i WordPress – wp_date och DateTime()

Att hantera datum och tider korrekt i WordPress är avgörande för att undvika buggar som kan vara svåra att spåra. En vanlig källa till problem är att blanda ihop när man ska använda wp_date() och när man ska använda PHPs inbyggda DateTime(). Den här artikeln förklarar skillnaden och ger praktiska kodexempel.

Bakgrund – Tidszoner i WordPress

WordPress lagrar all datum- och tidsinformation i databasen i UTC (Coordinated Universal Time). När du presenterar ett datum för användaren ska det konverteras till webbplatsens tidszon, vilket konfigureras under Inställningar → Allmänt i adminpanelen.

Funktionen wp_date() gör just det – den formaterar ett datum och konverterar det från UTC till webbplatsens lokala tidszon. Det är viktigt att förstå att denna konvertering bara ska ske en gång.

Spara datum till databasen – använd wp_date()

När du tar emot ett datum från användaren (t.ex. via ett formulär eller ett ACF-fält) och ska spara det i databasen, behöver du konvertera det till UTC. Skapa ett DateTime-objekt med webbplatsens tidszon och konvertera sedan till UTC innan du sparar.

/**
 * Konverterar ett datum från webbplatsens tidszon till UTC
 * och sparar det som post meta.
 *
 * @param int    $post_id  Post-ID att spara till.
 * @param string $date_str Datumsträng i lokalt format, t.ex. "2024-06-15 14:30:00".
 */
function save_event_date( int $post_id, string $date_str ): void {
    // Skapa ett DateTime-objekt med webbplatsens tidszon.
    $timezone = new DateTimeZone( wp_timezone_string() );
    $local_dt = new DateTime( $date_str, $timezone );

    // Konvertera till UTC och spara i databasen.
    $local_dt->setTimezone( new DateTimeZone( 'UTC' ) );
    $utc_date = $local_dt->format( 'Y-m-d H:i:s' );

    update_post_meta( $post_id, 'event_date_utc', $utc_date );
}

Om du i stället vill spara ett Unix-tidsstämpel fungerar det ännu enklare, eftersom getTimestamp() alltid returnerar ett UTC-baserat värde:

/**
 * Sparar ett Unix-tidsstämpel från en lokal datumsträng.
 *
 * @param int    $post_id  Post-ID att spara till.
 * @param string $date_str Datumsträng i lokalt format.
 */
function save_event_timestamp( int $post_id, string $date_str ): void {
    $timezone = new DateTimeZone( wp_timezone_string() );
    $local_dt = new DateTime( $date_str, $timezone );

    // getTimestamp() returnerar alltid UTC-baserat Unix-tidsstämpel.
    update_post_meta( $post_id, 'event_timestamp', $local_dt->getTimestamp() );
}

Läsa datum från databasen – använd DateTime()

När du läser ett datum ur databasen är värdet redan lagrat i UTC. Du ska inte använda wp_date() för att parsa det råa värdet – det är enbart avsett för att presentera datumet för slutanvändaren. Använd istället DateTime() för att skapa ett objekt:

/**
 * Hämtar ett sparat event-datum och returnerar ett DateTime-objekt.
 *
 * @param int $post_id Post-ID att läsa från.
 * @return DateTime|null DateTime i UTC, eller null om inget värde finns.
 */
function get_event_date( int $post_id ): ?DateTime {
    $utc_date = get_post_meta( $post_id, 'event_date_utc', true );

    if ( empty( $utc_date ) ) {
        return null;
    }

    // Skapa DateTime med UTC – värdet är redan i UTC från databasen.
    return new DateTime( $utc_date, new DateTimeZone( 'UTC' ) );
}

// Exempelanvändning:
$event_dt = get_event_date( $post_id );

if ( $event_dt !== null ) {
    // Konvertera till webbplatsens tidszon före visning.
    $event_dt->setTimezone( new DateTimeZone( wp_timezone_string() ) );

    // Formatera med wp_date() för presentation (tar hänsyn till WP-locale).
    echo wp_date( 'd F Y, H:i', $event_dt->getTimestamp() );
}

Har du sparat ett Unix-tidsstämpel är det ännu enklare:

/**
 * Hämtar ett Unix-tidsstämpel och returnerar ett DateTime-objekt.
 *
 * @param int $post_id Post-ID att läsa från.
 * @return DateTime|null DateTime i UTC, eller null om inget värde finns.
 */
function get_event_datetime_from_timestamp( int $post_id ): ?DateTime {
    $timestamp = get_post_meta( $post_id, 'event_timestamp', true );

    if ( empty( $timestamp ) ) {
        return null;
    }

    // Skapa DateTime från Unix-tidsstämpel (alltid UTC).
    $dt = new DateTime( '@' . (int) $timestamp );

    return $dt;
}

// Exempelanvändning:
$event_dt = get_event_datetime_from_timestamp( $post_id );

if ( $event_dt !== null ) {
    // wp_date() konverterar från UTC till webbplatsens tidszon och formaterar.
    echo wp_date( 'Y-m-d H:i', $event_dt->getTimestamp() );
}

Vanligt misstag – dubbel konvertering med wp_date()

Det allra vanligaste felet är att använda wp_date() även när man läser ett värde ur databasen och redan vet att det är UTC. Eftersom wp_date() alltid konverterar från UTC till lokal tid, är det fullt korrekt – men om du råkar spara ett lokalt värde och sedan läser det med wp_date(), konverteras det igen och du får fel resultat.

Här är ett tydligt exempel på vad som kan gå fel:

// Scenario: webbplatsens tidszon är Europe/Stockholm (UTC+2 sommartid)

// ❌ FEL – värdet sparas INTE konverterat till UTC.
function save_date_wrong( int $post_id, string $date_str ): void {
    // date_str är "2024-06-15 14:30:00" (lokal tid, UTC+2)
    // wp_date() konverterar ett timestamp från UTC → lokal tid.
    // Används FEL här: vi skickar in ett lokalt värde via strtotime().
    $formatted = wp_date( 'Y-m-d H:i:s', strtotime( $date_str ) );
    // $formatted är nu "2024-06-15 16:30:00" – konverterat +2 timmar FEL!
    update_post_meta( $post_id, 'event_date', $formatted );
}

// ✅ RÄTT – konvertera till UTC med DateTime().
function save_date_correct( int $post_id, string $date_str ): void {
    $timezone = new DateTimeZone( wp_timezone_string() );
    $local_dt = new DateTime( $date_str, $timezone );
    $local_dt->setTimezone( new DateTimeZone( 'UTC' ) );
    update_post_meta( $post_id, 'event_date', $local_dt->format( 'Y-m-d H:i:s' ) );
}

Och på läsningssidan:

$utc_date = get_post_meta( $post_id, 'event_date', true ); // "2024-06-15 12:30:00" (UTC)

// ❌ FEL – använder wp_date() för att parsa strängen via strtotime()
// wp_date() konverterar korrekt, men strtotime() tolkar strängen
// som lokal servertid – inte UTC – vilket kan ge fel timestamp!
$wrong = wp_date( 'd F Y H:i', strtotime( $utc_date ) );

// ✅ RÄTT – skapa ett DateTime-objekt med explicit UTC-tidszon.
$dt    = new DateTime( $utc_date, new DateTimeZone( 'UTC' ) );
$right = wp_date( 'd F Y H:i', $dt->getTimestamp() ); // Konverterar korrekt UTC → lokal tid

Sammanfattning

Situation Använd Varför
Spara datum till databasen DateTime() + setTimezone('UTC') Konverterar lokal tid till UTC för lagring
Läsa datum från databasen new DateTime($val, new DateTimeZone('UTC')) Parsar det lagrade UTC-värdet korrekt
Presentera datum för användaren wp_date() Konverterar UTC → lokal tid och formaterar
Parsa ett lokalt värde new DateTime($val, new DateTimeZone(wp_timezone_string())) Undviker dubbelkonvertering

Kom ihåg: wp_date() är avsedd för presentation – att formatera och konvertera ett Unix-tidsstämpel till ett läsbart datum i webbplatsens lokala tidszon. DateTime() är verktyget för att hantera och manipulera datum programmatiskt. Håll dem åtskilda, och din datumhantering i WordPress blir både korrekt och förutsägbar.