Tại sao Unix lưu trữ dấu thời gian trong một số nguyên đã ký?


24

Tại sao một số nguyên đã ký được sử dụng để biểu thị dấu thời gian? Có một sự khởi đầu được xác định rõ ràng vào năm 1970 được biểu thị bằng 0, vậy tại sao chúng ta lại cần số trước đó? Là dấu thời gian tiêu cực được sử dụng bất cứ nơi nào?


2
Đó là lý do tại sao Nostradamus không thể sử dụng máy tính của mình để viết dự đoán của mình cho những năm 3000 + ... nó sẽ gây ra tràn và hiển thị ngày của anh ta là âm. Tôi nghĩ rằng họ gọi nó là lỗi Y3K hoặc một cái gì đó!
Jeach

3
Người La Mã cổ đại có một vấn đề thậm chí còn tồi tệ hơn khi số năm chuyển từ tiêu cực sang tích cực. Họ sẽ gọi đó là vấn đề Y0K nếu họ có cách thể hiện số 0. 8-)}
Keith Thompson

Câu trả lời:


35

Các phiên bản đầu của C không có số nguyên không dấu. (Một số lập trình viên đã sử dụng con trỏ khi họ cần số học không dấu.) Tôi không biết cái nào xuất hiện trước, kiểu time()hàm hoặc kiểu không dấu, nhưng tôi nghi ngờ biểu diễn được thiết lập trước khi loại không dấu có sẵn trên toàn cầu. Và năm 2038 là đủ xa trong tương lai mà có lẽ nó không đáng lo ngại. Tôi nghi ngờ rằng nhiều người nghĩ rằng Unix vẫn sẽ tồn tại trước đó.

Một ưu điểm khác của việc ký kết time_tlà việc mở rộng nó lên 64 bit (điều này đã xảy ra trên một số hệ thống) cho phép bạn đại diện cho thời gian vài trăm tỷ năm trong tương lai mà không mất khả năng đại diện cho thời gian trước năm 1970. (Đó là lý do tại sao tôi phản đối việc chuyển sang 32-bit chưa được ký time_t , chúng ta có đủ thời gian để chuyển đổi sang 64 bit).


7
Các timechức năng là lớn tuổi hơn thời đại: Unix v1 (năm 1971) tính theo đơn vị 1 / 60th của một giây, từ nửa đêm ngày 1971/1/1. Nó đã là một lỗi được biết rằng “thời gian - sử dụng đầu óc sẽ lưu ý rằng 2 ** 32/60 của asecond chỉ khoảng 2,5 năm.” unsigned Đã được giới thiệu bởi K & R vào năm 1978 , cũng sau khi kỷ nguyên 1970 được thành lập.
Gilles 'SO- ngừng trở nên xấu xa'

Tôi đã làm một bài kiểm tra nhanh và trên hộp linux 64 bit của mình. gmtimelocaltimetối đa trong năm 2147483647 (với giây tiếp theo sau khi cho -2147483648 là năm). Vì vậy, để có được 55 bit thời gian, ai đó sẽ phải cập nhật thói quen đầu ra để sử dụng int 64 bit trong năm thay vì int 32 bit không dấu. Hy vọng ai đó sẽ chăm sóc con bọ đó đôi khi trong vài tỷ năm tới.
freiheit

@freiheit: Thú vị. Vấn đề ở đây là struct tmloại này có một thành viên tm_year(đại diện cho những năm kể từ năm 1900) là loại int. Các hệ thống 64 bit có thể dễ dàng có 64 bit time_t, nhưng chúng thường có 32 bit int. (Nếu charlà 8 bit và intlà 64 bit, thì shortcó thể là 16 hoặc 32 bit và sẽ không có loại được xác định trước cho kích thước khác.) Nhưng time()có lẽ là chức năng duy nhất trong <time.h>đó thực sự cần hỗ trợ ở cấp hệ thống; bạn có thể viết mã của riêng mình để chuyển đổi time_tgiá trị thành chuỗi có thể đọc được.
Keith Thompson

12

Đó là để hỗ trợ dấu thời gian và ngày trước ngày 1 tháng 1 năm 1970.


1
Điều này làm cho chỉ 68 năm trong quá khứ - 1902. Điều này có vẻ khá ít.
Bakudan

2
POSIX không yêu cầu time_tchỉ có 32 bit; Nó đã có 64 bit trên nhiều hệ thống.
Keith Thompson

1
mktime()Hàm trả về -1trong trường hợp có lỗi nên có thể không phân biệt được dấu thời gian chính xác trước 1970-01-01 và lỗi ts. Ngày rõ ràng trước ngày 1970-01-01 bị cấm
DimG

@DimG: Thật khó để phân biệt lỗi và dấu thời gian cụ thể 1969-12-31 23:59:59 UTC. Một giá trị âm khác hơn -1là không rõ ràng.
Keith Thompson

1
@mtraceur: Tiêu chuẩn C không yêu cầu mktime()đặt cuộc gọi thất bại errno. (POSIX nào.)
Keith Thompson
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.