Имейте в виду, что компьютерные часы не настроены на какой-либо уровень точности - два часа на разных компьютерах обычно будут отличаться по крайней мере на несколько миллисекунд, если вы не приложили некоторых усилий для настройки процедуры высокоточной синхронизации. (когда такое возможно даже физически). Я не могу себе представить, какой смысл знать время компьютера с точностью до микросекунды. (Если вы пытаетесь измерить интервал точно на одном компьютере, тогда, конечно, это вполне разумно, но вам не нужна полная временная метка.)
Дэвид З
2
Кроме того, некоторые версии Unix / Linux возвращают только 1 миллисекунду или 10 миллисекунду в поле микросекунды.
Stephen C
Косвенным способом является JDBC , если он подключен к базе данных, такой как Postgres, которая фиксирует текущее время в микросекундах.
Basil Bourque
2
Java 9 и новее:Instant.now()
Basil
Используйте Instant для вычисления микросекунд с момента Epoch: val instant = Instant.now();val currentTimeMicros = instant.getEpochSecond() * 1000_000 + instant.getNano() / 1000;
Майкл М.
Ответы:
149
Нет, у Java такой возможности нет.
У него есть System.nanoTime (), но он просто дает смещение от некоторого ранее известного времени. Таким образом, хотя вы не можете извлечь из этого абсолютное число, вы можете использовать его для измерения наносекундной (или более высокой) точности.
Обратите внимание, что в JavaDoc говорится, что хотя это обеспечивает точность в наносекунду, это не означает точность в наносекунду. Итак, возьмите какой-нибудь достаточно большой модуль возвращаемого значения.
Можно было бы предположить, что причины, по которым Java не имеет getTimeInMicroseconds (), включают: 1) точность, недоступную на многих платформах, 2) возврат миллисекундной точности в микросекундном вызове, приводит к проблемам с переносимостью приложения.
Stephen C
9
В Linux System.nanoTime () вызывает clock_gettime (CLOCK_MONOTONIC, _). Брайан Оксли покопался в исходном коде Java, чтобы найти этот самородок.
Дэвид Вебер
8
Этот ответ уже устарел . Реализации Java 9 в OpenJDK и Oracle поставляются с новой реализацией, Clockкоторая обеспечивает захват текущего момента с разрешением меньше миллисекунд. На MacBook Pro Retina я получаю текущее время в микросекундах (шесть цифр десятичной дроби). Фактические результаты и точность зависят от базового тактового оборудования главного компьютера.
Basil
1
@BasilBourque: многие системы все еще работают на Java 8 или даже более ранней версии, поскольку нет необходимости их переносить. Хотя ответ устарел, он все еще полезен.
Драгас
1
@Dragas На самом деле, было бы необходимо перенести их ... чтобы получить текущее время в микросекундах , как задал этот вопрос.
Basil
81
tl; dr
Java 9 и новее: разрешение до наносекунд при захвате текущего момента. Это 9 цифр десятичной дроби.
Instant// Represent a moment in UTC. .now()// Capture the current moment. Returns a `Instant` object. .truncatedTo(// Lop off the finer part of this moment. ChronoUnit.MICROS // Granularity to which we are truncating. )// Returns another `Instant` object rather than changing the original, per the immutable objects pattern.
2017-12-23T12: 34: 56.123456Z
На практике вы увидите только микросекунды, захваченные с помощью .nowсовременных обычных компьютерных аппаратных часов, неточности в наносекундах .
подробности
Другие ответы несколько устарели с Java 8.
java.time
Java 8 и более поздние версии поставляются с фреймворком java.time . Эти новые классы вытесняют ошибочные и проблемные классы времени и даты, поставляемые с самыми ранними версиями Java, такими как java.util.Date/.Calendar и java.text.SimpleDateFormat. Структура определяется JSR 310, вдохновленной Joda-Time , расширенной проектом ThreeTen-Extra.
Классы в java.time разрешаются в наносекунды , что намного меньше миллисекунд, используемых как старыми классами даты и времени, так и Joda-Time. И точнее микросекунд, заданных в Вопросе.
Clock Реализация
Хотя классы java.time поддерживают данные, представляющие значения в наносекундах, классы еще не генерируют значения в наносекундах. Эти now()методы используют ту же самую старую реализацию часов , как и старые классы даты и время, System.currentTimeMillis(). У нас есть новый Clockинтерфейс в java.time, но реализация этого интерфейса - те же старые часы в миллисекундах.
Таким образом, вы можете отформатировать текстовое представление результата, ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )чтобы увидеть девять цифр дробной секунды, но только первые три цифры будут иметь такие числа:
2017-12-23T12:34:56.789000000Z
Новые часы в Java 9
Реализации Java 9 в OpenJDK и Oracle имеют новую Clockреализацию по умолчанию с более высокой степенью детализации, вплоть до полной наносекундной возможности классов java.time.
На MacBook Pro (Retina, 15 дюймов, конец 2013 г.) с macOS Sierra я получаю текущий момент в микросекундах (до шести цифр десятичной дроби).
2017-12-23T12:34:56.123456Z
Аппаратные часы
Помните, что даже с новой более тонкой Clockреализацией ваши результаты могут отличаться в зависимости от компьютера. Java зависит от часов базового компьютерного оборудования, чтобы узнать текущий момент.
Разрешение аппаратных часов изменяться в широких пределах. Например, если аппаратные часы конкретного компьютера поддерживают детализацию только в микросекундах , любые сгенерированные значения даты и времени будут иметь только шесть цифр дробной секунды, причем последние три цифры будут нулями.
Точность аппаратных часов изменяться в широких пределах. Просто потому, что часы генерируют значение с несколькими цифрами десятичной доли секунды, эти цифры могут быть неточными, просто приближениями, дрейфующими от фактического времени, которое может быть прочитано с атомных часов . Другими словами, только то, что вы видите группу цифр справа от десятичного знака, не означает, что вы можете доверять истекшему времени между такими показаниями, чтобы быть верным до этой минутной степени.
Они могут разрешаться в наносекунды, но они все еще основаны на System.currentTimeMillis, поэтому они просто добавляют кучу нулей в конце. Совсем не помогает, если вы пытаетесь получить время в микро / нано секундах, пользователь может просто вручную добавить нули к времени миллисекунды.
annedroiid
@annedroiid Я рассказал об этом в своем ответе. В Java 8 вы можете сохранять моменты с разрешением наносекунды, но запись текущего момента осуществляется только в миллисекундах. Исправлено в Java 9 с помощью новой реализации Clock. Даже в этом случае в Java 8 классы java.time полезны для хранения значений, полученных из других источников, таких как микросекунды, в базе данных Postgres. Но остерегайтесь неточности значений в диапазоне микросекунд и наносекунд; обычное компьютерное оборудование может не обеспечивать точное отслеживание времени аппаратных часов. Значение с шестью или девятью цифрами дробной секунды может быть неверным.
@Roland Да, теперь исправлено, спасибо. К вашему сведению, в Stack Overflow вам предлагается напрямую отредактировать ответ, чтобы исправить такую ошибку.
long start =System.nanoTime();// do stufflong end =System.nanoTime();long microseconds =(end - start)/1000;
чтобы получить время в наносекундах, но это строго относительная мера. Это не имеет абсолютного значения. Это полезно только для сравнения с другими нано-временами, чтобы измерить, сколько времени что-то потребовалось.
Как уже указывалось на других плакатах; ваши системные часы, вероятно, не синхронизированы с текущим мировым временем с точностью до микросекунд. Тем не менее, это временные метки с точностью до микросекунд, которые можно использовать как гибрид как для индикации текущего времени на стене, так и для измерения / профилирования продолжительности событий.
Я помечаю все события / сообщения, записанные в файлы журнала, с помощью временных меток, например «2012-10-21 19: 13: 45.267128». Они передают время, когда это произошло (время «стены»), а также могут использоваться для измерения продолжительности между этим и следующим событием в файле журнала (относительная разница в микросекундах).
Для этого вам нужно связать System.currentTimeMillis () с System.nanoTime () и с этого момента работать исключительно с System.nanoTime (). Пример кода:
/**
* Class to generate timestamps with microsecond precision
* For example: MicroTimestamp.INSTANCE.get() = "2012-10-21 19:13:45.267128"
*/publicenumMicroTimestamp{ INSTANCE ;privatelong startDate ;privatelong startNanoseconds ;privateSimpleDateFormat dateFormat ;privateMicroTimestamp(){this.startDate =System.currentTimeMillis();this.startNanoseconds =System.nanoTime();this.dateFormat =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");}publicString get(){long microSeconds =(System.nanoTime()-this.startNanoseconds)/1000;long date =this.startDate +(microSeconds/1000);returnthis.dateFormat.format(date)+String.format("%03d", microSeconds %1000);}}
Идея хороша, но вы должны время от времени выполнять повторную синхронизацию. Системное время (currentTime) и часы процессора (nanoTime) НЕ синхронизированы, поскольку они часто основаны на разных аппаратных часах. Кроме того, сервер времени вашей операционной системы повторно синхронизирует системные часы с внешним источником времени, если он доступен. Следовательно, ваш, казалось бы, очень точный класс будет производить отметки времени, которые могут быть далекими!
h2stein
3
Этот код не кажется потокобезопасным. Два одновременных вызова MicroTimestamp.INSTANCE.get()могут быть проблематичными.
Ахмед
@Ahmed Как вы думаете, почему код не является потокобезопасным? В get()методе нет ничего, что обновляло бы переменные-члены; он использует только временные локальные переменные.
Джейсон Смит
6
Возможно, вы могли бы создать компонент, который определяет смещение между System.nanoTime () и System.currentTimeMillis () и эффективно получать наносекунды с эпохи.
Если вас интересует Linux: если вы извлечете исходный код для «currentTimeMillis ()», вы увидите, что в Linux, если вы вызовете этот метод, он вернется на микросекунду назад. Однако Java затем усекает микросекунды и возвращает вам миллисекунды. Отчасти это связано с тем, что Java должна быть кроссплатформенной, поэтому предоставление методов специально для Linux было большим запретом в те времена (помните, что грубая поддержка софт-ссылок с версии 1.6 назад ?!). Это еще и потому, что, хотя ваши часы могут возвращать вам микросекунды в Linux, это не обязательно означает, что они подходят для проверки времени. На уровне микросекунд вам необходимо знать, что NTP не корректирует ваше время и что ваши часы не слишком сильно отклоняются во время вызовов методов.
Это означает, что теоретически в Linux вы можете написать оболочку JNI, такую же, как в пакете System, но не усекать микросекунды.
«быстрое и грязное» решение, которое я в итоге выбрал:
TimeUnit.NANOSECONDS.toMicros(System.nanoTime());
ОБНОВИТЬ:
Первоначально я выбрал System.nanoTime, но затем я обнаружил, что его следует использовать только в течение прошедшего времени, в конечном итоге я изменил свой код, чтобы он работал с миллисекундами или в некоторых местах использовал:
Документ явно говорит не использовать System.nanoTimeдля времени настенных часов: «Этот метод может быть использован только для измерения затраченного времени и не связан с каким - либо другим понятием системы или времени на стену часов.»
Basil Bourque
1
@BasilBourque, вы правы, написав это, я в конце концов узнал и изменил свой код, но забыл обновить здесь, спасибо за комментарий!
Это неверно, вы получите время в разрешении / длине MICRO, но само время всегда будет только с точностью MILI (то есть последние 3 цифры всегда будут равны 0).
Михалс,
0
Если вы собираетесь использовать его для системы реального времени, возможно, java не лучший выбор для получения отметки времени. Но если вы собираетесь использовать if для уникального ключа, ответа Джейсона Смита будет достаточно. Но на всякий случай, чтобы ожидать, что 2 элемента в конечном итоге получат одну и ту же метку времени (это возможно, если эти 2 обрабатывались почти одновременно), вы можете зацикливаться до тех пор, пока последняя метка времени не будет равна текущей метке времени.
Неправильный ответ. Класс java.util.Date имеет разрешение в миллисекунды, а не микросекунды, указанные в вопросе. Создание java.sql.Timestamp не приводит к извлечению дополнительных данных из воздуха.
Instant.now()
val instant = Instant.now();
val currentTimeMicros = instant.getEpochSecond() * 1000_000 + instant.getNano() / 1000;
Ответы:
Нет, у Java такой возможности нет.
У него есть System.nanoTime (), но он просто дает смещение от некоторого ранее известного времени. Таким образом, хотя вы не можете извлечь из этого абсолютное число, вы можете использовать его для измерения наносекундной (или более высокой) точности.
Обратите внимание, что в JavaDoc говорится, что хотя это обеспечивает точность в наносекунду, это не означает точность в наносекунду. Итак, возьмите какой-нибудь достаточно большой модуль возвращаемого значения.
источник
Clock
которая обеспечивает захват текущего момента с разрешением меньше миллисекунд. На MacBook Pro Retina я получаю текущее время в микросекундах (шесть цифр десятичной дроби). Фактические результаты и точность зависят от базового тактового оборудования главного компьютера.tl; dr
Java 9 и новее: разрешение до наносекунд при захвате текущего момента. Это 9 цифр десятичной дроби.
Чтобы ограничиться микросекундами , усеките .
На практике вы увидите только микросекунды, захваченные с помощью
.now
современных обычных компьютерных аппаратных часов, неточности в наносекундах .подробности
Другие ответы несколько устарели с Java 8.
java.time
Java 8 и более поздние версии поставляются с фреймворком java.time . Эти новые классы вытесняют ошибочные и проблемные классы времени и даты, поставляемые с самыми ранними версиями Java, такими как java.util.Date/.Calendar и java.text.SimpleDateFormat. Структура определяется JSR 310, вдохновленной Joda-Time , расширенной проектом ThreeTen-Extra.
Классы в java.time разрешаются в наносекунды , что намного меньше миллисекунд, используемых как старыми классами даты и времени, так и Joda-Time. И точнее микросекунд, заданных в Вопросе.
Clock
РеализацияХотя классы java.time поддерживают данные, представляющие значения в наносекундах, классы еще не генерируют значения в наносекундах. Эти
now()
методы используют ту же самую старую реализацию часов , как и старые классы даты и время,System.currentTimeMillis()
. У нас есть новыйClock
интерфейс в java.time, но реализация этого интерфейса - те же старые часы в миллисекундах.Таким образом, вы можете отформатировать текстовое представление результата,
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
чтобы увидеть девять цифр дробной секунды, но только первые три цифры будут иметь такие числа:Новые часы в Java 9
Реализации Java 9 в OpenJDK и Oracle имеют новую
Clock
реализацию по умолчанию с более высокой степенью детализации, вплоть до полной наносекундной возможности классов java.time.См. Проблему OpenJDK, Повышение точности реализации java.time.Clock.systemUTC () . Эта проблема успешно реализована.
На MacBook Pro (Retina, 15 дюймов, конец 2013 г.) с macOS Sierra я получаю текущий момент в микросекундах (до шести цифр десятичной дроби).
Аппаратные часы
Помните, что даже с новой более тонкой
Clock
реализацией ваши результаты могут отличаться в зависимости от компьютера. Java зависит от часов базового компьютерного оборудования, чтобы узнать текущий момент.источник
Clock
. Даже в этом случае в Java 8 классы java.time полезны для хранения значений, полученных из других источников, таких как микросекунды, в базе данных Postgres. Но остерегайтесь неточности значений в диапазоне микросекунд и наносекунд; обычное компьютерное оборудование может не обеспечивать точное отслеживание времени аппаратных часов. Значение с шестью или девятью цифрами дробной секунды может быть неверным.Вы можете использовать
System.nanoTime()
:чтобы получить время в наносекундах, но это строго относительная мера. Это не имеет абсолютного значения. Это полезно только для сравнения с другими нано-временами, чтобы измерить, сколько времени что-то потребовалось.
источник
Как уже указывалось на других плакатах; ваши системные часы, вероятно, не синхронизированы с текущим мировым временем с точностью до микросекунд. Тем не менее, это временные метки с точностью до микросекунд, которые можно использовать как гибрид как для индикации текущего времени на стене, так и для измерения / профилирования продолжительности событий.
Я помечаю все события / сообщения, записанные в файлы журнала, с помощью временных меток, например «2012-10-21 19: 13: 45.267128». Они передают время, когда это произошло (время «стены»), а также могут использоваться для измерения продолжительности между этим и следующим событием в файле журнала (относительная разница в микросекундах).
Для этого вам нужно связать System.currentTimeMillis () с System.nanoTime () и с этого момента работать исключительно с System.nanoTime (). Пример кода:
источник
MicroTimestamp.INSTANCE.get()
могут быть проблематичными.get()
методе нет ничего, что обновляло бы переменные-члены; он использует только временные локальные переменные.Возможно, вы могли бы создать компонент, который определяет смещение между System.nanoTime () и System.currentTimeMillis () и эффективно получать наносекунды с эпохи.
Следующий тест дал на моей машине довольно хорошие результаты.
Кажется, что разница колеблется в диапазоне + -3 мс. Думаю, можно было бы еще немного подправить расчет смещения.
источник
Если вас интересует Linux: если вы извлечете исходный код для «currentTimeMillis ()», вы увидите, что в Linux, если вы вызовете этот метод, он вернется на микросекунду назад. Однако Java затем усекает микросекунды и возвращает вам миллисекунды. Отчасти это связано с тем, что Java должна быть кроссплатформенной, поэтому предоставление методов специально для Linux было большим запретом в те времена (помните, что грубая поддержка софт-ссылок с версии 1.6 назад ?!). Это еще и потому, что, хотя ваши часы могут возвращать вам микросекунды в Linux, это не обязательно означает, что они подходят для проверки времени. На уровне микросекунд вам необходимо знать, что NTP не корректирует ваше время и что ваши часы не слишком сильно отклоняются во время вызовов методов.
Это означает, что теоретически в Linux вы можете написать оболочку JNI, такую же, как в пакете System, но не усекать микросекунды.
источник
«быстрое и грязное» решение, которое я в итоге выбрал:
ОБНОВИТЬ:
Первоначально я выбрал System.nanoTime, но затем я обнаружил, что его следует использовать только в течение прошедшего времени, в конечном итоге я изменил свой код, чтобы он работал с миллисекундами или в некоторых местах использовал:
но это просто добавит нули в конце значения (микрос = миллис * 1000)
Оставил этот ответ здесь как «предупреждающий знак» на случай, если кто-то еще подумает о nanoTime :)
источник
System.nanoTime
для времени настенных часов: «Этот метод может быть использован только для измерения затраченного времени и не связан с каким - либо другим понятием системы или времени на стену часов.»Поддержка микросекунд Java через
TimeUnit
enum.Вот java-документ: Enum TimeUnit
Вы можете получить микросекунды в java следующим образом:
Вы также можете преобразовать микросекунды обратно в другие единицы времени, например:
источник
Если вы собираетесь использовать его для системы реального времени, возможно, java не лучший выбор для получения отметки времени. Но если вы собираетесь использовать if для уникального ключа, ответа Джейсона Смита будет достаточно. Но на всякий случай, чтобы ожидать, что 2 элемента в конечном итоге получат одну и ту же метку времени (это возможно, если эти 2 обрабатывались почти одновременно), вы можете зацикливаться до тех пор, пока последняя метка времени не будет равна текущей метке времени.
источник
Используйте Instant для вычисления микросекунд с момента Epoch:
источник
источник
Вот пример того, как создать текущую метку времени UnsignedLong:
источник