2012-04-17 42 views
13

Vì vậy, tôi có một trang web có tính năng nhận xét trong đó dấu thời gian của nhận xét được lưu trữ trong cơ sở dữ liệu MySQL. Từ những gì tôi hiểu, dấu thời gian được chuyển thành UTC khi được lưu trữ, sau đó chuyển đổi về múi giờ mặc định khi được truy xuất. Trong trường hợp của tôi, máy chủ của tôi nằm trong múi giờ ban ngày trung tâm (CDT).PHP & MySQL: Chuyển đổi TIMESTAMP được lưu trữ thành múi giờ địa phương của người dùng

Tôi có kế hoạch nhận múi giờ từ mỗi người dùng thông qua biểu mẫu nhập. Tôi chỉ muốn biết cách chuyển đổi giá trị TIMESTAMP vào múi giờ của người dùng.

  • Trước tiên, tôi có chuyển đổi từ UTC thành múi giờ địa phương không? Hoặc CDT đến múi giờ địa phương?
  • Thứ hai, tôi sẽ làm thế nào trong PHP? Tôi chỉ cần làm:
 
$userTimezone = new DateTimeZone($userSubmittedTimezoneString); 
$myDateTime = new DateTime($storedTimestamp, $userTimezone); 

... hoặc điều đó không đúng?

+2

không, dấu thời gian được lưu trữ như trong mysql, nhưng không có bất kỳ dữ liệu TZ nào. nếu bạn chèn "3pm, CST" vào db, sau đó 3 giờ chiều, cst là những gì được lưu trữ. Bạn cần chuyển đổi sang UTC trước khi chèn, do đó bạn có cơ sở không thay đổi chung để chuyển đổi sang các TZ khác. –

Trả lời

20

Ngày/thời gian/giá trị datetime được lưu trữ trong MySQL như bạn cung cấp cho họ. I E. nếu bạn INSERT chuỗi 2012-04-17 12:03:23 thành một cột DATETIME, đó là giá trị sẽ được lưu trữ. Nó sẽ được chuyển đổi nội bộ thành một dấu thời gian có thể hoặc có thể không chính xác (xem bên dưới), nhưng khi bạn truy vấn lại giá trị, bạn sẽ nhận được cùng một giá trị trở lại; khứ hồi là minh bạch.

Sự cố có thể xảy ra nếu bạn cố gắng thực hiện các phép tính thời gian bên trong SQL. I E. bất kỳ thao tác nào yêu cầu SQL phải tính thời gian và/hoặc thời gian của máy chủ. Ví dụ: sử dụng NOW(). Đối với bất kỳ hoạt động nào, múi giờ và/hoặc thời gian máy chủ nên được đặt chính xác. Xem Time Zone Problems.

Nếu điều đó không liên quan đến bạn và bạn chỉ cần thực hiện các phép tính trong PHP, bạn chỉ cần đảm bảo bạn biết từ múi giờ nào bạn muốn chuyển đổi múi giờ nào. Vì mục đích đó, có thể thuận tiện để chuẩn hóa mọi thời gian thành UTC, nhưng không cần thiết, vì chuyển đổi múi giờ từ bất kỳ múi giờ nào sang múi giờ khác cũng chỉ hoạt động, miễn là bạn rõ ràng về múi giờ nào chuyển đổi từ và sang.

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

Mã này phù hợp nhất với nhu cầu của tôi. Tuy nhiên, tôi nghĩ rằng nó có thể là tốt hơn để lưu trữ múi giờ theo cách như thế này: http://blog.benkuhl.com/2009/12/timezone-list-in-mysql/ với các offset được xác định. Đó là một cách tốt hơn để trình bày các lựa chọn cho người dùng. Với múi giờ được lưu trữ theo cách đó và nếu tôi biết múi giờ của máy chủ (có vẻ là CDT), làm cách nào tôi có thể sử dụng giá trị được biết (ví dụ: -5.0, 3.0) trên các giá trị 'TIMESTAMP' được lưu trữ trong cơ sở dữ liệu? – TerranRich

+0

@Terran Bạn thực sự muốn sử dụng múi giờ theo số nhận dạng được đặt tên của chúng, không chỉ bằng cách bù đắp. Bù đắp thay đổi trong suốt cả năm dựa trên các quy định tiết kiệm ánh sáng ban ngày của địa phương và tất cả những thay đổi đó đều khác nhau. Nếu người dùng chọn "DST -06: 00" ngày hôm nay, bạn không có ý tưởng múi giờ nào và khi nào sẽ thay đổi thành "DST -07: 00" hoặc "DST -05: 00". Bạn phải cho phép người dùng chọn múi giờ được đặt tên. Bạn có thể tính toán và hiển thị độ lệch tại thời điểm người dùng chọn nó nếu bạn muốn. – deceze

+0

OK, vì vậy khi trình bày hộp danh sách để người dùng lựa chọn, các giá trị được gửi đến cơ sở dữ liệu sẽ là những thứ như 'America/New_York' ... có cách hiển thị * offset * hiện tại của' America/New_York' không et al to GMT khi cho họ lựa chọn? \t Có lẽ một cái gì đó giống như câu trả lời cho http://stackoverflow.com/questions/1727077/generating-a-drop-down-list-of-timezones-with-php sẽ là cách để tạo ra danh sách cho người dùng ? – TerranRich

1

Không có cách nào đáng tin cậy để nhận múi giờ của người dùng. Thông tin múi giờ không được gửi trong tiêu đề HTTP. Điều tốt nhất mà bạn có thể làm là một trong hai:

  1. Phù hợp với địa chỉ IP againsta cơ sở dữ liệu địa lý -hoặc-
  2. Sử dụng Javascript để có được thời gian đặt trên máy tính của người dùng và một trong hai gửi đến máy chủ (AJAX) hoặc tạo chuỗi thời gian trên máy khách.
+4

Anh ấy đã có cách để có múi giờ. Anh ấy yêu cầu người dùng chọn múi giờ họ đang ở. Những gì anh ấy muốn là một cách để chuyển đổi thời gian thành múi giờ được chỉ định. – Jack

+0

Tôi hiểu, cảm ơn 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"; 

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

Bạn có thể tạo một DateTimeZone() đối tượng mới cho mỗi đầu vào người dùng.

0

Cách để làm điều đó là sử dụng javascript. Tôi nghĩ cách tốt nhất để làm điều đó là lưu trữ người dùng GMT vào cookie của anh ta và lấy nó trên biểu mẫu tiến trình 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 giải thích:

  1. Date().getTimezoneOffset() trả về bù đắp lấy múi giờ GMT-0 trong vài phút
  2. Kể từ getTimezoneOffset() sẽ trả lại bù đắp lấy múi giờ GMT-0 và không từ GMT-0 chúng ta sẽ cần phải xoay vòng. Làm sao? đơn giản, chỉ bằng cách biết rằng -*-=+ & -*+=-. Nếu bạn biết toán cơ bản, bạn đã biết nguyên tắc này.
  3. Như tôi đã nói trong bước 1getTimezoneOffset() sẽ trả về giá trị bù trừ bằng phút, vì vậy chúng tôi chỉ chia cho 60, vì vậy chúng tôi có thể lấy định dạng bù đắp gmt.

Kết quả:(-(new Date().getTimezoneOffset()))/60


Bây giờ lấy cookie trong PHP:

<?php 

$user_timezone = $_COOKIE['utimezone']; 

?> 
Các vấn đề liên quan