2012-02-19 74 views
7

我想问,如果这是去上班之前,我对我如何处理日期和时间完全成熟的重构去了。存储日期和时间在UTC并将其转换在PHP当地时间/ MySQL的

到帧我的问题,这是我的问题... 我保存用户的历史记录表所采取的“行动”。这些行为有一个时间戳。用户可以来自世界各地,因此有不同的时区。我想要显示历史中的项目并在当地时区显示时间戳。

另外,我知道我可以使用日期时间字段,只是存储UTC时间格式,但我选择使用时间戳,所以我可以设置默认为当前时间。

这是否适合我的问题?

  1. 我的服务器的时区将是洛杉矶

  2. 商店时间戳MySQL中的时间戳。我的理解是,时间戳记始终以UTC格式存储。记录将默认存储为creation_date或者我将明确设置UTC_TIMESTAMP()。有效地,数据库中的所有记录都是UTC。

  3. 当用户登录我会抓住他们的时区(我这个存储在数据库中的用户设置)。 对于这个例子,可以说这个人在纽约。

这是我的问题所在。这些工作是否会起作用?

  • 一个)抓斗的历史数据。所有时间戳会自动从UTC转换到洛杉矶时间。 Foreach历史项目,将洛杉矶时间戳转换为纽约时间戳和回显。
  • OR

  • b)设置在PHP时区 “date_default_timezone_set” 纽约。抓取历史数据。所有的时间戳仍然在洛杉矶时间仍然是洛杉矶时间。 Foreach历史项目,只是回显时间戳,因为“date_default_timezone_set”会自动将洛杉矶时间戳转换为纽约。
  • 意志选项4B工作?有没有更好的方法将洛杉矶时间转换为纽约时间?

    有没有更好的方法来做到这一点?

    +3

    以UTC格式存储,显示本地用户是主流解决方案。 – 2012-02-19 20:47:06

    回答

    5

    你是对的,Unix时间戳总是UTC。如果将时间戳存储在数据库中的UTC,则只需在本地时间输出时间戳即可将PHP中的时区更改为用户本地的时区。您不需要对时间戳进行任何转换。

    <?php 
    
    $timeStampFromDatabase = 1325448000; // 01 Jan 2012 20:00:00 GMT 
    
    date_default_timezone_set('America/Los_Angeles'); 
    echo date('r', $timeStampFromDatabase); // Sun, 01 Jan 2012 12:00:00 -0800 
    
    date_default_timezone_set('Asia/Hong_Kong'); 
    echo date('r', $timeStampFromDatabase); // Mon, 02 Jan 2012 04:00:00 +0800 
    

    您可以在飞行中改变你的时区,并继续输出时间戳的日期格式,他们会根据在PHP中设置时区是“转化”。这很容易,你不需要做任何特殊的处理,只要你在输出日期之前这样做,并且你可以在设置时区之前阅读它们,但是在何处设置时区并不重要。

    +1

    'date_default_timezone_set'用于设置默认时区。我不会设置它一次以上。我认为最好创建一个'DateTime'对象并使用'DateTime :: setTimezone()':http://www.php.net/manual/en/function.date-timezone-set.php – CodeZombie 2012-02-19 20:54:17

    +0

    那么我只是改变它来说明这一点。我想它只会在应用程序中设置一次,但可以多次切换。如果您在切换时非常小心,可以随时对其进行更改,然后将其更改回以前的值,而不会出现任何问题。 – drew010 2012-02-19 20:56:11

    +1

    谢谢你的帮助。关于date_default_timezone_set函数的一些小问题。这是一个只影响当前用户的设置还是全局系统变量?如果它是一个全局变量,它不能在不同时区的所有用户中造成问题吗? – jsheir 2012-02-20 09:34:55

    3

    不幸的是,“date_default_timezone_set”没有按照我认为的方式工作。根据前面的例子,如果我正在使用的日期已经是unix时间戳格式,那么它就会工作。然而,他们被格式化为“Y-m-d H:i:s”,唯一会改变的是GMT偏移量,这显然不起作用。

    经过几个小时的烦躁后,下面是我如何处理时间转换。

    $datetime = new DateTime($date_to_convert); 
    $usertimezone = new DateTimeZone($_SESSION['timezone']); //each user has their own timezone i store in a session (i.e. - "Americas/Los_Angeles") 
    $datetime->setTimezone($usertimezone); 
    echo $datetime->format("Y-m-d H:i:s"); 
    

    我想我可以做下面还有:

    Pseudo code 
    strtotime($datetime) 
    date_default_timezone_set($user_timezone) 
    echo date(format, $datetime) 
    

    以上,我认为,将生效的日期函数来处理它在给定的$ user_timezone逻辑。事后看来,我将不得不翻译每个$ datetime - > unix_timestamp - > $ datetime_converted,这听起来并不比我选择做的要好得多。

    1

    始终将您的时间戳存储为数据库中的UTC。这是一个时区和夏令时独立的时间点。要在用户的时区显示这一点,只需执行以下操作:

    $users_timezone = 'Europe/London'; // See PHP documentation for names that can be used. 
    $date = new DateTime(); 
    $date->setTimestamp($timestamp_from_database); 
    $date->setTimezone(new DateTimeZone($users_timezone)); 
    echo $date->format("H:ia jS F Y"); 
    
    0

    默认情况下,Unix时间戳始终为UTC。如果我们将时间戳存储在UTC数据库中,我们只需要使用以下PHP脚本:

    <?php 
    
    $TZ_UTC = new DateTimeZone('UTC'); //-->Database Timezone; 
    $TZ_LOCAL = new DateTimeZone('America/New_York'); //-->Expected Local Timezone from user settings; 
    
    //--Example Database Query-- 
    while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { 
        //---If we want to show UTC timezone directy---- 
        echo $row['action_timestamp']; 
    
        //---If we want to show LOCAL timezone from user settings---- 
        $dateObj = new DateTime($row['action_timestamp'], $TZ_UTC); 
        $dateObj->setTimezone($TZ_LOCAL); //--> Here is the conversion! 
        echo $dateObj->format("Y-m-d H:i:s T"); 
    } 
    ?> 
    
    相关问题