Nhận DateTime. Làm thế nào với độ chính xác mili giây


231

Làm thế nào tôi có thể xây dựng chính xác một dấu thời gian của thời gian thực với độ chính xác đến mili giây?

Tôi cần một cái gì đó như 16.4.2013 9: 48: 00: 123. Điều này có thể không? Tôi có một ứng dụng, trong đó tôi lấy mẫu các giá trị 10 lần mỗi giây và tôi cần hiển thị chúng trong biểu đồ.



Xin lưu ý rằng một số câu trả lời đang sử dụng hhtrong nhiều giờ (thời gian tiêu chuẩn). Trong trường hợp dấu thời gian (và trong nhiều trường hợp khác), điều này có lẽ nên được ghép với tt(sáng / chiều) hoặc thay thế bằng HH(giờ quân sự).
didz

Câu trả lời:


304

Làm thế nào tôi có thể xây dựng chính xác một dấu thời gian của thời gian thực với độ chính xác đến mili giây?

Tôi nghi ngờ bạn có nghĩa là độ chính xác mili giây . DateTimecó rất nhiều độ chính xác, nhưng khá thô về độ chính xác. Nói chung, bạn không thể. Thông thường đồng hồ hệ thống (là nơi DateTime.Nowlấy dữ liệu của nó) có độ phân giải khoảng 10-15 ms. Xem bài đăng trên blog của Eric Lippert về độ chính xác và độ chính xác để biết thêm chi tiết.

Nếu bạn cần thời gian chính xác hơn thời gian này, bạn có thể muốn xem xét sử dụng máy khách NTP.

Tuy nhiên, không rõ ràng rằng bạn thực sự cần độ chính xác đến mili giây ở đây. Nếu bạn không quan tâm đến thời gian chính xác - bạn chỉ muốn hiển thị các mẫu theo đúng thứ tự, với độ chính xác "khá tốt", thì đồng hồ hệ thống sẽ ổn. Tôi khuyên bạn nên sử dụng DateTime.UtcNowhơn là DateTime.Nowđể tránh các vấn đề về múi giờ xung quanh việc chuyển đổi tiết kiệm ánh sáng ban ngày, v.v.

Nếu câu hỏi của bạn thực sự chỉ xoay quanh việc chuyển đổi DateTimemột chuỗi thành độ chính xác đến mili giây, tôi khuyên bạn nên sử dụng:

string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                            CultureInfo.InvariantCulture);

(Lưu ý rằng không giống như mẫu của bạn, điều này có thể sắp xếp và ít gây nhầm lẫn xung quanh việc nó có nghĩa là "tháng / ngày / năm" hay "ngày / tháng / năm".)


5
@antonio: Không có nhiều thông tin hơn "không hoạt động" Tôi không thể cung cấp thêm trợ giúp.
Jon Skeet

Có, tôi có thể cung cấp thêm thông tin: "{0: yyyyMMdd HH: mm: ss.fff}", DateTime.UtcNow -> 20180502 11: 07: 20.000 Win32.GetSystemTime (refime) -> 2018,2,5,11 , 7,20,0 (ymdh mm ss ms) Tôi có thể tạo một thể hiện của thời gian ngày với mili giây: var dt = new DateTime (2018, 5, 2, 19, 34, 55, 200); "{0: yyyyMMdd HH: mm: ss.fff}", dt -> 20180502 19: 34: 55.200 .Net compact framework, Windows Embedded Compact 7, trên ARM Cortex-A8
antonio

@antonio: Vì vậy, có vẻ như phiên bản .NET bạn đang sử dụng trên phần cứng bạn đang sử dụng đơn giản là không cung cấp độ chính xác thứ hai - hoặc bạn tình cờ gọi nó trên ranh giới thứ hai. (Nếu bạn tiếp tục đánh DateTime.UtcNowliên tục, có phải nó chỉ tăng lên một lần mỗi giây không? Bạn đã không cho thấy điều đó.)
Jon Skeet

Khi tôi truy xuất Ticks từ DateTime. Bây giờ, giá trị bị cắt ngắn: Ticks 636534596580000000 DateTime từ Ticks 20180205 20: 34: 18.000. giới hạn là trong phần cứng / phần mềm, tôi nghĩ vậy. Tôi đã sử dụng lớp Đồng hồ bấm giờ, thay vào đó Cảm ơn Jon
antonio

@antonio: Có thể đáng để tạo một câu hỏi mới với đầy đủ chi tiết về thiết bị liên quan tại thời điểm này.
Jon Skeet

117

Điều này sẽ làm việc:

DateTime.Now.ToString("hh.mm.ss.ffffff");

Nếu bạn không cần nó được hiển thị và chỉ cần biết chênh lệch thời gian, thì đừng chuyển đổi nó thành Chuỗi. Cứ để nó nhưDateTime.Now();

Và sử dụng TimeSpanđể biết sự khác biệt giữa các khoảng thời gian:

Thí dụ

DateTime start;
TimeSpan time;

start = DateTime.Now;

//Do something here

time = DateTime.Now - start;
label1.Text = String.Format("{0}.{1}", time.Seconds, time.Milliseconds.ToString().PadLeft(3, '0'));

Tôi cần tính toán với nó, vì vậy tôi không thể chuyển đổi nó thành chuỗi.
LuckyHK

25

Tôi đang tìm kiếm một giải pháp tương tự, dựa trên những gì được đề xuất trên chủ đề này, tôi sử dụng như sau DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") , và nó hoạt động như sự quyến rũ. Lưu ý: đó .ffflà những con số chính xác mà bạn muốn chụp.


1
Nếu ngày là vào buổi chiều (4 giờ chiều) sẽ hiển thị như vào buổi sáng. CỐ ĐỊNH: Sử dụng HH(giờ quân sự) hoặc thêm tt(PM hoặc AM). Như được hiển thị trong ví dụ này: repl.it/KGr3/1
Jaider

22

Sử dụng cấu trúc DateTime với mili giây và định dạng như thế này:

string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", 
CultureInfo.InvariantCulture);
timestamp = timestamp.Replace("-", ".");

16

Câu trả lời của Pyromanc dường như khá tốt với tôi, nhưng có lẽ bạn muốn:

DateTime.Now.Millisecond

Nhưng nếu bạn đang so sánh ngày, TimeSpan là con đường để đi.


15
Lưu ý: Nếu bạn đang so sánh sự khác biệt giữa hai DateTimes là TimeSpan, bạn cần TotalMilliseconds. Milliseconds giữ bộ đếm Milliseconds hiện tại, không bao giờ lớn hơn 1000, trong khi TotalMilliseconds giữ tổng số mili giây trôi qua kể từ kỷ nguyên.
Contango

4

Nếu bạn vẫn muốn một ngày thay vì một chuỗi như các câu trả lời khác, chỉ cần thêm phương thức mở rộng này.

public static DateTime ToMillisecondPrecision(this DateTime d) {
    return new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute,
                        d.Second, d.Millisecond, d.Kind);
}

3

Theo như tôi hiểu câu hỏi, bạn có thể đi:

DateTime dateTime = DateTime.Now;
DateTime dateTimeInMilliseconds = dateTime.AddTicks(-1 * dateTime.Ticks % 10000); 

Điều này sẽ cắt bỏ bọ ve nhỏ hơn 1 mili giây.


Có, nhưng độ phân giải thực tế của DateTime. Bây giờ có thể không quá 16 ms.
Peter Mortensen

2

Vấn đề với DateTime.UtcNowDateTime.Nowlà, tùy thuộc vào máy tính và hệ điều hành, nó chỉ có thể chính xác trong khoảng từ 10 đến 15 mili giây. Tuy nhiên, trên máy tính windows người ta có thể sử dụng bằng cách sử dụng hàm cấp thấp GetSystemTimePreciseAsFileTime để có độ chính xác đến micro giây, xem chức năng GetTimeStamp()bên dưới.

    [System.Security.SuppressUnmanagedCodeSecurity, System.Runtime.InteropServices.DllImport("kernel32.dll")]
    static extern void GetSystemTimePreciseAsFileTime(out FileTime pFileTime);

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct FileTime  {
        public const long FILETIME_TO_DATETIMETICKS = 504911232000000000;   // 146097 = days in 400 year Gregorian calendar cycle. 504911232000000000 = 4 * 146097 * 86400 * 1E7
        public uint TimeLow;    // least significant digits
        public uint TimeHigh;   // most sifnificant digits
        public long TimeStamp_FileTimeTicks { get { return TimeHigh * 4294967296 + TimeLow; } }     // ticks since 1-Jan-1601 (1 tick = 100 nanosecs). 4294967296 = 2^32
        public DateTime dateTime { get { return new DateTime(TimeStamp_FileTimeTicks + FILETIME_TO_DATETIMETICKS); } }
    }

    public static DateTime GetTimeStamp() { 
        FileTime ft; GetSystemTimePreciseAsFileTime(out ft);
        return ft.dateTime;
    }

Cảm ơn bạn rất nhiều. Tôi đã tìm kiếm điều này quá lâu. Có phải nó gây ra bất kỳ vấn đề hiệu suất nào và có an toàn khi sử dụng mã sản xuất không?
Muhammet Göktürk Ayan


-2
public long millis() {
  return (long.MaxValue + DateTime.Now.ToBinary()) / 10000;
}

Nếu bạn muốn micro giây, chỉ cần thay đổi 10000thành 10và nếu bạn muốn số 10 của micro, hãy xóa / 10000.


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.