2013-08-08 49 views
7

Tôi đang phát triển một trang web nơi tôi phải xử lý các múi giờ có thể khác nhau từ người dùng. Điều này trở thành một vấn đề lớn vì trang web lưu trữ các sự kiện thời gian tinh tế như đấu giá.Làm thế nào để đối phó với múi giờ giữa máy chủ và máy khách?

Tất cả ngày/giờ trên máy chủ đều ở dạng UTC. Cơ sở dữ liệu lưu trữ mọi thứ trong dấu thời gian UTC. Múi giờ mặc định của PHP cũng được đặt thành UTC (date_default_timezone_set('UTC');).

Bây giờ, sự cố của tôi là cách tôi nên tương tác với người dùng, cho dù tôi chỉ hiển thị ngày hay quan trọng hơn, tôi đang đọc ngày/giờ từ đầu vào của người dùng.

Một ví dụ cụ thể:

  • Cuộc đấu giá có thời hạn, mà tôi lưu trữ trong cơ sở dữ liệu như UTC.
  • Khi tôi xem phiên đấu giá trên trang web, bộ hẹn giờ javascript sử dụng đối tượng Date để tính thời gian còn lại. Nó tự động chuyển đổi múi giờ thành GMT + 0100 (múi giờ địa phương của tôi). Vì vậy, nếu thời hạn là '2013-08-08 10:46:08' (UTC), đối tượng ngày javascript sẽ trả về Aug 08 2013 11:26:15 GMT+0100 (GMT Standard Time).
  • Nếu thời gian hiện tại lớn hơn 11:46:08 thì bộ hẹn giờ cho biết thời gian còn lại là 00:00 (chính xác).
  • Nhưng nếu tôi cố gắng để chèn một nỗ lực, máy chủ chấp nhận kể từ khi tình trạng trên MySQL INSERT đánh giá để true:

    INSERT INTO Hồ sơ dự thầu ... WHERE ... VÀ auction_deadline> NOW() ...

(vì auction_deadline = '2013-08-08 10:46:08' và VỚI DOANH NGHIỆP() = '2013-08-08 10:26:50')

Tất cả điều này mumbo jumbo của múi giờ tan não của tôi. Tôi đang thiếu gì ở đây? Tôi gần như chắc chắn rằng việc lưu trữ tất cả các ngày/giờ trong UTC bên trong cơ sở dữ liệu là tốt nhất. Tôi chỉ không thể nghĩ rằng tinh thể rõ ràng như thế nào để đối phó với nó giữa người sử dụng và cơ sở dữ liệu.

+0

Nếu bạn cần một số mã để làm rõ câu hỏi của tôi, vui lòng nói. –

Trả lời

3

Vấn đề của bạn không liên quan đến múi giờ, chỉ là thực tế là khách hàng có thể biến đồng hồ của họ hoặc có đồng hồ của họ bị lệch đáng kể. Cho rằng việc sửa chữa là để thăm dò ý kiến ​​các máy chủ mỗi một lần trong một thời gian cho một sửa chữa bù đắp để sử dụng trong tính toán.

Thực tế, bạn thậm chí không cần các đối tượng ngày tháng. Có một thời điểm phổ biến nhất định trong thời gian khi phiên đấu giá kết thúc. Giả sử nó là 1375960662823. Ngay bây giờ, thời gian chung trong thời gian là 1375960669199, do đó, từ đó chúng tôi thấy rằng phiên đấu giá kết thúc sau 6 giây (1375960662823 - 1375960669199 ~ 6000). Nó sẽ kết thúc sau 6 giây bất kể tôi ở Morocco hay Nhật Bản. Bạn có hiểu nó chưa?

Để tạo các số này, ở phía máy khách, bạn có thể gọi var now = Date.now() + skewFix trong đó skewFix là hiệu chỉnh cần áp dụng trong trường hợp máy khách bị lệch thời gian hoặc đặt máy tính của họ sai thời gian.

Trong PHP, bạn có thể tạo ra nó bằng $now = time() * 1000;

0

Bạn có thể làm như sau

một khi trang được tải, gửi yêu cầu ajax tới máy chủ với chênh lệch múi giờ của người dùng. Bạn có thể lấy bù trừ múi giờ bằng cách sử dụng mã sau đây.

var curdate = new Date() 
var offset = curdate.getTimezoneOffset() 

offset là chênh lệch múi giờ tính bằng phút.

Tôi nghĩ điều đó sẽ hữu ích.

0

Đây là một chủ đề điển hình nhưng rất phức tạp đối với hầu hết mọi người đều hiểu. Điều đầu tiên, bạn không bao giờ đề cập đến việc GIẢM GIÁ NGÀY. vâng tôi đang tăng căng thẳng của bạn :).

Bây giờ, hãy xem chúng tôi có thể làm điều này như thế nào. Bạn đã làm một công việc tốt bằng cách tiết kiệm thời gian trong UTC. Bây giờ, tôi hy vọng bạn đã đăng ký thành viên và mỗi thành viên có khả năng đặt múi giờ ưa thích của họ, nếu không bạn sẽ hiển thị thời gian dựa trên múi giờ của Máy chủ cho họ.

Khi bạn thông qua "thời gian bắt đầu" cho người dùng, bạn phải gửi chúng sau khi chuyển đổi thời gian UTC, tương tự như khi bạn chấp nhận TIME từ trình duyệt có thể là hành động của người dùng hoặc javascript bạn cần chuyển đổi thời gian đó sang UTC người dùng là múi giờ mà anh chọn cho tiểu sử của mình.

Hy vọng rằng hãy xóa ý tưởng về nơi bạn đang đi sai? Hãy đọc qua tiết kiệm ánh sáng ban ngày vì điều đó cũng sẽ đóng một vai trò quan trọng khi bạn tiến lên phía trước với logic khác giống nhau.

EDIT:

Bạn có thể sử dụng bù trừ múi giờ của javascript, để tự động gửi và nhập người dùng dựa trên cài đặt của mình.

0

mọi khi bạn nhận được ngày từ clientside, bạn có thể sử dụng getUTC để chuyển đổi cho đến nay UTC ví dụ:

var todayDate = new Date(); 

var todayDateInUTC = new Date(todayDate.getUTCFullYear(), todayDate.getUTCMonth(), todayDate.getUTCDate(), todayDate.getUTCHours(), todayDate.getUTCMinutes(), todayDate.getUTCSeconds()); 

như vậy ngay trước khi bạn chèn ngày nỗ lực nhằm cơ sở dữ liệu, sử dụng các chức năng getUTC để chuyển đổi nó thành định dạng UTC.

1

ngày trong JavaScript sử dụng múi giờ địa phương. Bạn sẽ nhận được thời gian UTC cho người dùng và gửi cho máy chủ

new Date 
Thu Aug 08 2013 17:00:14 GMT+0530 (India Standard Time) 
(new Date("Thu Aug 08 2013 17:00:14")).toUTCString(); 
"Thu, 08 Aug 2013 11:30:14 GMT" 

Điều này sẽ giải quyết vấn đề múi giờ giữa máy chủ và ứng dụng khách.

1

Bạn nói

(vì auction_deadline = '2013/08/08 10:46:08' và NOW() = '2013/08/08 10:26:50')

Trong MySQL - NOW trả về thời gian hiện tại theo múi giờ địa phương của máy chủ (docs).

Bạn có thể muốn một cái gì đó như UTC_TIMESTAMP trả về thời gian hiện tại ở UTC (docs).

Ngoài ra - có thể bạn không nên chấp nhận bất kỳ thời gian nhập nào từ JavaScript của khách hàng chút nào. Chỉ tin tưởng đồng hồ của riêng bạn. Khi đặt giá thầu, hãy sử dụng thời gian trên máy chủ của bạn bằng MySQL hoặc bằng PHP. Không chấp nhận nó làm đầu vào.