Как я могу узнать количество миллисекунд с полуночи для текущего?

125

Заметьте, я НЕ хочу миллис от эпохи. Мне нужно текущее количество миллисекунд на часах.

Так, например, у меня есть этот фрагмент кода.

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

Есть ли способ получить миллисекунды с датой? Есть ли другой способ сделать это?

Примечание: System.currentTimeMillis() дает мне миллисекунд эпохи, а это не то, что я ищу.

Lemonio
источник
2
Вы имеете в виду «миллисекунды в секунду», поэтому значение всегда находится в интервале [0, 999], правильно? @thinksteep прочитал последнее предложение.
Мэтт Болл
@Lemonio Если вы приведете пример, ваш вопрос станет более ясным.
Basil Bourque
К вашему сведению, неприятные старые классы даты и времени, такие как java.util.Dateтеперь унаследованные , вытеснены классами java.time .
Basil
К вашему сведению, неприятные старые классы даты и времени, такие как java.util.Dateтеперь унаследованные , вытеснены классами java.time . См. Учебник Oracle .
Basil
1
@ChrisNeve JEP 150, одобренный Брайаном Гетцем , единогласно принятый JSR 310 , техническая статья, опубликованная Oracle, и замена старого учебника Oracle с указанием даты на новый учебник java.time .
Basil Bourque

Ответы:

198

Ты имеешь ввиду?

long millis = System.currentTimeMillis() % 1000;

Кстати, 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)не должно. Всегда думайте о крайних случаях!
Джон Скит
и если кто-то определяет часовой пояс не на второй границе или добавляет високосную миллисекунду, это прерывается. =))
Маркус Микколайнен 02
35
Java не поддерживает путешествия во времени.
Р. Мартиньо Фернандес
1
@MarkusMikkolainen: Нет, System.currentTimeMillis()часовые пояса не влияют.
Джон Скит
1
@PeterLawrey: Может быть, а может и нет. Это зависит от реализации. Из документов для Date: «Секунда представлена ​​целым числом от 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 нет.
kgautron 02
17
Calendar.getInstance().get(Calendar.MILLISECOND);
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();

Если вам действительно нужны миллисекунды, обрежьте более точные данные, разделив их на миллион. Например, полсекунды - это 500000000 наносекунд, а также 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 Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310 .

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .

Василий Бурк
источник
13

Я пробовал несколько из вышеперечисленных, но они, кажется, сбрасывают @ 1000

Это определенно работает, и также следует учитывать год

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

а затем при необходимости сделайте то же самое для времени окончания.

Мастер высокого калибра
источник
1
Отвечая на неправильный вопрос. Это текущие миллисекунды от эпохи, а не миллисекунды текущего времени.
Шон Ван Гордер,
5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Пт, 04 апреля, 14:27:05 PDT 2014

omarflorez
источник
3

Joda времени

Думаю, для этого можно использовать Joda-Time . Взгляните на DateTimeкласс и его getMillisOfSecondметод. Что-то вроде

int ms = new DateTime().getMillisOfSecond() ;
RNJ
источник
Ошибка компиляции: « getMillis()имеет защищенный доступ»; нужно использовать get()вместо этого. Также обратите внимание, что new DateTime(new Date())это эквивалентно простому письму new DateTime().
Jonik
Метод millisOfSecondобращается к объекту, и последующий вызов getизвлекает примитив intиз этого объекта. Вы можете свернуть два вызова, используя удобный метод получения getMillisOfSecond. Joda-Time следует этому шаблону во многих своих свойствах.
Basil Bourque
1
К вашему сведению, проект Joda-Time сейчас находится в режиме обслуживания , и команда советует перейти на классы java.time .
Basil
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));
Раджу
источник