2009-11-08 74 views

Trả lời

36

Để có thời gian được biểu thị bằng UTC, hãy sử dụng GetSystemTime trong API Win32.

SYSTEMTIME st; 
GetSystemTime(&st); 

SYSTEMTIME được ghi chép lại như có những thành viên có liên quan:

WORD wYear; 
WORD wMonth; 
WORD wDayOfWeek; 
WORD wDay; 
WORD wHour; 
WORD wMinute; 
WORD wSecond; 
WORD wMilliseconds; 

Như shf301 helpfully chỉ ra dưới đây, GetLocalTime (với nguyên mẫu giống nhau) sẽ mang lại một thời gian điều chỉnh múi giờ hiện tại của người dùng.

Bạn có một vài câu trả lời hay ở đây, tùy thuộc vào những gì bạn đang theo dõi. Nếu bạn đang tìm kiếm chỉ thời gian trong ngày, câu trả lời của tôi là cách tiếp cận tốt nhất - nếu bạn cần ngày tháng vững chắc cho số học, hãy xem xét Alex's. Có a lot of ways to skin the time cat trên Windows và một số trong số đó chính xác hơn các loại khác (và chưa có ai đề cập đến QueryPerformanceCounter).

+5

Sử dụng GetLocalTime để có được thời gian và ngày mà người dùng sẽ thấy. http://msdn.microsoft.com/en-us/library/ms724338%28VS.85%29.aspx – shf301

+2

QueryPerformanceCounter ... Tôi nghĩ bạn có thể đang nói đùa, vì nó có nhiều hạn chế khiến nó trở nên tồi tệ lựa chọn ở đây. –

+1

@Heath: Vâng, xin lỗi nó không rõ ràng. :) –

2

Tùy thuộc vào nhu cầu của ứng dụng của bạn có sáu tùy chọn phổ biến. Điều này Dr Dobbs Journal article sẽ cung cấp cho bạn tất cả các thông tin (và nhiều hơn nữa) bạn cần vào lựa chọn tốt nhất.

Trong trường hợp cụ thể của bạn, từ bài viết này:

GetSystemTime() lấy thời hệ thống hiện hành và khởi tạo một cấu trúc SYSTEMTIME, đó là bao gồm một số lĩnh vực riêng biệt bao gồm năm, tháng , ngày, giờ, phút, giây và mili giây.

+1

Đúng nếu tôi sai, nhưng không GetTickCount cho số hte mili giây đã trôi qua kể từ khi khởi chạy ứng dụng oyur? – Mark

+1

Đúng vậy, tôi đã thêm sai câu. Lấy làm tiếc. Tôi đã sửa nó ngay bây giờ. – Ash

+1

@Mark: Kể từ khi hệ thống được khởi động. 'GetTickCount64', kể từ Windows Vista, mở rộng đến 64 bit; các cựu được giới hạn 32. –

2

Sử dụng GetSystemTime, trước tiên; sau đó, nếu bạn cần điều đó, bạn có thể gọi SystemTimeToFileTime trên cấu trúc SYSTEMTIME mà trước đây sẽ điền cho bạn. A FILETIME là số lượng 64-bit của khoảng thời gian 100 nanosec từ một kỷ nguyên, và vì vậy phù hợp hơn cho số học; a SYSTEMTIME là cấu trúc với tất cả các trường được mong đợi (năm, tháng, ngày, giờ, v.v., xuống đến mili giây). Nếu bạn muốn biết "bao nhiêu mili giây đã trôi qua kể từ nửa đêm", ví dụ, trừ hai cấu trúc FILETIME (một cho thời gian hiện tại, một cấu trúc thu được bằng cách chuyển đổi cùng một số SYSTEMTIME sau khi xóa các trường thích hợp) và chia cho mười có lẽ là cách tiếp cận có sẵn đơn giản nhất.

+0

Jed, phải, viết từ bộ nhớ Tôi nghĩ rằng có một gạch dưới - chỉnh sửa ngay bây giờ để sửa chữa, tx. –

+0

Đó là những gì tôi đã tìm. :) –

41

Cách đơn giản nhất (và trực tiếp nhất) là để gọi GetSystemTimeAsFileTime(), mà trả về một FILETIME, một cấu trúc mà các cửa hàng số 64-bit của khoảng 100 nano giây kể từ nửa đêm 01 tháng 1, 1601.

Ít nhất tại thời gian của Windows NT 3.1, 3.51 và 4.01, API GetSystemTimeAsFileTime() là API chế độ người dùng nhanh nhất có thể truy xuất thời gian hiện tại. Nó cũng cung cấp lợi thế (so với GetSystemTime() -> SystemTimeToFileTime()) là một cuộc gọi API duy nhất, trong các trường hợp bình thường không thể thất bại.

Để chuyển đổi một FILETIME ft_now; đến một số nguyên 64-bit tên ll_now, sử dụng như sau:
ll_now = (LONGLONG)ft_now.dwLowDateTime + ((LONGLONG)(ft_now.dwHighDateTime) << 32LL);

Sau đó bạn có thể chia cho số lượng khoảng 100 nano giây trong một phần nghìn giây (10.000 của những) và bạn có mili giây kể từ kỷ nguyên Win32.

Để chuyển sang kỷ nguyên Unix, trừ 116444736000000000LL đạt 01 Tháng Một, 1970.

Bạn đề cập đến một mong muốn tìm ra số mili giây vào ngày hiện tại. Bởi vì kỷ nguyên Win32 bắt đầu vào lúc nửa đêm, số mili giây đã trôi qua cho đến nay ngày nay có thể được tính từ thời gian filetime với một hoạt động modulus. Cụ thể, vì có 24 hours/day * 60 minutes/hour * 60 seconds/minute * 1000 milliseconds/second = 86,400,000 milliseconds/day, bạn có thể sử dụng mô-đun của thời gian hệ thống theo mô-đun mili giây 86400000LL.

Đối với một ứng dụng khác, người dùng có thể không muốn sử dụng mô-đun. Đặc biệt nếu người ta tính thời gian trôi qua, người ta có thể gặp khó khăn do quấn quanh vào lúc nửa đêm. Những khó khăn này là khả năng giải quyết được, ví dụ tốt nhất mà tôi biết là dòng của Linus Torvald trong hạt nhân Linux xử lý truy cập xung quanh.

Hãy nhớ rằng thời gian hệ thống được trả về dưới dạng thời gian UTC (cả trong trường hợp GetSystemTimeAsFileTime() và chỉ đơn giản là GetSystemTime()). Nếu bạn yêu cầu giờ địa phương như được cấu hình bởi Quản trị viên, thì bạn có thể sử dụng GetLocalTime().

+2

+1 cho sự cố độc lập. Hãy cẩn thận để thêm bit cho NT5.1 + về 'ít nhất là tại thời điểm Windows NT 3.1, 3.51 và 4.01 .. người dùng nhanh nhất-api'. Nó có ngụ ý nó không còn là trường hợp? –

+1

Nó chỉ ngụ ý rằng tôi không thể thề với tình hình sau 4.01, nhưng trên thực tế tôi tin rằng API này vẫn là nhanh nhất. Trong những ngày cũ, nó đã được thực hiện như một vài hoạt động MOV - SystemTimeAsFileTime được lưu trữ trong một trang bộ nhớ chia sẻ mà tất cả các quá trình có thể đọc. –

+1

Rất đẹp, trong câu trả lời chuyên sâu. Để trả lời câu hỏi cuối cùng của bạn, tôi đang mô phỏng một kịch bản môi trường, khi mà ngày diễn ra, môi trường sẽ phát triển tối hơn (như ở ngoài trời).Nó chỉ là vấn đề nhận được thời gian trong ngày (tính bằng mili giây kể từ nửa đêm là định dạng mà động cơ của tôi hiện đang đọc) để đồng bộ hóa :) – Mark

1

Dưới đây là một số mã hoạt động trong Windows mà tôi đã sử dụng trong dự án Open Watcom C. Nó sẽ làm việc trong C++ nó trả về giây (không mili giây) sử dụng _dos_gettime hoặc GetTime

double seconds(void) 
    { 
    #ifdef __WATCOMC__ 
    struct dostime_t t; 
    _dos_gettime(&t); 
    return ((double)t.hour * 3600 + (double)t.minute * 60 + (double)t.second + (double)t.hsecond * 0.01); 
    #else 
    struct time t; 
    gettime(&t); 
    return ((double)t.ti_hour * 3600 + (double)t.ti_min * 60 + (double)t.ti_sec + (double)t.ti_hund * 0.01); 
    #endif 
} 
3

Một ví dụ cắt-to-the-đuổi của câu trả lời Jed của trên:

const std::string currentDateTime() { 

SYSTEMTIME st, lt; 

GetSystemTime(&st); 

char currentTime[84] = ""; 

sprintf(currentTime,"%d/%d/%d %d:%d:%d %d",st.wDay,st.wMonth,st.wYear, st.wHour, st.wMinute, st.wSecond , st.wMilliseconds); 

return string(currentTime); } 
+0

'sprintf (currentTime, "%. 4d% .2d% .2d% .2d% .2d% .2d% .4d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 'cho một chuỗi có độ dài cố định – Antonio

+0

Điều này nhận được thời gian UTC; 'GetLocalTime()' hoạt động tương tự nhưng cho thời gian múi giờ cục bộ –

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