Nhận thời gian tính bằng mili giây bằng C #


131

Tôi đang thực hiện một chương trình mà tôi cần có thời gian tính bằng mili giây. Theo thời gian, ý tôi là một con số không bao giờ bằng chính nó và luôn lớn hơn 1000 số so với một giây trước. Tôi đã thử chuyển đổi DateTime.Nowsang a TimeSpanvà nhận được TotalMillisecondstừ đó ... nhưng tôi nghe nói nó không hoàn toàn chính xác.

Có cách nào dễ dàng hơn để làm điều này?


Bạn có mong đợi bất kỳ hai cuộc gọi để luôn luôn dẫn giá trị ngày càng tăng? Nói chung, các cuộc gọi gần hơn khoảng thời gian tối thiểu mà độ phân giải hẹn giờ cho phép sẽ mang lại cùng một giá trị. Bạn sẽ cần phải thêm bộ bẻ khóa của riêng bạn dưới dạng một bộ nối tiếp chính xác giả.
Steven Sudit

16
"Một con số không bao giờ bằng chính nó". Nghe có vẻ ... phức tạp. ;)
Mizipzor

1
NaN sẽ phù hợp với yêu cầu đó thực sự. Mặc dù là "không phải là số", nó là một loại số và nó không bằng chính nó.
Yay295

Câu trả lời:


78

Sử dụng Stopwatchlớp học.

Cung cấp một tập hợp các phương thức và thuộc tính mà bạn có thể sử dụng để đo chính xác thời gian đã trôi qua.

Có một số thông tin tốt về việc thực hiện nó ở đây:

Kiểm tra hiệu suất: Các phép đo thời gian chạy chính xác với System.Diagnostics.Stopwatch


8
Đồng hồ bấm giờ là một phần của Chẩn đoán. Nó có nên được sử dụng trong mã thực?
Andrey


Điều này thường chỉ chính xác đến 15ms gần nhất.
Steven Sudit

11
Nó đắt thế nào? có lẽ chúng ta nên bấm giờ một đồng hồ bấm giờ :)
jb.

3
@Steven, điều đó phụ thuộc vào HĐH và phần cứng cơ bản. Nếu có sẵn một bộ đếm thời gian độ phân giải cao được sử dụng, đó là trường hợp cho tất cả các phiên bản Windows x86 trên máy tính để bàn và máy chủ hiện tại mà tôi biết. Kiểm tra các thuộc tính Tần số và IsHighResolution để biết thêm chi tiết. Ở cấp độ HĐH, QueryPerformanceCorer và QueryPerformanceFrequency là các API cấp thấp hỗ trợ chức năng này.
Chris Taylor

320
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

Đây thực sự là cách các phương thức chuyển đổi Unix khác nhau được triển khai trong DateTimeOffsetlớp (.NET Framework 4.6+, .NET Standard 1.3+):

long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();

65
Tiêu đề là "có được thời gian tính bằng mili giây". Câu trả lời này rất hữu ích.
Không gian vũ trụ

33
Yup, đối với những người trong chúng ta đang tìm kiếm một câu trả lời cho câu hỏi như đã đặt ra, điều này rất hữu ích, cảm ơn bạn.
dùng430788

1
Nếu bạn muốn số thập phân (ngay cả khi DateTime.Nowkhông được "cập nhật" rất thường xuyên), tất nhiên sử dụng decimal milliseconds = DateTime.Now.Ticks / (decimal)TimeSpan.TicksPerMillisecond;thay thế.
Jeppe Stig Nielsen

1
Điều này hữu ích hơn nhiều so với câu trả lời được chọn cho kết quả tìm kiếm và thậm chí cho những gì tôi thu thập được từ câu hỏi ban đầu.
bwoogie

1
Câu trả lời này đã cứu mạng tôi. Có mã tương tự nhưng không hoạt động. Không thể hiểu tại sao. Sau đó, tôi thấy longkiểu dữ liệu ở phía trước mili giây. Sử dụng intchắc chắn sẽ tràn.
FisNaN

13

Các DateTime.Tickstài sản được số tick đại diện cho ngày tháng và thời gian.

10.000 Ticks là một phần nghìn giây (10.000.000 tick mỗi giây).


4
Nhưng độ phân giải của Ticks rất ít hơn
1/10000

2
@codymanix - từ MSDN:A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.
Itay Karo

5
Chắc chắn là như vậy, nhưng hệ điều hành không có độ phân giải chính xác.
codymanix

6
@codymanix là chính xác. Theo cách tương tự, Angstrom là một đơn vị chiều dài; Mười tỷ Angstroms làm một mét. Bạn có thể viết một hàm báo cáo chiều cao của mình dưới dạng số nguyên 64 bit trong Angstroms, nhưng nếu tất cả những gì bạn có là một siêu dữ liệu chính xác đến từng centimet, thì thực tế là hàm đại diện cho độ chính xác dưới nanomet là hoàn toàn không liên quan. Các chữ số ít quan trọng hơn sẽ là rác.
Eric Lippert

4
@RedFilter: Nếu bạn thực sự biết tuổi của mình đến một phần nghìn giây gần nhất, bạn có thể hình dung một cách có thể hiểu được một câu như "Khi tôi chớp mắt lần nữa, tuổi của tôi sẽ là x mili giây." Vấn đề sâu xa hơn không phải là giao tiếp mà là đo lường: sự sinh nở của bạn khó có thể được biết ngay cả đến giây gần nhất.
Steven Sudit

11

Tôi sử dụng các lớp sau. Tôi đã tìm thấy nó trên Internet một lần, được yêu cầu là tốt nhất NGAY BÂY GIỜ () .

/// <summary>Class to get current timestamp with enough precision</summary>
static class CurrentMillis
{
    private static readonly DateTime Jan1St1970 = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    /// <summary>Get extra long current timestamp</summary>
    public static long Millis { get { return (long)((DateTime.UtcNow - Jan1St1970).TotalMilliseconds); } }
}

Không rõ nguồn gốc.


5
FWIW, toàn bộ điểm của đoạn mã thường được sử dụng này là tạo một dấu thời gian tương thích với tiêu chuẩn dấu thời gian Unix. Đối với điều đó, nó là quan trọng. Nếu một người chỉ muốn làm thời gian, nó là không cần thiết.
ToolmakerSteve

8

Bạn có thể thử QueryPerformanceCounterphương pháp bản địa. Xem http://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCorer.html để biết thêm thông tin. Đây là những gì Stopwatchlớp sử dụng.

Xem Làm thế nào để có được dấu thời gian của độ chính xác đánh dấu trong .NET / C #? để biết thêm thông tin.

Stopwatch.GetTimestamp() cung cấp quyền truy cập vào phương thức này:

public static long GetTimestamp() {
     if(IsHighResolution) {
         long timestamp = 0;
         SafeNativeMethods.QueryPerformanceCounter(out timestamp);
         return timestamp;
     }
     else {
         return DateTime.UtcNow.Ticks;
     }
 }


Đúng, việc thực hiện nội bộ thực Stopwatch.GetTimestamp()sự cung cấp quyền truy cập vào phương thức đó.
Pieter van Ginkel

5

Tôi đã sử dụng DateTime.Now.TimeOfDay.TotalMilliseconds (cho ngày hiện tại), hy vọng nó cũng giúp bạn.


1
sẽ không trả lại giá trị ngày càng tăng (như áp phích ban đầu được yêu cầu) vì TimeOfDay được đặt lại về 0 mỗi ngày vào nửa đêm. Thêm vào đó, nó sẽ có cùng các vấn đề tiềm năng mà người đăng đã đề cập khi chỉ sử dụng DateTime. Bây giờ nhận được tổng số mili giây từ đó.
Jim O'Nilil

3
Jim O'Neil Tôi đồng ý với bạn, đó là lý do tại sao tôi đã đề cập "(cho ngày hiện tại)" trong bài đăng của tôi ... Btw, giải pháp của tôi đã giải quyết được vấn đề của tôi, vì vấn đề của tôi không phải là ngày cụ thể, tôi chỉ cần lấy phần Milliseconds được sử dụng làm bộ đếm, vì vậy tôi đã đăng nó ở đây. Tôi mới ở đây, vì vậy nếu tôi đăng nó ở một vị trí sai thì xin lỗi :)
Sarvan

2

Sử dụng System.DateTime.Now.ToUniversalTime(). Điều đó đặt việc đọc của bạn ở định dạng mili giây dựa trên tham chiếu đã biết mà hoàn toàn loại bỏ thay đổi ngày, v.v.


Điều tốt để biết, nhưng không liên quan đến câu hỏi đang được hỏi, đó là về thời gian (đo thời gian trôi qua), không phải về thời gian giao tiếp chính xác.
ToolmakerSteve
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.