2012-04-17 13 views
13

Quindi ho un sito con una funzione di commenti in cui il timestamp del commento è memorizzato in un database MySQL. Da quanto ho capito, il timestamp viene convertito in UTC una volta memorizzato, quindi riconvertito al fuso orario predefinito quando recuperato. Nel mio caso, il mio server si trova nel fuso orario Central Daylight Time (CDT).PHP e MySQL: conversione di TIMESTAMP memorizzato nel fuso orario locale dell'utente

Ho un piano per ottenere il fuso orario da ciascun utente tramite il modulo di iscrizione. Volevo solo sapere come convertire il valore TIMESTAMP nel fuso orario dell'utente.

  • In primo luogo, dovrei convertire da UTC a fuso orario locale? O CDT al fuso orario locale?
  • In secondo luogo, come potrei fare in PHP? Avrei solo fare:
 
$userTimezone = new DateTimeZone($userSubmittedTimezoneString); 
$myDateTime = new DateTime($storedTimestamp, $userTimezone); 

... o è che non è corretta?

+2

no, i timestamp vengono memorizzati così come sono in mysql, ma senza dati TZ. se si inserisce "3pm, CST" nel db, quindi 3pm, cst è ciò che è memorizzato. Dovresti convertire in UTC prima di inserirlo, in modo da avere una base invariata comune da convertire in altre TZ. –

risposta

20

Data/datetime vengono memorizzati in MySQL come li si fornisce. Cioè se la stringa 2012-04-17 12:03:23 nella colonna è la INSERT, è il valore che verrà memorizzato. Verrà convertito internamente in un timestamp che può essere o non essere accurato (vedi sotto), ma quando richiedi nuovamente il valore, otterrai lo stesso valore; l'andata e ritorno è trasparente.

I problemi possono verificarsi se si tenta di eseguire calcoli temporali all'interno di SQL. Cioè qualsiasi operazione che richiede che SQL tenga conto del fuso orario e/o dell'orario del server. Ad esempio, utilizzando NOW(). Per ognuna di queste operazioni, il fuso orario e/o l'ora del server devono essere impostati correttamente. Vedi Time Zone Problems.

Se ciò non riguarda te e devi solo eseguire calcoli in PHP, devi solo assicurarti di sapere da quale fuso orario a quale fuso orario vuoi convertire. A tale scopo, può essere conveniente per standardizzare tutti i tempi in UTC, ma non è necessario, poiché le conversioni di fuso orario da qualsiasi fuso orario a qualsiasi altro fuso orario funzionano altrettanto bene, purché tu sia chiaro su quale fuso orario sei conversione da e verso.

date_default_timezone_set('Asia/Tokyo'); // your reference timezone here 

$date = date('Y-m-d H:i:s'); 

/* INSERT $date INTO database */; 

$date = /* SELECT date FROM database */; 

$usersTimezone = new DateTimeZone('America/Vancouver'); 
$l10nDate = new DateTime($date); 
$l10nDate->setTimeZone($usersTimezone); 
echo $l10nDate->format('Y-m-d H:i:s'); 
+0

Questo codice è il migliore per soddisfare le mie esigenze. Tuttavia, penso che potrebbe essere meglio archiviare i fusi orari in un modo come questo: http://blog.benkuhl.com/2009/12/timezone-list-in-mysql/ con gli offset specificati. È un modo migliore di presentare le scelte all'utente. Con i fusi orari memorizzati in questo modo e se conosco il fuso orario del server (che sembra essere CDT), come posso utilizzare l'offset noto (ad esempio -5.0, 3.0) sui valori 'TIMESTAMP' memorizzati nel database? – TerranRich

+0

@Terran Si desidera veramente utilizzare i fusi orari con i rispettivi identificatori denominati, non semplicemente con un offset. Gli offset cambiano durante l'anno in base alle normative locali sull'ora legale e tutti questi sono diversi. Se l'utente sceglie "DST -06: 00" oggi, non ha idea di quale fuso orario sia e quando cambierà in "DST -07: 00" o "DST -05: 00". Devi lasciare che l'utente scelga un fuso orario denominato. È possibile calcolare e visualizzare l'offset nel momento in cui l'utente lo sceglie, se lo si desidera. – deceze

+0

OK, quindi quando si presenta la casella di riepilogo per gli utenti tra cui scegliere, i valori inviati al database saranno come 'America/New_York' ... c'è un modo per visualizzare l'offset * corrente * di America/New_York' e al GMT quando danno loro l'opzione? \t Forse qualcosa come la risposta a http://stackoverflow.com/questions/1727077/generating-a-drop-down-list-of-timezones-with-php sarebbe la strada da percorrere per generare l'elenco per l'utente ? – TerranRich

1

Non esiste un modo affidabile per ottenere il fuso orario dell'utente. Le informazioni sul fuso orario non vengono inviate nelle intestazioni HTTP. Il meglio che si possa fare è uno:

  1. corrisponde all'indirizzo IP againsta database geografico oppure
  2. utilizzare JavaScript per ottenere il tempo impostato sul computer dell'utente e sia inviare che al server (AJAX) o rendere la stringa di tempo sul client.
+4

Ha già un modo per ottenere il fuso orario. Chiede agli utenti di selezionare il fuso orario in cui si trovano. Quello che vuole è un modo per convertire il tempo nel fuso orario specificato. – Jack

+0

Vedo, grazie Jack. – dotancohen

0
$timezone = new DateTimeZone('America/Vancouver'); 

$date = new DateTime(date('m/d/Y h:i:s a', time())); 
$date->setTimeZone($timezone); 
echo $date->format('l F j Y g:i:s A')."\n"; 

Sostituire new DateTime(date('m/d/Y h:i:s a', time())); con new DateTime("UTC Time");

È possibile creare un nuovo DateTimeZone() oggetto per ogni input dell'utente.

0

Il modo per farlo è utilizzando javascript. Penso che il modo migliore per farlo è archiviare gli utenti GMT nei suoi cookie e recuperarli nel modulo di processo di PHP.

<script language="javascript"> 

function TimeZoneCookie() 
{ 
var u_gmt = (-(new Date().getTimezoneOffset()))/60; 
var o_date = new Date("December 31, 2025"); 
var v_cookie_date = o_date.toGMTString(); 
var str_cookie = "utimezone="+u_gmt; 
str_cookie += ";expires=" + v_cookie_date; 
document.cookie=str_cookie; 
} 
//--------------------- 
TimeZoneCookie(); 

</script> 

u_gmt spiegato:

  1. Date().getTimezoneOffset() restituisce l'offset al GMT-0 in minuti
  2. Dal getTimezoneOffset() tornerà l'offset al GMT-0 e non da GMT-0 avremo bisogno di girarlo. Come? semplice, solo sapendo che -*-=+ & -*+=-. Se conosci la matematica di base, conosci già questo principio.
  3. Come ho detto in passaggio 1getTimezoneOffset() restituirà l'offset in pochi minuti, quindi lo dividiamo solo per 60, in modo che possiamo ottenere il formato offset GMT.

Risultato:(-(new Date().getTimezoneOffset()))/60


Ora recuperare il cookie in PHP:/tempo valori

<?php 

$user_timezone = $_COOKIE['utimezone']; 

?> 
Problemi correlati