Time offset là gì

Đối với các project mà có xu hướng phát triển ra quốc tế [vận hành không chỉ trong 1 nước], thì vấn đề liên quan time zone có thể nói khá quan trọng.
TimeZone sẽ ảnh hưởng đến việc thống kê, phân tích dữ liệu trong ngày.

Ví dụ như có 1 trang thương mại điện tử A được sử dụng ở cả Việt Nam [GMT +7] và Nhật Bản [GMT +9].
Admin ở Việt Nam thì sẽ mong muốn thống kê được số lượng Order được tạo trong ngày [theo múi giờ Việt Nam]
Admin ở Nhật thì sẽ mong muốn thống kê được số lượng Order được tạo trong ngày [theo múi giờ Nhật]

Đây là 1 cách suy nghĩ hoàn toàn tự nhiên. Tuy nhiên trong đại đa số các trường hợp, developer thường không để ý đến vấn đề TimeZone này [thường sử dụng luôn timezone trong default config của project] → Sẽ có khả năng xảy ra thông kê sai lệch

→ Đối với Shop, sự thống kê sai lệch có thể gây ra sự phán đoán sai lầm và sự điều chỉnh chiến thuật hay chiến lược bán hàng

Do đó, có thể nói đây là 1 vấn đề khá quan trọng mà trong khi phát triển dịch vụ, mỗi developer nên chú ý tới.

Hiện tại mình cũng đang gặp vấn đề như trên trong project hiện tại nên tiện thể cũng tìm hiểu qua về các khái niệm và cách thức giải quyết vấn đề này [trong Ruby và Rails]

TimeZone là gì?

Đây mà 1 khái niệm mà chắc hẳn developer ai cũng đã từng nghe qua 1 lần.

Time zone is a region where the same standard time is used.
  • Giải thích 1 cách đơn giản hơn: Thế giới chia ra làm 24 múi giờ dựa theo kinh độ, mỗi múi giờ sẽ tương ứng với 1 time zone. Có nghĩa là mỗi 1 timezone sẽ trải dài với 15 độ kinh độ. Mốc 0 được lấy tại đường kinh độ 0 độ đi qua London, Anh.

  • Danh sách database của timezone, các bạn có thể tham khảo tại link này

Các class liên quan đến time trong Ruby và Rails

Ruby

Ruby cung cấp các class sau để xử lý vấn đề thời gian.

Nhìn vào tên 3 class mà Ruby cung cấp ở trên, ta có thể thấy ngay sự khác biệt giữa Time, DateTime với Date.
Thế còn Time và DateTime khác nhau thế nào?

  • Time:

    • Tốc độ xử lý nhanh, phụ thuộc vào thời gian UNIX [khi init thì lấy default timezone trong máy]
    • Ruby v1.9.2 trở về trước, tồn tại vấn đề Year 2038
    • Xử lý được summer time, hay còn gọi là daylight saving time
  • DateTime:

    • Tốc độ xử lý chậm so với Time.
    • Không phụ thuộc vào thời gian UNIX → có thể hiển thị thời gian 1 cách mềm dẻo, linh hoạt.

Rails

Rails cung cấp class ActiveSupport::TimeWithZone để lưu time với time zone.
Khi tạo 1 dòng mới với các cột có type là datetime, trong DB sẽ mặc định lưu dưới time zone là UTC +0.
Tuy nhiên, khi lấy giá trị đó ra thì giá trị datetime ấy sẽ tự động được tính toán chuyển sang time zone tương ứng với setting trong application.rb.

【config/application.rb】 config.time_zone = 'Asia/Tokyo' 【Rails console】 blog = Blog.create blog.created_at => Sun, 24 Dec 2017 17:20:15 JST +09:00 blog.created_at_before_type_cast => 2017-12-24 08:20:15 UTC

Cách giải quyết vấn đề đặt ra

Trong trường hợp đặt ra ở trên, để có thể giúp AdminUser tại mỗi 1 địa điểm khác nhau thống kê được chính xác theo time_zone tương ứng thì cần phải xác định được time_zone cho mỗi user chứ không sử dụng time_zone default được setting trong application.rb
Có 2 cách để xác định điều này:

  • Lưu time_zone theo từng admin_user. Khi admin_user
  • Khi admin_user access vào thì sử dụng javascript bên phía client để lấy thông tin timezone và gửi như 1 param lên server. Server sẽ sử dụng params time_zone được gửi lên ấy và xử lý lấy dữ liệu dựa trên param này. Các bạn có thể tham khảo cách lấy time_zone qua javascript.

Note

1 điều cần chú ý khi cách generate sql để lấy data từ database ra bằng ActiveRecord với điều kiện so sánh là kiểu datetime trong câu lệnh where
Giả sử có model User với created_at.
Ta muốn lấy tất cả các users được tạo từ 12:00 21/12/2017 GMT +9 chẳng hạn.
Có 2 kiểu viết như sau:

User.where["created_at > #{Time.parse['2017-12-21 12:00']}"] → SELECT `users`.* FROM `users` WHERE [created_at > 2017-12-21 12:00:00 +0900]

User.where["created_at > ?", Time.parse['2017-12-21 12:00']] → SELECT `users`.* FROM `users` WHERE [created_at > '2017-12-21 03:00:00']

Nhìn vào câu lệnh sql được generate ra ở phía trên, chúng ta có thể thấy:

  • Cách 1: biến time truyền vào trong câu lệnh where thì time sẽ không được chuyển time ở UTC+0 mà vẫn bị giữ nguyên time tại UTC+9 để so sánh với giá trị created_at [UTC+0] → kết quả sẽ sai lệch
  • Cách 2: Giá trị của biến time được tự động chuyển về UTC+0 và được so sánh với created_at [UTC +0] → đưa ra kết quả đúng.

Đây chỉ là 1 điều cần lưu ý nhỏ khi mà thực hiện phép truy vấn với dữ liệu datetime bằng ActiveRecord.

Hi vọng bài này có ích cho anh chị em. :]

Cùng một tác giả

18 2

Xin thân chào các thí chủ. Bần tăng lại trở lại và ăn hại gấp n lần. Dạo gần đây nhìn vào khuynh hướng tìm hiểu tech của thiên hạ, vẫn như mọi kh...

15 3

Sau 1 thời gian hơi sấp mặt 1 chút, bần tăng đã trở lại và ăn hại gấp n lần. Mở đầu Đối với các công ty cung cấp dịch vụ B2B, khách hàng là thượ...

11 6

Bần tăng, 1 dev Ruby đã có kinh nghiệm làm việc cho 1 công ty Nhật 2 năm. Trong 2 năm qua bần tăng đã học được rất nhiều điều mà bản thân ngày xưa ...

The UTC offset is the difference in hours and minutes between Coordinated Universal Time [UTC] and local solar time, at a particular place. This difference is expressed with respect to UTC and is generally shown in the format ±[hh]:[mm], ±[hh][mm], or ±[hh]. So if the time being described is two hours ahead of UTC [such as in Kigali, Rwanda [approx. 30° E]], the UTC offset would be "+02:00", "+0200", or simply "+02".

By convention, every inhabited place in the world has a UTC offset that is a multiple of 15 minutes but the majority of offsets are stated in whole hours. There are many cases where the national standard time uses a time zone that differs from the UTC offset appropriate to its longitude.

Main article: Time zone

 

World map of current time zones

A time zone is a geographical region in which residents observe the same standard time. Although nominally a new time zone is established every 15 degrees east or west of the prime meridian [meaning a one hour change in solar time], in practice local geographical or political considerations may vary its application. The most extreme example of this is time in China, which applies a single standard time offset of UTC+08:00 [eight hours ahead of Coordinated Universal Time], even though China spans five geographical time zones.

The UTC offset [or time offset] is an amount of time subtracted from or added to Coordinated Universal Time [UTC] time to specify the local solar time [which may not be the current civil time, whether it is standard time or daylight saving time].

Daylight saving time

Main articles: Daylight saving time, Standard time, and Civil time

Several regions of the world use daylight saving time [DST] and the UTC offset during this season is typically obtained by adding one hour to local standard time. Central European Time UTC+01:00 is replaced by Central European Summer Time UTC+02:00, and Pacific Standard Time UTC−08:00 is replaced by Pacific Daylight Time UTC−07:00.

Main article: List of UTC time offsets

These cities have been chosen for convenience because they are sufficiently near the equator so as not to use DST. Where possible, cities near 0°, 45°, 90° etc have been chosen to best illustrate offsetting.

Some example cities Location Longitude UTC offset When UTC time is 12:00,
local standard time is: When local time is 12:00,
UTC time is
Honolulu, USA 157° 51 W UTC-10:00 02:00 22:00
Quito, Ecuador 78° 30' W UTC-05:00 07:00 17:00
Accra, Ghana 0° 12' W UTC+00:00 12:00 12:00
Mogadishu, Somalia 45° 20′ E UTC+03:00 15:00 09:00
Dhaka, Bangladesh 90° 23′ E UTC+06:00 18:00 06:00
Alice Springs, Australia 133° 52′ E UTC+09:30 21:30 02:30
Suva, Fiji 178° 27′ E UTC+12:00 00:00 00:00
  • ISO 8601 – international standard for representing dates and times.
  • Time Service Dept., U.S. Naval Observatory

 

This standards- or measurement-related article is a stub. You can help Wikipedia by expanding it.

  • v
  • t
  • e

Retrieved from "//en.wikipedia.org/w/index.php?title=UTC_offset&oldid=1073598029"

Video liên quan

Chủ Đề