Jak mogę obliczyć liczbę milisekund od północy dla prądu?

125

Uwaga, NIE chcę milis z epoki. Chcę podać liczbę milisekund aktualnie wyświetlanych na zegarze.

Na przykład mam ten kawałek kodu.

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

Czy jest sposób, aby uzyskać milisekundy z datą? Czy jest inny sposób, aby to zrobić?

Uwaga: System.currentTimeMillis() daje mi milis od epoki, której nie szukam.

Lemonio
źródło
2
Masz na myśli „milisekundy na sekundę”, więc wartość jest zawsze w przedziale [0, 999], prawda? @thinksteep przeczytaj ostatnie zdanie.
Matt Ball
@Lemonio Podanie przykładu uczyniłoby Twoje pytanie bardziej zrozumiałym.
Basil Bourque
FYI, kłopotliwe stare klasy daty i czasu, takie jak java.util.Dateobecnie starsze , zastąpione przez klasy java.time .
Basil Bourque
FYI, kłopotliwe stare klasy daty i czasu, takie jak java.util.Dateobecnie starsze , zastąpione przez klasy java.time . Zobacz samouczek firmy Oracle .
Basil Bourque
1
@ChrisNeve JEP 150 zatwierdzony przez Brian Goetz , JSR 310 przyjęta jednogłośnie , a artykuł techniczny opublikowany przez Oracle i wymiana starej daty i czasu Oracle Tutorial z nowym java.time Tutorial .
Basil Bourque

Odpowiedzi:

198

Czy masz na myśli?

long millis = System.currentTimeMillis() % 1000;

BTW Windows nie pozwala na podróż do 1969 roku

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.
Peter Lawrey
źródło
8
Zauważ, że jeśli cofniesz się w czasie do czasów sprzed epoki Uniksa, da to wartość ujemną, podczas gdy używanie c.get(Calendar.MILLISECOND)nie powinno. Zawsze myśl o narożnikach!
Jon Skeet
a jeśli ktoś definiuje strefę czasową nie na drugiej granicy lub dodaje milisekundę przestępną, to się zrywa. =))
Markus Mikkolainen
35
Java nie obsługuje podróży w czasie.
R. Martinho Fernandes
1
@MarkusMikkolainen: Nie, System.currentTimeMillis()strefy czasowe nie mają na nie wpływu.
Jon Skeet
1
@PeterLawrey: Cóż, może lub nie. To zależy od wdrożenia. Z dokumentacji dotyczącej daty: „Sekundę reprezentuje liczba całkowita od 0 do 61; wartości 60 i 61 występują tylko dla sekund przestępnych, a nawet wtedy tylko w implementacjach Java, które faktycznie śledzą sekundy przestępne. Ze względu na sposób, w jaki skok sekund są obecnie wprowadzane, jest bardzo mało prawdopodobne, aby dwie sekundy przestępne wystąpiły w tej samej minucie, ale ta specyfikacja jest zgodna z konwencjami dotyczącymi daty i czasu dla ISO C. ”
Jon Skeet
25

Użyj kalendarza

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

lub

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

W praktyce myślę, że prawie zawsze będzie równa System.currentTimeMillis ()% 1000; chyba że ktoś ma milisekundy przestępne lub jakiś kalendarz jest zdefiniowany z epoką nie znajdującą się na drugiej granicy.

Markus Mikkolainen
źródło
Kalendarz ma już domyślnie aktualny czas i nie ma go w MILLISECOND.
kgautron
17
Calendar.getInstance().get(Calendar.MILLISECOND);
kgautron
źródło
14

tl; dr

Pytasz o ułamek sekundy bieżącego czasu jako liczbę milisekund ( nie licząc od epoki).

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

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

  1. Uzyskaj ułamek sekundy w nanosekundach (miliardy).
  2. Podziel przez tysiąc, aby skrócić do milisekund (tysięcy).

Zobacz, jak działa ten kod na IdeOne.com .

Korzystanie z java.time

Współczesnym sposobem są klasy java.time.

Uchwyć aktualny moment w UTC.

Instant.now()

Użyj Instant.getmetody, aby zapytać o wartość TemporalField. W naszym przypadku TemporalFieldchcemy ChronoField.MILLI_OF_SECOND.

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

Lub zrób obliczenia samodzielnie.

Bardziej prawdopodobne jest, że pytasz o to dla określonej strefy czasowej. Ułamek sekundy prawdopodobnie będzie taki sam, jak w przypadku, Instantale jest tak wiele anomalii w strefach czasowych, że waham się czy przyjąć takie założenie.

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

Zapytaj o ułamek sekundy. Pytanie zadawano milisekund , ale klasy java.time używają dokładniejszej rozdzielczości nanosekund . Oznacza to, że liczba nanosekund będzie wynosić od 0 do 999 999 999.

long nanosFractionOfSecond = zdt.getNano();

Jeśli naprawdę potrzebujesz milisekund, skróć dokładniejsze dane, dzieląc je przez milion. Na przykład pół sekundy to 500 000 000 nanosekund, a także 500 milisekund.

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

Informacje o java.time

Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date, Calendar, i SimpleDateFormat.

Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .

Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .

Skąd wziąć klasy java.time?

Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .

Basil Bourque
źródło
13

Wypróbowałem kilka powyżej, ale wydają się resetować @ 1000

Ten zdecydowanie działa i powinien również uwzględniać rok

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

a następnie w razie potrzeby zrób to samo z czasem zakończenia.

Kreator dużego kalibru
źródło
1
Odpowiadając na złe pytanie. To bieżące milis od epoki, a nie miliskowa część obecnego czasu.
Sean Van Gorder
5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Pt, 4 kwietnia, 14:27:05 czasu PDT 2014

omarflorez
źródło
3

Joda-Time

Myślę, że możesz do tego użyć Joda-Time . Przyjrzyj się DateTimeklasie i jej getMillisOfSecondmetodzie. Coś jak

int ms = new DateTime().getMillisOfSecond() ;
RNJ
źródło
Błąd kompilacji: „ getMillis()ma chroniony dostęp”; trzeba użyć get()zamiast tego. Zauważ też, że new DateTime(new Date())jest to równoznaczne z prostym pisaniem new DateTime().
Jonik
Metoda millisOfSeconduzyskuje dostęp do obiektu i dalsze wywołanie getwyodrębnia prymityw intz tego obiektu. Można zwinąć dwa połączenia przy użyciu metody getter wygoda, getMillisOfSecond. Joda-Time podąża za tym wzorem dla wielu swoich właściwości.
Basil Bourque
1
FYI, projekt Joda-Time jest teraz w trybie konserwacji , a zespół doradza migrację do klas java.time .
Basil Bourque
0

W Javie 8 możesz to po prostu zrobić

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

zwraca: liczbę milisekund od epoki 1970-01-01T00: 00: 00Z

Aniket Thakur
źródło
1
[A] Nie o to chodzi w pytaniu. Wyraźnie mówi, że nie chcą odliczać milisekund od daty odniesienia epoki. [B] Możesz to skrócić, upuszczając ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque,
0

Zrobiłem test używając java 8 Nie ma znaczenia kolejność, w której budowniczy zawsze zajmuje 0 milisekund, a konkatacja między 26 a 33 milisekundami poniżej i iteracja konkatenacji 1000

Mam nadzieję, że pomoże ci to wypróbować z twoim ID

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));
    }
Aldo Infanzon
źródło
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);
Efren Villamagua
źródło
1
Nie działa w niektórych strefach czasowych. W niektórych strefach, w niektóre dni, dzień może nie zaczynać się o 00:00:00. A dzień może nie trwać 24 godziny, może wydłużyć lub pominąć kilka godzin lub minut. LocalDateTimeKlasa nie może reprezentować chwilę, pozbawiona koncepcję strefy czasowej lub przesunięcia-z czasem UTC, a zatem nie mogą śledzić te problemy strefy czasowej.
Basil Bourque
0

Aby uzyskać czas w milisekundach, można użyć klasy java.util.Calendar. Przykład:

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));
Rajat
źródło