2009-04-17 66 views
27

Cách tốt nhất để chuyển đổi thời gian biểu giữa giờ địa phương và UTC bằng C/C++ là gì?Chuyển đổi giữa giờ địa phương và GMT/UTC bằng C/C++

Bởi "datetime", tôi có nghĩa là một số đại diện thời gian có chứa ngày và thời gian trong ngày. Tôi sẽ hài lòng với time_t, struct tm hoặc bất kỳ đại diện nào khác có thể làm được điều đó.

Nền tảng của tôi là Linux.

Đây là vấn đề cụ thể tôi đang cố gắng giải quyết: Tôi nhận được một cặp giá trị chứa ngày tháng julian và một số giây vào ngày. Các giá trị đó tính bằng GMT. Tôi cần chuyển nó thành giá trị "YYYYMMDDHHMMSS" theo múi giờ địa phương. Tôi biết cách chuyển đổi ngày tháng julian thành Y-M-D, và rõ ràng là rất dễ dàng để chuyển đổi số giây thành HHMMSS. Tuy nhiên, phần khó khăn là chuyển đổi múi giờ. Tôi chắc chắn rằng tôi có thể tìm ra một giải pháp, nhưng tôi muốn tìm một cách "tiêu chuẩn" hoặc "nổi tiếng" hơn là vấp ngã.


Một câu hỏi có thể có liên quan là Get Daylight Saving Transition Dates For Time Zones in C

Trả lời

21

Bạn đang phải sử dụng sự kết hợp của gmtime/localtimetimegm/mktime. Điều đó sẽ cung cấp cho bạn công cụ trực giao để thực hiện chuyển đổi giữa struct tmtime_t.

Đối với UTC/GMT:

time_t t; 
struct tm tm; 
struct tm * tmp; 
... 
t = timegm(&tm); 
... 
tmp = gmtime(t); 

Đối localtime:

t = mktime(&tm); 
... 
tmp = localtime(t); 

Tất cả tzset() làm là đặt biến múi giờ nội bộ từ biến TZ môi trường. Tôi không nghĩ rằng điều này được cho là được gọi nhiều hơn một lần.

Nếu bạn đang cố gắng chuyển đổi giữa các múi giờ, bạn nên sửa đổi của struct tm.

+0

Cảm ơn! Tôi biết một cái gì đó như timegm() đã tồn tại, nhưng không biết tên. –

+0

Rất vui được trợ giúp. Thời gian chuyển đổi có thể là một khu vực khá phức tạp. Nó thường là một ý tưởng tốt để lưu trữ tất cả mọi thứ trong UTC bất cứ khi nào có thể. Chuyển đổi giữa các múi giờ thậm chí còn phức tạp hơn! –

+1

Vâng, rất tiếc, các nhà thiết kế của hệ thống đã chọn thời gian địa phương làm định dạng dấu thời gian "chuẩn" cho giao thức nhắn tin. Tôi ghét nó khi mọi người làm điều đó. –

2

Nếu bạn cần phải lo lắng về việc chuyển đổi ngày/giờ với quy tắc múi giờ, bạn có thể muốn xem xét ICU.

17

Nếu trên Windows, bạn không cần phải timegm() có sẵn cho bạn:

struct tm *tptr; 
time_t secs, local_secs, gmt_secs; 
time(&secs); // Current time in GMT 
// Remember that localtime/gmtime overwrite same location 
tptr = localtime(&secs); 
local_secs = mktime(tptr); 
tptr = gmtime(&secs); 
gmt_secs = mktime(tptr); 
long diff_secs = long(local_secs - gmt_secs); 

hoặc một cái gì đó tương tự ...

+0

Không nên' secs' và 'gmt_secs' giống hệt nhau? Tôi nghĩ bạn có thể đơn giản hóa Điều này khá một chút – jowo

+1

Tôi đã cố gắng để xác minh nó bằng cách thử nghiệm kết quả chống lại nghịch đảo.Đối với một số lần nó hoạt động, và cho những người khác, nó là tắt bởi một giờ.Tôi đoán đó là bởi vì DST bắt đầu và dừng lại tại các địa điểm khác nhau ở các địa điểm khác nhau mà tôi đang cố gắng (sử dụng GMT, nhưng chuyển đổi theo giờ địa phương PST) Có cách nào để bù đắp cho điều đó không? –

+1

Phiên bản này, sử dụng thư viện thời gian Boost POSIX, dường như hoạt động mặc dù các ngày DST khác nhau trên các múi giờ: http://stackoverflow.com/a/6849810/857029. –

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