Як я можу отримати лічильник мілісекунд з півночі на струм?


125

Зауважте, я не хочу мільйони з епохи. Я хочу кількість мілісекунд в даний час.

Так, наприклад, у мене є цей біт коду.

Date date2 = new Date(); 
Long time2 = (long) (((((date2.getHours() * 60) + date2.getMinutes())* 60 ) + date2.getSeconds()) * 1000);

Чи є спосіб отримати мілісекунди з датою? Чи є інший спосіб зробити це?

Примітка: System.currentTimeMillis() дає мені мілі з епохи, що не є те, що я шукаю.


2
Ви маєте на увазі "мілісекунди в секунду", тому значення завжди знаходиться в інтервалі [0, 999], правильно? @thinksteep прочитав останнє речення.
Метт Бал

@Lemonio Надаючи приклад, зробить ваше запитання більш зрозумілим.
Василь Бурк

FYI, старі класи, java.util.Dateякі зараз неспокійні, такі, як зараз, застарілі , замінені класами java.time .
Василь Бурк

FYI, старі класи, java.util.Dateякі зараз неспокійні, такі, як зараз, застарілі , замінені класами java.time . Дивіться Підручник від Oracle .
Василь Бурк

1
@ChrisNeve JEP 150, схвалений Брайаном Гецем , JSR 310 прийнято одноголосно , технічну статтю, опубліковану Oracle, та заміну старого навчального посібника Oracle для дат на новий навчальний посібник java.time .
Василь Бурк

Відповіді:


198

Ти маєш на увазі?

long millis = System.currentTimeMillis() % 1000;

BTW Windows не дозволяє проводити час до 1969 року

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.

8
Зауважте, що якщо ви повернетесь у часі до епохи Unix, це дасть негативне значення, тоді як використання c.get(Calendar.MILLISECOND)не повинно. Завжди думайте про кутові справи!
Джон Скіт

і якщо хтось визначить часовий пояс не на другому кордоні або додасть стрибкову мілісекунду, це порушується. =))
Markus Mikkolainen

35
Java не підтримує подорож у часі.
Р. Мартіньо Фернандес

1
@MarkusMikkolainen: Ні, System.currentTimeMillis()не впливає часовий пояс.
Джон Скіт

1
@PeterLawrey: Ну, а може, і не може. Це до реалізації. З Документів для дати: "Секунда представлена ​​цілим числом від 0 до 61; значення 60 і 61 трапляються лише протягом стрибних секунд і навіть тоді лише в реалізаціях Java, які насправді відстежують стрибкові секунди правильно. Через спосіб, у якому стрибок В даний час вводяться секунди, вкрай малоймовірно, що в одну і ту ж хвилину відбудуться дві високосні секунди, але ця специфікація відповідає умовам дати та часу для ISO C. "
Джон Скіт

25

Використовуйте календар

Calendar.getInstance().get(Calendar.MILLISECOND);

або

Calendar c=Calendar.getInstance();
c.setTime(new Date()); /* whatever*/
//c.setTimeZone(...); if necessary
c.get(Calendar.MILLISECOND);

На практиці, хоча я думаю, це майже завжди дорівнює System.currentTimeMillis ()% 1000; якщо у когось немає стрибків-мілісекунд або якийсь календар визначений епохою не на другій межі.


За замовчуванням у календаря вже поточний час, а в MILLISECOND немає s.
kgautron


14

тл; д-р

Ви запитуєте частку секунди поточного часу як кількість мілісекунд ( не рахуючи з епохи).

Instant.now()                               // Get current moment in UTC, then…
       .get( ChronoField.MILLI_OF_SECOND )  // interrogate a `TemporalField`.

2017-04-25T03: 01: 14.113Z → 113

  1. Отримайте дробову секунду в наносекундах (мільярдах).
  2. Розділіть на тисячу, щоб усікати до мілісекунд (тисяч).

Дивіться цей код, який виконується на веб-сайті IdeOne.com .

Використання java.time

Сучасний спосіб - з класами java.time.

Захопіть поточний момент у UTC.

Instant.now()

Використовуйте Instant.getметод для допиту на значення a TemporalField. У нашому випадку TemporalFieldми прагнемо ChronoField.MILLI_OF_SECOND.

int millis = Instant.now().get( ChronoField.MILLI_OF_SECOND ) ;  // Get current moment in UTC, then interrogate a `TemporalField`.

Або займайтеся математикою самостійно.

Швидше за все, ви запитуєте це для певного часового поясу. Частка секунди, ймовірно, буде такою самою, як і з, Instantале є дуже багато аномалій з часовими поясами, я вагаюся, щоб зробити це припущення.

ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) ) ;

Допитуйте на дробову секунду. Питання вимагає мілісекунд , але класи java.time використовують більш точну роздільну здатність наносекунд . Це означає, що кількість наносекунд буде варіюватися від 0 до 999,999,999.

long nanosFractionOfSecond = zdt.getNano();

Якщо ви справді хочете мілісекунди, обріжте найтонші дані, поділивши їх на мільйон. Наприклад, півтори секунди - 500 000 000 наносекунд, а також 500 мілісекунд.

long millis = ( nanosFractionOfSecond / 1_000_000L ) ;  // Truncate nanoseconds to milliseconds, by a factor of one million.

Про java.time

Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date, Calendar, і SimpleDateFormat.

Проект Joda-Time , який зараз знаходиться в режимі обслуговування , радить перейти до класів java.time .

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

Де отримати класи java.time?

  • Java SE 8 та SE 9 та новіші версії
    • Вбудований.
    • Частина стандартного Java API з пакетною реалізацією.
    • Java 9 додає деякі незначні функції та виправлення.
  • Java SE 6 і SE 7
    • Значна частина функцій java.time повертається до Java 6 і 7 у ThreeTen-Backport .
  • Android

Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є доказом можливих майбутніх доповнень до java.time. Тут ви можете знайти кілька корисних занять, наприклад Interval,YearWeek , YearQuarter, і більш .


13

Я спробував кілька вище, але вони, схоже, скидаються @ 1000

Цей, безумовно, працює, і також повинен враховувати рік

long millisStart = Calendar.getInstance().getTimeInMillis();

а потім зробіть те ж саме для кінця часу, якщо потрібно.


1
Відповідаючи на неправильне запитання. Це поточні мілі з епохи, а не частина мілісу поточного часу.
Sean Van Gorder


3

Joda-Time

Я думаю, ви можете використовувати Joda-Time для цього. Погляньте на DateTimeклас та його getMillisOfSecondметод. Щось на зразок

int ms = new DateTime().getMillisOfSecond() ;

Помилка компіляції: " getMillis()захистив доступ"; потрібно використовувати get()замість цього. Також зауважте, що new DateTime(new Date())рівносильно писати просто new DateTime().
Джонік

Метод millisOfSecondдоступу до об'єкта і подальший виклик для getвилучення примітиву intз цього об'єкта. Ви можете згорнути два виклики з допомогою методу геттер зручності getMillisOfSecond. Joda-Time слідує цій схемі для багатьох своїх властивостей.
Василь Бурк

1
FYI, проект Joda-Time зараз перебуває в режимі обслуговування , команда радить перейти до класів java.time .
Василь Бурк

0

У Java 8 можна просто зробити

ZonedDateTime.now().toInstant().toEpochMilli()

повертає: кількість мілісекунд з епохи 1970-01-01T00: 00: 00Z


1
[A] Це не запитання. Відверто зазначає, що вони не хочуть рахувати мілісекунд з дати відліку епохи. [B] Ви можете скоротити це, скинувши ZonedDateTime:Instant.now().toEpochMilli()
Василь Бурк

0

Я робив тест, використовуючи java 8. Не важливо, в чому порядок будівельника завжди займає 0 мілісекунд, а присадка між 26 та 33 мілісекундами під ітерацією 1000 конкатенації

Сподіваюся, що це допоможе спробувати його з ідеєю

public void count() {

        String result = "";

        StringBuilder builder = new StringBuilder();

        long millis1 = System.currentTimeMillis(),
            millis2;

        for (int i = 0; i < 1000; i++) {
            builder.append("hello world this is the concat vs builder test enjoy");
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));

        millis1 = System.currentTimeMillis();

        for (int i = 0; i < 1000; i++) {
            result += "hello world this is the concat vs builder test enjoy";
        }

        millis2 = System.currentTimeMillis();

        System.out.println("Diff: " + (millis2 - millis1));
    }

0

Java 8:

LocalDateTime toDate = LocalDateTime.now();
LocalDateTime fromDate = LocalDateTime.of(toDate.getYear(), toDate.getMonth(), 
toDate.getDayOfMonth(), 0, 0, 0);
long millis = ChronoUnit.MILLIS.between(fromDate, toDate);

1
Не працює в деяких часових поясах. У деяких зонах в деякі дати день може не починатися о 00:00:00. І день може не тривати 24 години, може додавати або пропускати кілька годин або хвилин. LocalDateTimeКлас не може являти собою момент, не вистачає якоїсь - або концепції тимчасової зони або офсетним через UTC, і , отже , не може відстежувати ці проблеми часових поясів.
Василь Бурк

0

Ви можете використовувати клас java.util.Calendar, щоб отримати час у мілісекундах. Приклад:

Calendar cal = Calendar.getInstance();
int milliSec = cal.get(Calendar.MILLISECOND);
// print milliSec

java.util.Date date = cal.getTime();
System.out.println("Output: " +  new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(date));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.