Bagaimana saya bisa menghitung milidetik sejak tengah malam untuk saat ini?

125

Catatan, saya TIDAK ingin milis dari zaman. Saya ingin jumlah milidetik saat ini di jam.

Jadi misalnya, saya memiliki sedikit kode ini.

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

Adakah cara untuk mendapatkan milidetik dengan tanggal? Apakah ada cara lain untuk melakukan ini?

Catatan: System.currentTimeMillis() beri saya milis dari zaman yang bukan itu yang saya cari.

Lemonio
sumber
2
Maksud Anda, "milidetik dalam detik", jadi nilainya selalu dalam interval [0, 999], benar? @thinksteep membaca kalimat terakhir.
Matt Ball
@Lemonio Memberi contoh akan membuat Pertanyaan Anda lebih jelas.
Basil Bourque
FYI, kelas tanggal-waktu lama yang merepotkan seperti java.util.Datesekarang sudah lama , digantikan oleh kelas java.time .
Basil Bourque
FYI, kelas tanggal-waktu lama yang merepotkan seperti java.util.Datesekarang sudah lama , digantikan oleh kelas java.time . Lihat Tutorial oleh Oracle .
Basil Bourque
1
@ChrisNeve JEP 150 didukung oleh Brian Goetz , JSR 310 diadopsi dengan suara bulat , artikel teknis yang diterbitkan oleh Oracle, dan penggantian Tutorial Oracle tanggal-waktu lama dengan Tutorial java.time baru .
Basil Bourque

Jawaban:

198

Maksudmu?

long millis = System.currentTimeMillis() % 1000;

BTW Windows tidak mengizinkan penjadwalan perjalanan ke 1969

C:\> date
Enter the new date: (dd-mm-yy) 2/8/1969
The system cannot accept the date entered.
Peter Lawrey
sumber
8
Perhatikan bahwa jika Anda melakukan perjalanan kembali ke masa sebelum zaman Unix, ini akan memberikan nilai negatif sedangkan menggunakan c.get(Calendar.MILLISECOND)tidak boleh. Selalu pikirkan kasus sudut!
Jon Skeet
dan jika seseorang menentukan zona waktu bukan di perbatasan kedua atau menambahkan lompatan-milidetik ini akan rusak. =))
Markus Mikkolainen
35
Jawa tidak mendukung perjalanan waktu.
R. Martinho Fernandes
1
@MarkusMikkolainen: Tidak, System.currentTimeMillis()tidak terpengaruh oleh zona waktu.
Jon Skeet
1
@ PeterLawrey: Ya, mungkin atau tidak. Terserah implementasinya. Dari dokumen untuk Tanggal: "Detik diwakili oleh bilangan bulat dari 0 hingga 61; nilai 60 dan 61 hanya terjadi untuk detik kabisat dan bahkan kemudian hanya dalam implementasi Java yang benar-benar melacak detik kabisat dengan benar. Karena cara lompatan detik saat ini diperkenalkan, sangat kecil kemungkinannya dua detik kabisat akan terjadi pada menit yang sama, tetapi spesifikasi ini mengikuti konvensi tanggal dan waktu untuk ISO C. "
Jon Skeet
25

Gunakan Kalender

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

atau

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

Dalam prakteknya saya pikir itu hampir selalu sama dengan System.currentTimeMillis ()% 1000; kecuali seseorang memiliki lompatan-milidetik atau beberapa kalender ditentukan dengan zaman bukan pada batas kedua.

Markus Mikkolainen
sumber
Kalender sudah menggunakan waktu saat ini secara default, dan tidak ada pada MILLISECOND.
kgautron
17
Calendar.getInstance().get(Calendar.MILLISECOND);
kgautron.dll
sumber
14

tl; dr

Anda meminta sepersekian detik waktu saat ini sebagai jumlah milidetik ( tidak dihitung dari masa).

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

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

  1. Dapatkan pecahan sekon dalam nanodetik (milyaran).
  2. Bagilah dengan seribu untuk dipotong menjadi milidetik (ribuan).

Lihat kode ini ditayangkan langsung di IdeOne.com .

Menggunakan java.time

Cara modern adalah dengan kelas java.time.

Tangkap momen saat ini dalam UTC.

Instant.now()

Gunakan Instant.getmetode untuk menginterogasi nilai a TemporalField. Dalam kasus kami, yang TemporalFieldkami inginkan adalah ChronoField.MILLI_OF_SECOND.

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

Atau lakukan matematika sendiri.

Kemungkinan besar Anda menanyakan ini untuk zona waktu tertentu. Sepersekian detik kemungkinan besar sama dengan Instanttetapi ada begitu banyak anomali dengan zona waktu, saya ragu untuk membuat asumsi itu.

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

Interogasi untuk pecahan detik. Pertanyaan menanyakan milidetik , tetapi kelas java.time menggunakan resolusi nanodetik yang lebih halus . Itu berarti jumlah nanodetik akan berkisar dari 0 hingga 999.999.999.

long nanosFractionOfSecond = zdt.getNano();

Jika Anda benar-benar menginginkan milidetik, potong data yang lebih halus dengan membaginya dengan satu juta. Misalnya, setengah detik adalah 500.000.000 nanodetik dan juga 500 milidetik.

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

Tentang java.time

The java.time kerangka dibangun ke Jawa 8 dan kemudian. Kelas-kelas ini menggantikan tua merepotkan warisan kelas tanggal-waktu seperti java.util.Date, Calendar, & SimpleDateFormat.

Proyek Joda-Time , sekarang dalam mode pemeliharaan , menyarankan migrasi ke kelas java.time .

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle . Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasinya adalah JSR 310 .

Di mana mendapatkan kelas java.time?

Proyek ThreeTen-Extra memperluas java.time dengan kelas tambahan. Proyek ini adalah tempat pembuktian untuk kemungkinan penambahan java.time di masa mendatang. Anda mungkin menemukan beberapa kelas berguna di sini seperti Interval, YearWeek, YearQuarter, dan lebih .

Basil Bourque
sumber
13

Saya mencoba beberapa yang di atas tetapi tampaknya mengatur ulang @ 1000

Yang ini pasti berhasil, dan juga harus mempertimbangkan tahun ke dalam pertimbangan

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

lalu lakukan hal yang sama untuk waktu berakhir jika diperlukan.

Penyihir Kaliber Tinggi
sumber
1
Menjawab pertanyaan yang salah. Itu adalah milidetik saat ini dari zaman, bukan milidetik dari waktu saat ini.
Sean Van Gorder
5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

Jum 04 Apr 14:27:05 PDT 2014

omarflorez.dll
sumber
3

Waktu Joda

Saya pikir Anda dapat menggunakan Joda-Time untuk melakukan ini. Lihatlah DateTimekelas dan getMillisOfSecondmetodenya. Sesuatu seperti

int ms = new DateTime().getMillisOfSecond() ;
RNJ
sumber
Kesalahan kompilasi: " getMillis()memiliki akses yang dilindungi"; perlu digunakan get()sebagai gantinya. Juga perhatikan bahwa new DateTime(new Date())sama dengan menulis sederhana new DateTime().
Jonik
Metode millisOfSecondmengakses objek dan panggilan selanjutnya untuk getmengekstrak primitif intdari objek itu. Anda bisa menciutkan kedua panggilan menggunakan metode pengambil kemudahan getMillisOfSecond,. Joda-Time mengikuti pola ini untuk banyak propertinya.
Basil Bourque
1
FYI, proyek Joda-Time sekarang dalam mode pemeliharaan , dengan tim menyarankan migrasi ke kelas java.time .
Basil Bourque
0

Di Java 8 Anda bisa melakukannya

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

mengembalikan: jumlah milidetik sejak periode 1970-01-01T00: 00: 00Z

Aniket Thakur
sumber
1
[A] Ini bukanlah pertanyaan yang ditanyakan. Secara tegas mengatakan mereka tidak menginginkan hitungan milidetik sejak tanggal referensi periode. [B] Anda dapat mempersingkatnya dengan menghapus ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque
0

Saya melakukan tes menggunakan java 8 Tidak masalah urutan pembangun selalu membutuhkan 0 milidetik dan concat antara 26 dan 33 milidetik di bawah dan iterasi 1000 penggabungan

Semoga membantu mencobanya dengan ide Anda

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
sumber
0

Jawa 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
sumber
1
Tidak berfungsi di beberapa zona waktu. Di beberapa zona, pada beberapa tanggal, hari mungkin tidak dimulai pada 00:00:00. Dan hari itu mungkin tidak 24 jam, bisa menambah atau melewati beberapa jam atau menit. The LocalDateTimekelas tidak dapat mewakili beberapa saat, kurang setiap konsep zona waktu atau offset-dari-UTC, dan karena itu tidak dapat melacak masalah zona waktu ini.
Basil Bourque
0

Anda dapat menggunakan kelas java.util.Calendar untuk mendapatkan waktu dalam milidetik. Contoh:

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
sumber