2011-12-19 11 views
11

Tôi đã thấy rất nhiều quan điểm khác nhau nên hãy nghĩ đến việc hỏi tại đây.mktime và tm_isdst

tôi đọc man mktime:

(A positive or zero value for tm_isdst causes mktime() to presume initially 
that summer time (for example, Daylight Saving Time) is or is not in 
effect for the specified time, respectively. A negative value for 
tm_isdst causes the mktime() function to attempt to divine whether summer 
time is in effect for the specified time. 

Câu hỏi của tôi là, không nên tm_isdst được giữ như -1 để cho hệ thống quyết định nếu dst của nó hay không và cách mà các mã trở nên dst thuyết bất khả tri?

Tôi có thiếu gì đó không?

Trả lời

5

Tôi tin rằng nguyên nhân ban đầu là do một số múi giờ không có thời gian tiết kiệm ánh sáng ban ngày. Vì mktime không an toàn và cũng không phải là entrant cho phép thực hiện lưu trữ giá trị hiện tại của tiết kiệm ánh sáng ban ngày trong POSIX extern char tzname [2], được lập chỉ mục bởi ánh sáng ban ngày [0 hoặc 1]. Điều này có nghĩa là tzname [0] = "[std TZ name]" và tzname = "[tên TZ ánh sáng ban ngày, ví dụ: EDT]"

Xem trang man tzset() của bạn để biết thêm thông tin về điều này. Các tiêu chuẩn tuân thủ mktime() là bắt buộc để hoạt động như thể nó được gọi là tzset(). Loại obviates việc sử dụng tm_isdst, IMO.

Điểm mấu chốt: triển khai và múi giờ cụ thể của bạn sẽ cho biết bạn có sử dụng -1, 0 hoặc 1 cho tm_isdst hay không. Không có cách nào chính xác mặc định cho mọi triển khai.

7

Bạn nên tránh đặt tm_isdst thành -1 nếu có thể. Hệ thống không phải lúc nào cũng có thể xác định trạng thái DST từ ngày và giờ. Đó là mơ hồ giờ trước và sau khi DST kết thúc. Ví dụ: nếu bạn vượt qua mktime() 1:30 SA ngày 4 tháng 11 năm 2012, thì không đủ thông tin để nhận được giá trị time_t chính xác từ mktime(). Thông thường tôi đã thấy mktime() giả định thời gian tiêu chuẩn trong trường hợp đó là mơ hồ, nhưng tôi đã không thấy bất kỳ tài liệu nào đảm bảo rằng hành vi trên tất cả các nền tảng. 1:30 sáng ngày 4 tháng 11 năm 2012 với tm_isdst == 1 sẽ là 1 giờ trước, vì giờ 1:00:00 đến 1:59:59 lặp lại.

#include <stdio.h> 
#include <time.h> 

int main() 
{ 
    time_t daylight, standard; 
    struct tm timestr; 
    double diff; 

    timestr.tm_year = 2012 - 1900; 
    timestr.tm_mon = 11 - 1; 
    timestr.tm_mday = 4; 
    timestr.tm_hour = 1; 
    timestr.tm_min = 30; 
    timestr.tm_sec = 0; 

    /* first with standard time */ 
    timestr.tm_isdst = 0; 
    standard = mktime(&timestr); 

    /* now with daylight time */ 
    timestr.tm_isdst = 1; 
    daylight = mktime(&timestr); 

    diff = difftime(standard, daylight); 

    printf("Difference is %f hour(s)", diff/60.0/60.0); 

    return 0; 
} 

này tạo ra:

Difference is 1.000000 hour(s) 

Cả hai đều là ngày 04 tháng 11 năm 2012 01:30, tuy nhiên cả hai đều là hai giá trị time_t riêng biệt, 1 giờ xa nhau.

mktime() về cơ bản có 2 kết quả đầu ra:

  • time_t
  • thời gian sửa chữa struct

Hiện struct là cả một đầu vào và đầu ra. Nó được sửa đổi bởi mktime() để trả về tất cả các thành viên cấu trúc theo phạm vi danh nghĩa. Ví dụ: nếu bạn tăng thành viên tm_hour += 500, điều đó có nghĩa là tăng thời gian thêm 500 giờ. Thành viên tm_hour sẽ được thay đổi thành giá trị từ 00 đến 59 và tm_day, tm_mday và tất cả sẽ được điều chỉnh cho phù hợp. tm_isdst cũng là cả đầu vào và đầu ra. giá trị của nó như sau:

  • 1 (DST có hiệu lực, ví dụ: điều chỉnh giờ)
  • 0 (DST không có hiệu lực, ví dụ:thời gian tiêu chuẩn)
  • -1 (tình trạng DST Unknown)

Vì vậy mktime() sẽ ra 1 hoặc 0 cho tm_isdst, không bao giờ -1.

-1 có thể là đầu vào, nhưng tôi nghĩ nó có nghĩa là "Không xác định". Đừng nghĩ rằng nó có nghĩa là "xác định tự động", bởi vì nói chung, mktime() không phải lúc nào cũng tự động xác định nó.

Trạng thái DST rõ ràng (0 hoặc 1) phải đến từ một thứ gì đó bên ngoài phần mềm, ví dụ như lưu trữ nó trong tệp hoặc cơ sở dữ liệu hoặc nhắc người dùng.

+2

Vâng, nếu bạn không biết DST, bạn cần xác định nó (may mắn với điều đó), hoặc đặt nó thành '-1'. Không có lựa chọn nào khác. Nếu bạn đặt nó là 0, bạn sẽ không nhận được DST ở tất cả những gì được bảo đảm sai, nếu bạn đặt nó thành 1, bạn buộc DST trên đó cũng được bảo đảm sai. – rustyx

+0

@RustyX Mã hóa cứng tới -1, 0 hoặc 1 sẽ luôn sai. -1 là ít nhất là xấu, nhưng vẫn còn xấu. Trạng thái rõ ràng (0 hoặc 1) phải là _input_ đối với phần mềm từ người dùng hoặc được lưu trữ trong dữ liệu (tệp hoặc cơ sở dữ liệu). Về cơ bản nó phải đến từ một cái gì đó bên ngoài ứng dụng. –

+0

v câu trả lời hay. Cảm ơn – drlolly