2016-12-27 86 views
0

我在建立一個mysql表格的早期階段,將保存來自兩個時區的數據。我的機器和服務器都在America/Los_Angeles時區。時區表沒有加載到MySQL服務器中,但在本網站的其他地方,我讀過這不是必要的,只要php處理查詢 - php會將UTC偏移量寫入到mysql中。 Mysql數據類型是TIMESTAMP。樣本數據已經被插入一個PHP腳本,其中包括以下語句:php mysql UTC timestamp

 if($company == 'HOS_CIN' or $company == 'HOS_FER') { 
     date_default_timezone_set("America/New_York"); 
    } 

然後兩個PHP腳本用於在瀏覽器中顯示的數據。其中一個包括上述說明,另一個則沒有。帶有聲明的那個人顯示的時間是中午的EST,而沒有顯示的時間是PST的中午。如果mysql存儲了UTC偏移量,那麼顯示的時間不應該有三小時的差異嗎?

PHP版本5.3.3,MySQL的版本5.0.95

+0

1)不,PHP將不打印UTC如果你不告訴它(例如,將時區設置爲UTC)2)'TIMESTAMP'在存儲/檢索日期時從/到MySQL服務器的時區轉換,似乎你沒有考慮設置一個已知的一。 –

+0

是不是date_default_timezone_set的目的? – dirk

+0

不確定你現在的意思,如果你選擇「America/New_York」,它將使用紐約時間,而不是UTC。 MySQL是一種不同的程序,有時甚至可以在另一臺計算機上運行;它不會關心PHP時區。 –

回答

0

你要面對關於PHP和MySQL以下限制:

  • MySQL沒有任何列類型,它允許存儲當地時間與時區信息。

  • PHP無法將複雜的數據類型(例如DateTime實例)傳遞給MySQL,所有事情都需要進行字符串化處理,而且MySQL沒有語法將日期文字與時區信息一起傳遞。

在實踐中它不是那麼糟糕,因爲它看起來可能,因爲你通常不需要插入誰的信息,用戶的本地時間:你只需要知道在時間的確切時刻所保存的日期指的是(可選)存儲日期必須顯示的時區。並且基本上有三種明智的方式來執行此操作:

  1. 使用不受時區影響的格式,例如, Unix時間戳存儲爲INT

  2. 使用具有明確時區信息的日期列類型,例如,一個TIMESTAMP列(不要與Unix時間戳混淆),其中時區始終是UTC。

  3. 使用帶隱式時區信息的日期列類型,例如, DATEDATETIME列,您已決定所有日期都屬於給定時區,可能是UTC。

#2和#3之間的區別在於MySQL是否知道時區,或者只有您和您的代碼知道。

無論您選擇的方法,這是必要的,這是預料之中的事時的所有程序區轉換被指示要使用哪個時區:

  • PHP需要的時間段來生成/顯示的Unix時間戳並將用戶輸入/預期的本地時間以及MySQL預期的/打印的時間轉換成本地時間,例如:

    $user_date = new DateTime('2016-10-03 00:00:00', new DateTimeZone('Europe/Berlin')); 
    $user_date->setTimezone(new DateTimeZone('UTC')); 
    echo $user_date->format('c'); 
    
  • MySQL需要時使用TIMESTAMP列,從/轉換爲本地時間的時區,例如:

    mysql> create table foo(
        -> foo int(10) unsigned auto_increment, 
        -> my_date timestamp, 
        -> primary key (foo) 
        ->); 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> set @@time_zone = '+01:00'; 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> insert into foo (my_date) values ('2016-12-27 18:50:00'); 
    Query OK, 1 row affected (0.00 sec) 
    
    mysql> set @@time_zone = '-07:00'; 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> insert into foo (my_date) values ('2016-12-27 18:50:00'); 
    Query OK, 1 row affected (0.00 sec) 
    
    mysql> select * from foo order by 1; 
    +-----+---------------------+ 
    | foo | my_date    | 
    +-----+---------------------+ 
    | 1 | 2016-12-27 10:50:00 | 
    | 2 | 2016-12-27 18:50:00 | 
    +-----+---------------------+ 
    2 rows in set (0.00 sec) 
    
    mysql> set @@time_zone = '+09:30'; 
    Query OK, 0 rows affected (0.00 sec) 
    
    mysql> select * from foo order by 1; 
    +-----+---------------------+ 
    | foo | my_date    | 
    +-----+---------------------+ 
    | 1 | 2016-12-28 03:20:00 | 
    | 2 | 2016-12-28 11:20:00 | 
    +-----+---------------------+ 
    2 rows in set (0.00 sec)