รับเวลาเป็นมิลลิวินาทีโดยใช้ C #


133

ฉันกำลังทำโปรแกรมที่ฉันต้องใช้เวลาเป็นมิลลิวินาที เมื่อเวลาผ่านไปฉันหมายถึงจำนวนที่ไม่เคยเท่ากับตัวมันเองและมักจะมีจำนวนมากกว่า 1,000 ตัวเมื่อเทียบกับวินาทีที่แล้ว ฉันได้ลองแปลงDateTime.Nowเป็น a TimeSpanและรับค่าTotalMillisecondsจากนั้น ... แต่ฉันได้ยินมาว่ามันไม่ถูกต้องอย่างสมบูรณ์

มีวิธีที่ง่ายกว่านี้ไหม


คุณคาดหวังว่าการเรียกสองครั้งจะนำไปสู่มูลค่าที่เพิ่มขึ้นหรือไม่ โดยทั่วไปการโทรที่ใกล้กว่าช่วงเวลาต่ำสุดที่ความละเอียดของตัวจับเวลาอนุญาตจะให้ค่าเดียวกัน คุณจะต้องเพิ่มไทเบรกเกอร์ของคุณเองในรูปแบบของซีเรียลไลเซอร์ที่มีความแม่นยำปลอม
Steven Sudit

16
"จำนวนที่ไม่เคยเท่ากับตัวมันเอง". ฟังดู ... ซับซ้อน ;)
Mizipzor

1
NaN เหมาะสมกับข้อกำหนดนั้นจริง แม้ว่าจะ "ไม่ใช่ตัวเลข" แต่ก็เป็นประเภทตัวเลขและไม่เท่ากับตัวมันเอง
Yay295

คำตอบ:


78

ใช้Stopwatchชั้นเรียน

จัดเตรียมชุดวิธีการและคุณสมบัติที่คุณสามารถใช้เพื่อวัดเวลาที่ผ่านไปอย่างแม่นยำ

มีข้อมูลที่ดีในการใช้งานที่นี่:

การทดสอบประสิทธิภาพ: การวัดเวลาทำงานที่แม่นยำด้วยระบบการวินิจฉัยนาฬิกาจับเวลา


8
นาฬิกาจับเวลาเป็นส่วนหนึ่งของการวินิจฉัย ควรใช้ในโค้ดจริงหรือไม่?
Andrey


โดยปกติจะมีความแม่นยำถึง 15ms ที่ใกล้ที่สุดเท่านั้น
Steven Sudit

11
ราคาแพงแค่ไหน? บางทีเราควรจับเวลาด้วยนาฬิกาจับเวลา :)
jb.

3
@Steven ขึ้นอยู่กับระบบปฏิบัติการและฮาร์ดแวร์พื้นฐาน หากมีให้ใช้ตัวจับเวลาความละเอียดสูงซึ่งเป็นกรณีสำหรับเดสก์ท็อปและเซิร์ฟเวอร์ที่ใช้ Windows รุ่น x86 ทั้งหมดที่ฉันทราบ ตรวจสอบคุณสมบัติความถี่และ IsHighResolution สำหรับรายละเอียดเพิ่มเติม ในระดับ OS QueryPerformanceCounter และ QueryPerformanceFrequency เป็น API ระดับต่ำที่สนับสนุนฟังก์ชันนี้
Chris Taylor

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

นี่คือวิธีการใช้งานวิธีการแปลง Unix ต่างๆในDateTimeOffsetคลาส (.NET Framework 4.6+, .NET Standard 1.3+):

long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();

65
ชื่อเรื่องคือ "รับเวลาเป็นมิลลิวินาที" คำตอบนี้มีประโยชน์
Aerospace

33
ใช่สำหรับพวกเราที่กำลังค้นหาคำตอบสำหรับคำถามตามที่โพสต์สิ่งนี้มีประโยชน์มากขอบคุณ
user430788

1
หากคุณต้องการทศนิยม (แม้ว่าDateTime.Nowจะไม่ "อัปเดต" บ่อยนักก็ตาม) ให้ใช้decimal milliseconds = DateTime.Now.Ticks / (decimal)TimeSpan.TicksPerMillisecond;แทน
Jeppe Stig Nielsen

1
สิ่งนี้มีประโยชน์มากกว่าคำตอบที่เลือกไว้สำหรับผลการค้นหาและแม้กระทั่งสำหรับสิ่งที่ฉันรวบรวมจากคำถามเดิม
bwoogie

1
คำตอบนี้ช่วยชีวิตฉัน มีรหัสที่คล้ายกัน แต่ใช้งานไม่ได้ คิดไม่ออกว่าทำไม จากนั้นฉันเห็นlongประเภทข้อมูลอยู่ข้างหน้ามิลลิวินาที ใช้intแน่นอนจะล้น
FisNaN

13

DateTime.Ticksคุณสมบัติได้รับจำนวนเห็บที่แสดงวันที่และเวลา

10,000 เห็บเป็นมิลลิวินาที (10,000,000 เห็บต่อวินาที)


4
แต่ความละเอียดของเห็บน้อยกว่า 1 / 10000s มากอาจเป็น
1/62 วินาที

2
@codymanix - จาก 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
แน่นอน แต่ระบบปฏิบัติการไม่ได้มีความละเอียดเท่านี้แน่นอน
codymanix

6
@codymanix ถูกต้อง. โดยการเปรียบเทียบอังสตรอมเป็นหน่วยของความยาว อังสตรอมหมื่นล้านสร้างหนึ่งเมตร คุณสามารถเขียนฟังก์ชันที่รายงานความสูงของคุณเป็นจำนวนเต็ม 64 บิตในอังสตรอม แต่ถ้าสิ่งที่คุณมีคือ metrestick ที่แม่นยำถึงเซนติเมตรความจริงที่ว่าฟังก์ชันนี้แสดงถึงความแม่นยำระดับนาโนเมตรจะไม่เกี่ยวข้องโดยสิ้นเชิง ตัวเลขที่มีนัยสำคัญน้อยกว่าจะเป็นขยะ
Eric Lippert

4
@RedFilter: ถ้าคุณรู้อายุของตัวเองเป็นมิลลิวินาทีที่ใกล้ที่สุดจริงๆคุณอาจจะพูดว่า "เมื่อฉันกระพริบตาอีกครั้งอายุของฉันจะเท่ากับ x มิลลิวินาที" ปัญหาที่ลึกกว่าไม่ใช่การสื่อสาร แต่เป็นการวัดผล: การเกิดของคุณไม่น่าจะเป็นที่รู้จักแม้แต่วินาทีที่ใกล้ที่สุด
Steven Sudit

11

ฉันใช้คลาสต่อไปนี้ ผมพบว่ามันบนอินเทอร์เน็ตครั้งการตั้งสมมติฐานที่จะดีที่สุดNOW ()

/// <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); } }
}

ไม่ทราบแหล่งที่มา


5
FWIW ประเด็นทั้งหมดของตัวอย่างข้อมูลที่ใช้กันทั่วไปนี้คือการสร้างการประทับเวลาที่เข้ากันได้กับมาตรฐานการประทับเวลา Unix ดังนั้นจึงมีความสำคัญ หากใครต้องการทำเวลาก็มีราคาแพงโดยไม่จำเป็น
ToolmakerSteve

8

คุณสามารถลองใช้QueryPerformanceCounterวิธีดั้งเดิม ดูhttp://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCounter.htmlสำหรับข้อมูลเพิ่มเติม นี่คือสิ่งที่Stopwatchชั้นเรียนใช้

ดูวิธีรับการประทับเวลาของขีดความแม่นยำใน. NET / C #? สำหรับข้อมูลเพิ่มเติม.

Stopwatch.GetTimestamp() ให้การเข้าถึงวิธีนี้:

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

1
AFAIK StopWatch ใช้ QueryPerformanceCounter เป็นการภายในถ้ามี
codymanix

ใช่การใช้งานภายในของStopwatch.GetTimestamp()ให้การเข้าถึงวิธีการนั้นจริง
Pieter van Ginkel

5

ฉันใช้ DateTime.Now.TimeOfDay.TotalMilliseconds (สำหรับวันปัจจุบัน) หวังว่ามันจะช่วยคุณได้เช่นกัน


1
ที่จะไม่คืนค่าที่เพิ่มขึ้น (ตามที่ต้องการโปสเตอร์ต้นฉบับ) เนื่องจาก TimeOfDay ถูกรีเซ็ตเป็นศูนย์ทุกวันตอนเที่ยงคืน นอกจากนี้ยังมีปัญหาที่อาจเกิดขึ้นเช่นเดียวกับที่ผู้โพสต์กล่าวถึงเมื่อใช้ DateTime ตอนนี้การรับจำนวนมิลลิวินาทีทั้งหมดจากนั้น
Jim O'Neil

3
Jim O'Neil ฉันเห็นด้วยกับคุณนั่นคือเหตุผลที่ฉันพูดถึง "(สำหรับวันปัจจุบัน)" ในโพสต์ของฉัน ... Btw วิธีแก้ปัญหาของฉันใช้ได้กับปัญหาของฉันเนื่องจากปัญหาของฉันไม่ใช่วันที่ที่เฉพาะเจาะจงฉันเพียงแค่ต้องได้รับ ส่วนมิลลิวินาทีที่จะใช้เป็นตัวนับฉันจึงโพสต์ไว้ที่นี่ ฉันเป็นคนใหม่ที่นี่ดังนั้นหากฉันโพสต์ผิดที่ขออภัย :)
Sarvan

2

ใช้System.DateTime.Now.ToUniversalTime(). นั่นทำให้การอ่านของคุณอยู่ในรูปแบบมิลลิวินาทีอ้างอิงตามที่รู้จักซึ่งกำจัดการเปลี่ยนแปลงของวันโดยสิ้นเชิง ฯลฯ


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