Получить DateTime.Now с точностью до миллисекунд


231

Как точно построить временную отметку реального времени с точностью до миллисекунд?

Мне нужно что-то вроде 16.4.2013 9: 48: 00: 123. Это возможно? У меня есть приложение, в котором я выбираю значения 10 раз в секунду, и мне нужно показать их на графике.



Имейте в виду, что ряд ответов используется hhдля часов (стандартное время). В случае метки времени (и во многих других случаях) это, вероятно, должно быть связано с tt(am / pm) или заменено на HH(военное время).
Венц

Ответы:


304

Как точно построить временную отметку реального времени с точностью до миллисекунд?

Я подозреваю, что вы имеете в виду точность в миллисекундах . DateTimeимеет много точности, но довольно груб с точки зрения точности. Вообще говоря, вы не можете. Обычно системные часы (откуда они DateTime.Nowполучают данные) имеют разрешение около 10-15 мс. См. Блог Эрика Липперта о точности и точности для более подробной информации.

Если вам нужно более точное время, чем это, вы можете изучить использование клиента NTP.

Однако, не ясно, что вам действительно нужна точность в миллисекундах. Если вас не интересует точное время - вы просто хотите показать сэмплы в правильном порядке с «довольно хорошей» точностью, тогда системные часы должны быть в порядке. Я бы посоветовал вам использовать, DateTime.UtcNowа не DateTime.Now, чтобы избежать проблем с часовыми поясами при переходе на летнее время и т. Д.

Если ваш вопрос на самом деле только вокруг преобразования DateTimeв строку с точностью до миллисекунды, я предложил бы использовать:

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

(Обратите внимание, что в отличие от вашего образца, это сортируется и с меньшей вероятностью может привести к путанице относительно того, будет ли это «месяц / день / год» или «день / месяц / год».)


5
@antonio: не имея больше информации, чем «не работает», я не могу больше помочь.
Джон Скит

Да, я могу предоставить дополнительную информацию: "{0: ггггМмдд ЧЧ: мм: сс.ффф}", DateTime.UtcNow -> 20180502 11: 07: 20.000 Win32.GetSystemTime (ref stime) -> 2018,2,5,11 , 7,20,0 (ммдх мм сс мс) Я могу создать экземпляр даты и времени с миллисекундами: var dt = new DateTime (2018, 5, 2, 19, 34, 55, 200); «{0: ггггММдд ЧЧ: мм: сс.ффф}», дт -> 20180502 19: 34: 55.200. Компактный каркас .Net, Windows Embedded Compact 7, на ARM Cortex-A8
Антонио

@antonio: Похоже, версия .NET, которую вы используете на оборудовании, которое вы используете, просто не обеспечивает точность до секунды, или вы случайно назвали ее на второй границе. (Если вы продолжаете наносить удары DateTime.UtcNowнесколько раз, увеличивается ли он когда-либо только раз в секунду? Вы этого не показывали.)
Джон Скит,

Когда я получаю тики из DateTime.Now, значение усекается: Ticks 636534596580000000 DateTime из тиков 20180205 20: 34: 18.000. я думаю, что ограничение в аппаратном / программном обеспечении. Я использую класс Секундомер, вместо этого Спасибо Джон
Антонио

@antonio: Вероятно, стоит создать новый вопрос с полной информацией об устройстве, задействованном на данный момент.
Джон Скит

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
Если дата в полдень (4 вечера) будет отображаться как утром. ИСПРАВЛЕНИЕ: Используйте HH(военное время) или добавить tt(PM или AM). Как показано в этом примере: repl.it/KGr3/1
Jaider

22

Используйте DateTime Structure с миллисекундами и форматируйте так:

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

16

Ответ Pyromancer кажется мне довольно хорошим, но, возможно, вы хотели:

DateTime.Now.Millisecond

Но если вы сравниваете даты, TimeSpan это путь.


15
Примечание. Если вы сравниваете разницу между двумя значениями DateTime и TimeSpan, вам нужно TotalMilliseconds. Миллисекунды содержат текущий счетчик Миллисекунд, который никогда не превышает 1000, тогда как 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.Now может составлять не более 16 мс.
Питер Мортенсен

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

Огромное спасибо. Я так долго искал это. Это вызывает какие-либо проблемы с производительностью и безопасно ли использовать производственный код?
Мухаммет Гектюрк Аян


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

Если вы хотите микросекунды, просто измените 10000на 10, и если вы хотите 10-й микро, удалите / 10000.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.