2012-02-19 37 views
7

Tôi muốn hỏi xem điều này có hiệu quả không, trước khi tôi thực hiện công việc sửa lỗi chính xác về cách xử lý ngày và giờ.Lưu trữ ngày và thời gian trong UTC và chuyển đổi giờ địa phương bằng PHP/MySQL

Để đặt câu hỏi cho tôi, đây là vấn đề của tôi ... Tôi lưu trữ "hành động" do người dùng thực hiện trong bảng lịch sử. Những hành động này có dấu thời gian trên chúng. Người dùng có thể đến từ khắp nơi trên thế giới và do đó có múi giờ khác nhau. Tôi muốn hiển thị các mục trong lịch sử và hiển thị dấu thời gian trong múi giờ địa phương của một người.

Ngoài ra, tôi biết tôi có thể sử dụng trường ngày giờ và chỉ lưu trữ định dạng thời gian UTC, nhưng tôi chọn sử dụng dấu thời gian để tôi có thể đặt mặc định thành thời gian hiện tại.

Điều này có phù hợp với sự cố của tôi không?

  1. múi giờ máy chủ của tôi sẽ là Los Angeles

  2. cửa hàng timestamps như một dấu thời gian trong MySQL. Sự hiểu biết của tôi là dấu thời gian luôn được lưu trữ dưới dạng UTC. Các bản ghi sẽ được lưu trữ theo mặc định là creation_date HOẶC tôi sẽ đặt UTC_TIMESTAMP() một cách rõ ràng. Quả thực, tất cả các bản ghi trong db sẽ là UTC.

  3. Khi người dùng đăng nhập, tôi sẽ lấy múi giờ của họ (tôi lưu trữ múi giờ này trong db dưới dạng cài đặt người dùng). Ví dụ này, giả sử người này ở New York.

Đây là câu hỏi của tôi. Một trong hai tác phẩm này có hoạt động không?

  1. a) Lấy dữ liệu lịch sử. Tất cả các dấu thời gian sẽ tự động được chuyển đổi từ UTC sang Los Angeles. Mục lịch sử Foreach, chuyển đổi dấu thời gian Los Angeles thành dấu thời gian và tiếng vọng của New York.

HOẶC

  1. b) Đặt php múi giờ "date_default_timezone_set" đến New York. Lấy dữ liệu lịch sử. Tất cả các dấu thời gian là STILL ở Los Angeles thời gian bằng máy chủ vẫn là thời gian Los Angeles. Mục lịch sử Foreach, chỉ cần lặp lại dấu thời gian vì "date_default_timezone_set" sẽ tự động chuyển đổi dấu thời gian Los Angeles thành New York.

Tùy chọn 4b có hoạt động không? Có cách nào tốt hơn để chuyển đổi từ thời gian Los Angeles sang New York?

Có cách nào tốt hơn để làm điều này nói chung không?

+3

Lưu trữ trong UTC, hiển thị địa phương cho người dùng là giải pháp hiện hành. –

Trả lời

5

Bạn đúng, dấu thời gian Unix luôn ở dạng UTC. Nếu bạn lưu dấu thời gian trong cơ sở dữ liệu của bạn trong UTC, tất cả những gì bạn cần làm để xuất nó theo thời gian cục bộ là thay đổi múi giờ trong PHP thành múi giờ cục bộ cho người dùng. Bạn không cần thực hiện bất kỳ chuyển đổi nào trên dấu thời gian.

<?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 

Bạn có thể thay đổi múi giờ khi đang di chuyển và tiếp tục xuất dấu thời gian ở định dạng ngày và chúng sẽ được "chuyển đổi" dựa trên múi giờ đã đặt trong PHP. Nó rất dễ dàng, bạn không cần phải thực hiện bất kỳ xử lý đặc biệt nào và không quan trọng bạn đặt múi giờ ở đâu, miễn là bạn thực hiện trước khi bạn xuất ngày, nhưng bạn có thể đọc chúng trước khi đặt múi giờ.

+1

'date_default_timezone_set' được sử dụng để đặt múi giờ mặc định. Tôi sẽ không đặt nó nhiều hơn một lần. Tôi nghĩ tốt hơn là nên tạo đối tượng 'DateTime' và sử dụng' DateTime :: setTimezone() ': http://www.php.net/manual/en/function.date-timezone-set.php – CodeZombie

+0

Tôi chỉ là thay đổi nó để minh họa điểm. Tôi đoán nó sẽ chỉ được thiết lập một lần trong ứng dụng, nhưng bạn có thể chuyển đổi nó nhiều lần. Nếu bạn cẩn thận trong việc chuyển đổi nó, bạn luôn có thể thay đổi nó và sau đó thay đổi nó trở lại những gì giá trị trước đó là không có bất kỳ vấn đề. – drew010

+1

cảm ơn một tấn giúp đỡ. câu hỏi hơi mới về hàm date_default_timezone_set. đây có phải là một thiết lập chỉ ảnh hưởng đến người dùng hiện tại hay nó là một biến hệ thống toàn cầu? nếu nó là một var toàn cầu, nó có thể gây ra vấn đề giữa tất cả người dùng trong các múi giờ khác nhau không? – jsheir

3

Rất tiếc, "date_default_timezone_set" không hoạt động theo cách tôi nghĩ. Theo ví dụ trước, nó sẽ hoạt động nếu những ngày tôi đang làm việc đã ở định dạng dấu thời gian unix. Tuy nhiên, họ đã được định dạng trong "Y-m-d H: i: s" và điều duy nhất có thể thay đổi là bù đắp GMT, mà rõ ràng là không hoạt động.

Sau một vài giờ bồn chồn, đây là cách tôi có thể xử lý chuyển đổi thời gian.

$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"); 

Tôi cho rằng mình có thể làm những điều sau đây cũng như:

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

trên, tôi nghĩ rằng, sẽ buộc các chức năng ngày để xử lý nó là logic trong $ user_timezone nhất định. trong hindsight, tôi sẽ phải dịch mỗi $ datetime -> unix_timestamp -> $ datetime_converted, mà doesnt âm thanh được tốt hơn nhiều so với những gì tôi đã chọn để làm.

1

Luôn lưu dấu thời gian của bạn trong cơ sở dữ liệu dưới dạng UTC. Đây là múi giờ độc lập và tiết kiệm ánh sáng ban ngày trong thời gian. Để hiển thị lại cho người dùng trong múi giờ của họ, chỉ cần thực hiện:

$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

Theo mặc định, dấu thời gian Unix luôn ở dạng UTC. Nếu chúng tôi lưu trữ dấu thời gian trong cơ sở dữ liệu của chúng tôi trong UTC, chúng tôi chỉ cần sử dụng tập lệnh PHP sau:

<?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"); 
} 
?> 
Các vấn đề liên quan