Làm cách nào để xử lý múi giờ trong ứng dụng web của tôi?


105

Tôi đang tìm cách hiểu rõ hơn về câu chuyện người dùng sau:

John làm việc ở Sidney. Vào lúc 9:00 sáng, anh ấy ghi lại một sự kiện trong một ứng dụng web chạy trên máy chủ ở Zurich. Ngày hôm sau, anh ấy đến New York cho một cuộc họp khẩn cấp, trong đó sự kiện sẽ được thảo luận. Trong cuộc họp, anh ta tìm kiếm sự kiện theo ngày và giờ.

Theo tôi thấy, có ít nhất hai vấn đề ở đây:

  1. Làm cách nào để lưu dấu thời gian trong cơ sở dữ liệu
  2. Tôi nên trình bày chúng như thế nào trong giao diện người dùng

Khi John tìm kiếm sự kiện, anh ấy sẽ biết rằng nó xảy ra lúc 9:00 nhưng anh ấy nên nhập gì vào trình duyệt web? Anh ấy sẽ không tìm thấy bất cứ điều gì khi anh ấy chỉ nhập "9:00" làm dấu thời gian vì đó có thể là giờ Zurich hoặc New York (vì sự kiện chưa được tìm thấy, ứng dụng không có cách nào để biết rằng nó đã xảy ra ở Sidney, vì vậy nó không thể tự động chọn múi giờ chính xác).

Cách tốt để hỏi người dùng về dấu thời gian có thể bao gồm múi giờ là gì?

Vấn đề thứ hai là cách hiển thị kết quả. Nếu các đội từ khắp nơi trên thế giới cần thảo luận về sự kiện (và tìm các sự kiện liên quan, hãy nghĩ đến một cuộc tấn công bẻ khóa nhắm vào một số trang web trên toàn cầu cùng một lúc).

Ví dụ tốt để hiển thị dấu thời gian có thể đã được tạo ở một múi giờ khác là gì?

Lưu ý: Hãy tập trung vào khả năng sử dụng của yêu cầu. Tôi có thể tự tìm ra ánh xạ cơ sở dữ liệu. Hiện tại, tôi không chắc về quy trình công việc. Nó sẽ hỏi / trình bày thông tin cần thiết theo cách trực quan / không xâm phạm. Nếu bạn có thể, hãy cung cấp một liên kết đến một ứng dụng web hiện có đã giải quyết được vấn đề này.


5
Stack Overflow giải quyết vấn đề này bằng cách đưa mọi thứ vào UTC. Không phải lúc nào cũng thuận tiện, nhưng nó chắc chắn rõ ràng, không khó thực hiện và hoạt động.
Ry-

2
UTC rất hấp dẫn nhưng OTOH, SO không bao giờ cần phải đồng bộ hóa các sự kiện qua nhiều múi giờ.
Aaron Digulla

3
Điều gì sẽ xảy ra nếu một trong các quốc gia liên quan ban hành luật thay đổi giờ địa phương sau khi sự kiện được lên lịch, nhưng trước khi sự kiện diễn ra? Hệ thống nên xử lý điều này như thế nào? vi.wikipedia.org/wiki/…
Julius Musseau

1
Loại câu hỏi về múi giờ cổ điển này đã bị đánh bại trong nhiều thập kỷ qua internet và in ấn, tôi ngạc nhiên khi thấy đầu vào sống động và tiền thưởng cho câu hỏi này!
BenSwayne

2
Tôi bổ sung thêm một điểm phức tạp bằng cách chỉ ra điều hiển nhiên, cụ thể là hầu hết Thế giới phương Tây thay đổi múi giờ hai lần một năm ("Giờ tiết kiệm ánh sáng ban ngày") và các quy tắc về thời điểm điều này xảy ra không đồng nhất trên toàn cầu cũng như không nhất thiết tầm thường, nói theo thuật toán?
fr13

Câu trả lời:


98

Vấn đề lưu trữ dấu thời gian rất đơn giản: Lưu trữ chúng ở UTC.

Đối với việc hiển thị chúng, sẽ hợp lý nếu bạn sử dụng cài đặt múi giờ của thiết bị và sử dụng nó làm múi giờ hiện tại. Điều đó có nghĩa là, sẽ có một menu thả xuống múi giờ bên cạnh hộp "nhập thời gian", mặc định cho múi giờ hiện tại của thiết bị, vì vậy người dùng có thể thay đổi nếu cần.

Đa số người dùng của bạn có thể sẽ không thay đổi múi giờ nhiều hoặc ít thay đổi. Phần lớn, tình huống bạn nêu ra là không phổ biến. Bằng cách triển khai danh sách thả xuống với một mặc định phù hợp, bạn sẽ có thể làm cho mọi thứ trở nên dễ dàng đối với những người hay di chuyển (bởi vì họ thường hiểu rõ hơn về múi giờ so với những người không phải là khách du lịch).

Trên thực tế, tốt hơn hết là bạn nên lưu múi giờ mà thiết bị được đặt thành khi ứng dụng của bạn được chạy lần đầu tiên và sau đó xem nó có bao giờ thay đổi hay không. Nếu nó thay đổi, thì người dùng có thể là khách du lịch và có thể sẽ được hưởng lợi từ việc thả xuống múi giờ. Nếu không, chỉ cần không hiển thị menu thả xuống và mặc định thành múi giờ của thiết bị (vì người dùng không cần biết về chúng). Trong cả hai trường hợp, có một cài đặt trong ứng dụng cho phép người dùng hiển thị / ẩn trình đơn thả xuống múi giờ theo cách thủ công.


Tóm tắt những điều trên:

  • Trong lần chạy đầu tiên, hãy lưu múi giờ mà thiết bị được đặt.
  • Sử dụng múi giờ đó làm múi giờ mặc định. Luôn giả định rằng múi giờ.
  • Nếu thiết bị chuyển đổi múi giờ, hãy thêm menu thả xuống để chọn múi giờ diễn ra sự kiện, mặc định là múi giờ của chính thiết bị.
  • Thêm tùy chọn để hiển thị / ẩn trình đơn thả xuống múi giờ này theo cách thủ công.
  • Luôn lưu trữ dấu thời gian ở UTC.

Chúng tôi có nghĩa là gì bởi "múi giờ" Nó có vẻ được sử dụng một cách mơ hồ. Điều này trông giống như một tài liệu tham khảo: en.wikipedia.org/wiki/Tz_database Từ những gì tôi có thể cho biết "múi giờ" là "Khu vực / Vị trí", ví dụ: "Mỹ / New_York". Điều đó có vẻ là về mặt địa lý, điều này thật tuyệt vì ví dụ: America / Los_Angeles có nghĩa là CẢ PST và PDT tùy thuộc vào việc toàn cầu có đang hoạt động trong Giờ tiết kiệm ánh sáng ban ngày hay không. Và nếu đúng như vậy, câu hỏi đặt ra là chúng ta làm cách nào để tính toán những thay đổi hai năm một lần trong thời gian bù giờ UTC cho các khu vực? Ngoài ra, chúng ta gọi những lời kêu gọi đó là gì vì chúng không phải là "khu vực" về mặt địa lý đúng không?
iJames

Đây là một câu trả lời tuyệt vời. Có phương pháp hay nhất về cách lưu trữ thông tin múi giờ không? Ví dụ - cái nào sẽ tốt hơn - 'PST' hay 'Châu Mỹ / Thái Bình Dương'? Làm cách nào để tôi có thể dễ dàng chuyển đổi dấu thời gian ở UTC sang múi giờ người dùng đã nắm bắt? Bất kỳ thực hành tốt nhất về điều này sẽ được đánh giá cao.
Patthebug

27

Trong các ứng dụng của chúng tôi, chúng tôi thường lưu trữ múi giờ của người dùng khi chúng tôi đăng ký lần đầu tiên, như thường thấy trên các trang diễn đàn và luôn hiển thị thời gian cùng với múi giờ .

Đối với việc lưu trữ ngày tháng, UTC là một cách để thực hiện. Chuyển đổi sang UTC và gắn nó vào cơ sở dữ liệu. Trong khi truy xuất, chỉ cần chuyển đổi thời gian thành múi giờ đã đặt cho người dùng.

Tôi đã phải giải quyết một trường hợp sử dụng tương tự, trong đó các thông báo tùy chỉnh, như "Chúc mừng năm mới", có thể được gửi tới tất cả người dùng ứng dụng web. Vì người dùng trải rộng trên toàn thế giới, chúng tôi cần hiển thị thông báo theo múi giờ. Lưu trữ dấu thời gian trong UTC phục vụ tốt mục đích của chúng tôi mà không gặp trục trặc.

Trong trường hợp sử dụng của bạn, nếu bạn không lưu trữ múi giờ của người dùng ở đâu đó, bạn sẽ không bao giờ có thể trả lại chính xác kết quả tìm kiếm của mình mà không yêu cầu người dùng nhập, trừ khi bạn bắt đầu sử dụng một số loại phát hiện vị trí như gmaps, nhưng đó là không ' t đáng tin cậy. Vì vậy, bạn sẽ cần hỏi múi giờ mọi lúc để đảm bảo người dùng biết những gì họ đang nhập vào trang web.

Nếu bạn có thông tin múi giờ, toàn bộ ứng dụng web sẽ được chạy với cài đặt múi giờ. Do đó, khi người dùng thực hiện tìm kiếm lúc 9:00, anh ta sẽ tìm kiếm theo múi giờ Sydney. Mặt khác, nếu anh ta tạo một sự kiện khi đang ngồi ở New York, anh ta sẽ tạo một sự kiện với múi giờ Sydney. Chúng tôi giải quyết những trường hợp như vậy bằng cách luôn hiển thị múi giờ trong khi hiển thị ngày tháng.

Hy vọng nó giúp! :)


Tôi nghĩ rằng với việc bổ sung trình đơn thả xuống cho các múi giờ khi tìm kiếm và tạo sự kiện, đây là cách để thực hiện. (khi tôi cần phải tìm kiếm các sự kiện tạo ra bởi đồng nghiệp ở New York, tôi không muốn làm toán bản thân mình)
RasmusWL

Đây là một câu trả lời tuyệt vời. Có phương pháp hay nhất về cách lưu trữ thông tin múi giờ không? Ví dụ - cái nào sẽ tốt hơn - 'PST' hay 'Châu Mỹ / Thái Bình Dương'? Làm cách nào để tôi có thể dễ dàng chuyển đổi dấu thời gian ở UTC sang múi giờ người dùng đã nắm bắt? Bất kỳ thực hành tốt nhất về điều này sẽ được đánh giá cao.
Patthebug

11
  1. UTC. Giữ nó đơn giản.

  2. Sử dụng múi giờ phù hợp nhất với người dùng.

    Nếu bạn biết người dùng sẽ đến hoặc đi du lịch đến Sydney để tham dự sự kiện, thì họ sẽ nghĩ đến múi giờ đó khi sắp xếp phương tiện di chuyển đến sự kiện. Thực tế là họ hiện đang ở New York phần lớn không liên quan. Và tất nhiên, nếu ứng dụng của bạn hiển thị ngày ở nhiều múi giờ khác nhau, ứng dụng phải luôn hiển thị múi giờ bên cạnh ngày, ví dụ: 09:00 EST .

    Nếu nó không làm rối giao diện của bạn quá nhiều, bạn có thể hiển thị ngày trong múi giờ sự kiện và múi giờ địa phương, ví dụ: 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Tôi cho rằng tìm kiếm cũng là một vấn đề tương tự, với một lưu ý: chúng ta có thể chấp nhận được kết quả dương tính giả (nhận được kết quả mà chúng ta không mong đợi), nhưng chúng ta không thể chịu được âm tính giả (không nhận được kết quả mà chúng ta mong đợi).

    Một lần nữa, tôi muốn tập trung vào việc tìm kiếm múi giờ phù hợp nhất với người dùng (ví dụ: múi giờ sự kiện) và ưu tiên các kết quả này trong kết quả tìm kiếm, nhưng bạn cũng có thể trả về các sự kiện phù hợp trong các múi giờ khác có liên quan đến người dùng (ví dụ: giờ địa phương). Nếu bạn làm điều này, bạn sẽ hiển thị ngày diễn ra sự kiện trong múi giờ phù hợp, đặc biệt nếu bạn đánh dấu văn bản phù hợp.


7

Ở đây, tôi đang đưa ra các đề xuất về khả năng sử dụng tốt nhất mà không cần bận tâm nhiều về tính khả thi khi triển khai.
1. Đối với vấn đề đầu tiên về việc lưu trữ các sự kiện trong db, mọi người sẽ đồng ý lưu trữ nó ở UTC

2. Để mang lại trải nghiệm người dùng tốt nhất, hãy lưu lịch sử múi giờ của người dùng. Nếu bạn có thể lưu dấu thời gian của sự thay đổi múi giờ, thậm chí còn tốt hơn. Điều này sẽ cho phép chúng tôi cho phép người dùng tự do truy vấn mà không cần chỉ định múi giờ rõ ràng mỗi lần.

Vì vậy, với các tính năng này, hãy xem truy vấn tìm kiếm chỉ "9,00" của John sẽ được xử lý như thế nào:
Với các tính năng đã đề cập ở trên, bây giờ tôi biết rằng John đã ở trong 2 múi giờ cho đến nay (hoặc nhận danh sách múi giờ cho khoảng thời gian đã đề cập). Vì vậy, tôi sẽ ẩn 9 giờ từ múi giờ Sydney đến UTC, thực hiện một truy vấn. Đồng thời chuyển đổi 9,00 từ múi giờ NewYork sang UTC, kích hoạt một truy vấn. Do đó, tôi sẽ hiển thị 2 hàng cho John hiển thị những gì anh ấy đã làm lúc 9.00 ở sydney và 9.00 ở new york. Dòng New york sẽ trống trong trường hợp này, nhưng tôi nghĩ vẫn nên hiển thị cho người dùng, chỉ để thông báo cho anh ta rằng chúng tôi cũng đã tìm kiếm múi giờ này.

3. Cách tốt để hỏi người dùng về dấu thời gian có thể bao gồm múi giờ là gì?

Nếu múi giờ của anh ấy gần đây bị thay đổi, bất cứ khi nào anh ấy đăng nhập ứng dụng, sẽ nhận được thông báo rằng, múi giờ mặc định của bạn sẽ được thay đổi thành múi giờ gốc.
Trong khi tạo sự kiện, giả sử người dùng chọn múi giờ từ menu thả xuống, đừng gây gánh nặng cho người dùng bằng cách đưa ra các tùy chọn của tất cả các múi giờ trên thế giới. Tùy chọn đầu tiên của menu thả xuống phải là múi giờ hiện tại của thiết bị của người dùng. sau các múi giờ đó từ lịch sử múi giờ của anh ấy, rồi đến UTC và sau đó là các múi giờ còn lại mà anh ấy chưa bao giờ sử dụng cho đến nay.

4.Cách hiển thị kết quả, nếu các đội từ khắp nơi trên thế giới cần thảo luận về sự kiện:

Tôi muốn chia trường hợp sử dụng này cho số đội 2 hoặc nhiều hơn 2.
Đối với chỉ 2 đội, tôi muốn mỗi đội nhìn thấy dấu thời gian trong múi giờ địa phương của mình và múi giờ của đội khác. (Cá nhân tôi thích nói chuyện theo múi giờ của người ở đầu bên kia để thuận tiện cho anh ta trong khi lên lịch họp). Đối với nhiều hơn 2 đội, tốt hơn hết là bạn nên xem xét múi giờ chung hơn tức là UTC. Vì vậy, trong trường hợp này, mọi người dùng sẽ thấy dấu thời gian trong 2 múi giờ, theo UTC và theo múi giờ mặc định của mình.

Đề xuất này được đưa ra với ý định rằng người dùng không cần thực hiện bất kỳ phép tính nào theo giờ địa phương của mình nhưng đồng thời anh ta sẽ có thể giao tiếp với những người dùng khác một cách trôi chảy trong múi giờ ưa thích của họ.


2
+1 Đây là một ý tưởng rất thú vị bởi vì tôi biết rằng người dùng đã tham gia một sự kiện lúc 9:00 ở Sidney, vì vậy khi cùng một người dùng tìm kiếm một thời gian (không có múi giờ rõ ràng), tôi nên cho rằng anh ấy có nghĩa là "tôi đã ở đâu thời gian đó "
Aaron Digulla

4

Được rồi, tôi có một cách tiếp cận khác với những người khác:

Thứ nhất, tôi đã giả định một vài thứ trước đó.

Người đang liệt kê một sự kiện có điện thoại thông minh (nếu đó là trình duyệt, tôi không phải đưa ra những giả định này) với:

  1. GPS

  2. Khả năng HTML5.

  3. Khả năng Javascript

Làm cách nào để lưu các dấu thời gian trong cơ sở dữ liệu?

Giải pháp: Rõ ràng là UTC , tôi đã phủ lên quy trình bên dưới:

Bước 1. Sử dụng Vị trí địa lý của người dùng bằng API Vị trí địa lý

    window.onload = getMyLocation;

    function getMyLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(displayLocation);
        } else {
            alert("Oops, no geolocation support");
        }
    }

    function displayLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var div = document.getElementById("location");
        div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    }

Bước 2. Đưa ra (Dài, Vĩ độ) làm đối số cho một số api (Vĩ độ, Kinh độ) cho TimeZone như Yahoo API Vĩ độ (Vĩ độ, Kinh độ (sử dụng Flag R để chuyển đổi Latitude thành Múi giờ) để lấy múi giờ của người dùng.

=> Múi giờ của người dùng được xác định mà không cần người dùng nhập (Tôi đang sử dụng cái này vì bạn không thể đơn giản cho rằng người dùng biết múi giờ của nơi anh ta sinh sống, tôi đã biết múi giờ của mình chỉ sau vài tháng hoặc tại nơi đó: P, khá ngớ ngẩn! )

Bảng mỗi sự kiện có Timezone, Eventvà như vậy cũng có thể đã CityName Sau đó tạo một bảng cơ sở dữ liệu với phân loại dựa trên CityNames. Vì vậy, ở đây người dùng sẽ có hai cột

|---------------------------------------|
|_____NewYork________|______Sydney______|
|                    |                  |
|Event 1             |  Event 2         |
|____________________|__________________| 

Đối với giao diện người dùng

=> sử dụng API Lịch Google hoặc một số API Lịch

Bài đọc liên quan:

  1. Xác định múi giờ từ vĩ độ / kinh độ mà không cần sử dụng các dịch vụ web như Geonames.org

  2. Tra cứu múi giờ từ kinh độ vĩ độ

Tôi biết nó chỉ là chỉ ra một số ý tưởng làm thế nào để giải quyết vấn đề này. Nhưng hãy xem nó trở nên chính xác và nhẹ nhàng đến mức nào đối với người dùng khi Múi giờ được xác định bằng cách sử dụng API thiết bị

Hy vọng nó giúp!


4
Khá dễ dàng để tìm múi giờ của ai đó mà không cần định vị địa lý. new Date().getTimezoneOffset()cung cấp cho nó trong vài phút sau UTC.
Ry-

@minitech, điều đó đúng nhưng điều gì sẽ xảy ra nếu sự kiện đang diễn ra ở NewYork và một nơi nào đó phía Nam có cùng múi giờ. Tôi đang sử dụng Vị trí địa lý để bạn có thể xác định chính xác Thành phố (thậm chí chính xác), Múi giờ trong ảnh chụp và dựa vào bảng db của tôi. Tôi muốn giảm thiểu đầu vào của người dùng bằng api thiết bị để tăng hiệu quả của ứng dụng.
Uday

Vì thế? Thời gian sẽ giống nhau ở cả hai nơi, vì vậy không có vấn đề gì. -1
Ry-

@minitech, bạn có thể xem liên kết này về lý do tại sao tôi khuyên bạn nên sử dụng api của thiết bị hơn các phương pháp khác. webdirections.org/sotmw2011
uday

2
Được rồi, nhưng vấn đề ở đây không phải là lấy thành phố của người dùng. Nó chỉ là về việc nhận được múi giờ. Sử dụng API định vị địa lý không hoạt động trên mọi trình duyệt / máy tính, sau đó chuyển hướng đến API lịch, là một cách không tốt để lấy múi giờ của người dùng khi múi giờ đó có sẵn trong một dòng mã.
Ry-

2

Đối với trường hợp cụ thể đó, tôi sẽ lưu trữ cả hai thời gian địa phương và UTC. UTC là một phần lớn và được sử dụng để đồng bộ hóa và chuyển đổi thời gian sang múi giờ hiện tại. Địa phương được sử dụng để tìm kiếm và để biết thêm thông tin, như:

Bạn có một cuộc họp:

12:00 Monday (UTC)
9:00 Monday (Sydney, creation local time)
11:00 Monday (Zurich, local time)

hoặc điều tương tự. Cách khác là lưu trữ múi giờ tạo và chuyển đổi trong thời gian chạy (điều này đặc biệt tốt hơn trong trường hợp người dùng thay đổi thời gian họp). Dù thế nào thì lý do chính là có thể khôi phục lại thời gian tạo ban đầu để người dùng có thể tham khảo.


2
  1. Làm cách nào để lưu dấu thời gian trong cơ sở dữ liệu

Khi tạo sự kiện, tôi sẽ lưu trữ giờ UTC và múi giờ địa phương (hay còn gọi là creation time zone). Tôi sẽ sử dụng những gì tôi đã lưu trữ để chuyển đổi giờ UTC thành giờ địa phương (hay còn gọi là creation time) và lưu trữ nó cùng với giờ UTC vàcreation time zone .

LƯU Ý: Tôi có thể lưu trữ giờ địa phương ngay từ khi bắt đầu, nhưng khi người dùng thực hiện tìm kiếm một sự kiện, tôi hy vọng sẽ tồn tại chuyển đổi sang giờ địa phương. Tôi cũng hy vọng máy chủ có thể phát hiện ra máy khách đang ở múi giờ nào.

  1. Tôi nên trình bày chúng như thế nào trong giao diện người dùng

Khi người dùng tìm kiếm "9:00", tôi sẽ tìm kiếm các sự kiện bao gồm "9:00" theo giờ UTC HOẶC creation time HOẶC giờ địa phương. Đối với kết quả, tôi sẽ hiển thị một bảng kết quả trong creation time(Bảng này nhằm mục đích hiển thị dấu thời gian có thể đã được tạo ở một múi giờ khác, vì chúng tôi giả sử người dùng đang tìm kiếm thời gian họ tạo sự kiện ở bất kỳ đâu.) và hiển thị bảng kết quả thứ hai bên dưới với các kết quả có liên quan, có lẽ với tiêu đề "Không phải thứ bạn đang tìm kiếm? Hãy xem kết quả liên quan" (những kết quả này bao gồm kết quả UTC và giờ địa phương còn sót lại).

Nhìn chung, tôi sẽ hiển thị giờ UTC, giờ địa phương creation time, và creation time zone(tức là giờ địa phương và múi giờ của sự kiện nơi nó được tạo) được sắp xếp theo giờ UTC, vì vậy bạn có thể xem sự kiện nào đến trước, trong trường hợp hai sự kiện khác nhau các sự kiện đã được lên lịch vào 9:00 ở hai múi giờ khác nhau.


1
+1 Tôi thích ý tưởng hiển thị tất cả các sự kiện ở tất cả các múi giờ mà giờ địa phương khớp với nhau; Tôi chỉ không hài lòng với SQL ( BETWEENđiều kiện 24x ).
Aaron Digulla
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.