รับ DateTime ตอนนี้ด้วยความแม่นยำมิลลิวินาที


231

ฉันจะสร้างการประทับเวลาตามเวลาจริงด้วยความแม่นยำเป็นมิลลิวินาทีได้อย่างไร

ฉันต้องการบางอย่างเช่น 16.4.2013 9: 48: 00: 123 เป็นไปได้ไหม ฉันมีแอปพลิเคชันที่ฉันสุ่มค่า 10 ครั้งต่อวินาทีและฉันต้องแสดงในกราฟ



โปรดทราบว่าคำตอบจำนวนหนึ่งใช้hhสำหรับชั่วโมง (เวลามาตรฐาน) ในกรณีของการประทับเวลา (และในอีกหลายกรณี) สิ่งนี้อาจถูกจับคู่กับtt(am / pm) หรือแทนที่ด้วยHH(เวลาทางทหาร)
goz

คำตอบ:


304

ฉันจะสร้างการประทับเวลาตามเวลาจริงด้วยความแม่นยำเป็นมิลลิวินาทีได้อย่างไร

ฉันสงสัยว่าคุณหมายถึงมิลลิวินาทีความถูกต้อง DateTimeมีความแม่นยำสูง แต่ค่อนข้างหยาบในแง่ของความแม่นยำ โดยทั่วไปคุณไม่สามารถทำได้ โดยปกตินาฬิการะบบ (ซึ่งเป็นที่DateTime.Nowรับข้อมูลจาก) มีความละเอียดประมาณ 10-15 ms ดูโพสต์บล็อกของ Eric Lippert เกี่ยวกับความแม่นยำและความแม่นยำสำหรับรายละเอียดเพิ่มเติม

หากคุณต้องการเวลาที่แม่นยำกว่านี้คุณอาจต้องการใช้ไคลเอ็นต์ NTP

อย่างไรก็ตามมันไม่ชัดเจนว่าคุณต้องการความแม่นยำเป็นมิลลิวินาทีที่นี่ หากคุณไม่สนใจเวลาที่แน่นอน - คุณเพียงแค่ต้องการแสดงตัวอย่างในลำดับที่ถูกต้องด้วยความแม่นยำ "ค่อนข้างดี" นาฬิการะบบควรจะดี ฉันขอแนะนำให้คุณใช้DateTime.UtcNowแทนDateTime.Nowเพื่อหลีกเลี่ยงปัญหาเกี่ยวกับโซนเวลาในช่วงการเปลี่ยนภาพตามฤดูกาล ฯลฯ

หากคำถามของคุณจริงเพียงรอบแปลงDateTimeเป็นสตริงที่มีความแม่นยำมิลลิวินาทีผมขอแนะนำให้ใช้:

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

(โปรดทราบว่าไม่เหมือนกับตัวอย่างของคุณซึ่งสามารถจัดเรียงได้และมีโอกาสน้อยที่จะเกิดความสับสนว่า "เดือน / วัน / ปี" หรือ "วัน / เดือน / ปี")


5
@antonio: ไม่มีข้อมูลมากไปกว่า "ไม่ทำงาน" ฉันไม่สามารถให้ความช่วยเหลือเพิ่มเติมได้อีก
Jon Skeet

ใช่ฉันสามารถให้ข้อมูลเพิ่มเติม: "{0: yyyyMMdd HH: mm: ss.fff}", DateTime.UtcNow -> 20180502 11: 07: 20.000 Win32.GetSystemTime (ref stime) -> 2018,2,5,11 , 7,20,0 (ymdh mm ss ms) ฉันสามารถสร้างตัวอย่างของเวลาวันที่ด้วยมิลลิวินาที: var dt = ใหม่ DateTime (2018, 5, 2, 19, 34, 55, 200); "{0: yyyyMMdd HH: mm: ss.fff}", dt -> 20180502 19: 34: 55.200. โครงร่างกระชับสุทธิ. Windows Compact Compact 7, บน ARM Cortex-A8
อันโตนิโอ

@antonio: ดังนั้นดูเหมือนว่าเวอร์ชันของ. NET ที่คุณใช้บนฮาร์ดแวร์ที่คุณใช้งานอยู่นั้นไม่ได้ให้ความแม่นยำในระดับรองลงมาหรือคุณเรียกมันในขอบเขตที่สอง (ถ้าคุณกดปุ่มDateTime.UtcNowซ้ำ ๆ มันจะเพิ่มขึ้นเพียงครั้งเดียวต่อวินาทีหรือไม่คุณไม่ได้แสดงให้เห็น)
Jon Skeet

เมื่อฉันดึงข้อมูล Ticks จาก DateTime ตอนนี้ค่าจะถูกตัดทอน: Ticks 636534596580000000 DateTime จาก Ticks 20180205 20: 34: 18.000 ข้อ จำกัด อยู่ที่ฮาร์ด / ซอฟต์แวร์ฉันคิดว่า ฉันใช้คลาสนาฬิกาจับเวลาแทน Thanks Jon
อันโตนิโอ

@antonio: มันอาจคุ้มค่าที่จะสร้างคำถามใหม่พร้อมรายละเอียดทั้งหมดของอุปกรณ์ที่เกี่ยวข้องในตอนนี้
Jon Skeet

117

สิ่งนี้น่าจะใช้ได้:

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

หากคุณไม่ต้องการให้แสดงผลและต้องการทราบความแตกต่างของเวลาคุณไม่ควรแปลงเป็นสตริง เพียงปล่อยไว้เป็นDateTime.Now();

และใช้TimeSpanเพื่อทราบความแตกต่างระหว่างช่วงเวลา:

ตัวอย่าง

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'));

ฉันต้องการคำนวณกับมันดังนั้นฉันไม่สามารถแปลงเป็นสตริงได้
LuckyHK

25

ฉันกำลังมองหาวิธีการแก้ปัญหาที่คล้ายกันโดยอิงจากสิ่งที่แนะนำในกระทู้นี้ฉันใช้สิ่งต่อไปนี้ DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") และมันทำงานได้อย่างมีเสน่ห์ หมายเหตุ: นั่น.fffคือตัวเลขความแม่นยำที่คุณต้องการจับ


1
หากวันที่ในช่วงบ่าย (4PM) จะแสดงเช่นเดียวกับในตอนเช้า การแก้ไข:ใช้HH(เวลาทหาร) หรือเพิ่มtt(PM หรือ AM) ดังที่แสดงในตัวอย่างนี้: repl.it/KGr3/1
Jaider

22

ใช้โครงสร้าง DateTime กับมิลลิวินาทีและรูปแบบดังนี้:

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

16

คำตอบของ Pyromancer นั้นค่อนข้างดีสำหรับฉัน แต่บางทีคุณอาจต้องการ:

DateTime.Now.Millisecond

แต่ถ้าคุณเปรียบเทียบวันที่ TimeSpan เป็นหนทางที่จะไป


15
หมายเหตุ: หากคุณกำลังเปรียบเทียบความแตกต่างระหว่างสอง DateTimes เป็น TimeSpan TotalMillisecondsคุณจะต้อง มิลลิวินาทีถือตัวนับมิลลิวินาทีปัจจุบันซึ่งไม่เคยมากกว่า 1,000 ในขณะที่ TotalMilliseconds ถือมิลลิวินาทีทั้งหมดที่ผ่านไปนับตั้งแต่ยุค
Contango

4

หากคุณยังต้องการวันที่แทนที่จะเป็นสตริงเหมือนคำตอบอื่น ๆ เพียงเพิ่มวิธีการขยายนี้

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

เท่าที่ฉันเข้าใจคำถามคุณสามารถไปที่:

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

สิ่งนี้จะตัดเห็บที่มีขนาดเล็กกว่า 1 มิลลิวินาที


ใช่ แต่ความละเอียดที่แท้จริงของ DateTime ตอนนี้อาจไม่เกิน 16 ms
Peter Mortensen

2

ปัญหาเกี่ยวกับการDateTime.UtcNowและDateTime.Nowเป็นที่ขึ้นอยู่กับระบบคอมพิวเตอร์และการดำเนินงานมันอาจจะเป็นแค่ความถูกต้องระหว่าง 10 และ 15 มิลลิวินาที อย่างไรก็ตามในคอมพิวเตอร์ windows หนึ่งสามารถใช้โดยใช้ฟังก์ชันระดับต่ำGetSystemTimePreciseAsFileTimeเพื่อรับความแม่นยำระดับไมโครวินาทีดูฟังก์ชันGetTimeStamp()ด้านล่าง

    [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;
    }

ขอบคุณมาก. ฉันค้นหามานานแล้ว มันทำให้เกิดปัญหาประสิทธิภาพการทำงานใด ๆ และมันปลอดภัยที่จะใช้รหัสการผลิต?
Muhammet Göktürk Ayan


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

หากคุณต้องการ microseconds เพียงแค่เปลี่ยน10000ไป10และถ้าคุณต้องการที่ 10 / 10000ของไมโครลบ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.