Akıntı için gece yarısından bu yana geçen milisaniye sayısını nasıl alabilirim?


125

Not, çağdan milis istemiyorum. Şu anda saatteki milisaniye sayısını istiyorum.

Örneğin, bu biraz kodum var.

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

Tarihle milisaniye almanın bir yolu var mı? Bunu yapmanın başka bir yolu var mı?

Not: System.currentTimeMillis() Bana aradığım şey olmayan çağdan milisaniye verir.


2
Yani "saniyede milisaniye" demek istiyorsun, yani değer her zaman aralıktadır [0, 999], değil mi? @thinksteep son cümleyi oku.
Matt Ball

@Lemonio Bir örnek vermek, Sorunuzu daha net hale getirir.
Basil Bourque

Bilginize, java.time sınıfları tarafından değiştirilen java.util.Date, artık miras kalan , zahmetli eski tarih-saat sınıfları.
Basil Bourque

Bilginize, java.time sınıfları tarafından değiştirilen java.util.Date, artık miras kalan , zahmetli eski tarih-saat sınıfları. Oracle'ın Eğitimi bölümüne bakın .
Fesleğen Bourque

1
Brian Goetz tarafından onaylanan @ChrisNeve JEP 150 , oybirliğiyle kabul edilen JSR 310 , Oracle tarafından yayınlanan teknik bir makale ve eski tarih-zaman Oracle Eğitimi'nin yeni java.time Eğitimi ile değiştirilmesi .
Basil Bourque

Yanıtlar:


198

Demek istiyorsun

long millis = System.currentTimeMillis() % 1000;

BTW Windows 1969'a kadar zaman yolculuğuna izin vermiyor

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

8
Unix döneminden önceye kadar zamanda geriye giderseniz, bunun negatif bir değer vereceğini, kullanmanın c.get(Calendar.MILLISECOND)vermemesi gerektiğini unutmayın. Her zaman köşe kasaları düşünün!
Jon Skeet

ve birisi ikinci sınırda olmayan bir saat dilimi tanımlarsa veya bir artık milisaniye eklerse, bu
kesilir

35
Java, zamanda yolculuğu desteklemez.
R. Martinho Fernandes

1
@MarkusMikkolainen: Hayır, System.currentTimeMillis()saat dilimlerinden etkilenmez.
Jon Skeet

1
@PeterLawrey: Olabilir veya olmayabilir. Uygulamaya kalmış. Tarih için dokümanlardan: "Bir saniye, 0 ile 61 arasında bir tamsayı ile temsil edilir; 60 ve 61 değerleri yalnızca artık saniyeler için ve o zaman bile yalnızca artık saniyeleri doğru bir şekilde izleyen Java uygulamalarında ortaya çıkar. Sıçrama biçiminden dolayı Saniyeler şu anda tanıtıldı, aynı dakikada iki artık saniyenin meydana gelmesi son derece düşük bir ihtimaldir, ancak bu belirtim ISO C için tarih ve saat kurallarına uyar. "
Jon Skeet

25

Takvimi Kullan

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

veya

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

Pratikte neredeyse her zaman System.currentTimeMillis ()% 1000'e eşit olacağını düşünüyorum; birisi artık milisaniyeye sahip değilse veya bazı takvim ikinci sınırda olmayan bir çağla tanımlanmadıkça.


Takvim varsayılan olarak zaten şimdiki zamandır ve MILLISECOND'da hiç s yoktur.
kgautron


14

tl; Dr.

Sen (milisaniye sayısı olarak şimdiki zamanın bir saniyenin fraksiyonu sormak değil çağdan sayım).

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

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

  1. Nanosaniye cinsinden kesirli saniyeyi (milyarlarca) alın.
  2. Milisaniyeye (bin) kesmek için bine bölün.

Bu koda IdeOne.com'da canlı olarak bakın .

Java.time kullanma

Modern yöntem java.time sınıflarıdır.

Geçerli anı UTC olarak yakalayın.

Instant.now()

Instant.getA'nın değerini sorgulamak için yöntemi kullanın TemporalField. Bizim durumumuzda TemporalFieldistediğimiz şey ChronoField.MILLI_OF_SECOND.

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

Veya matematiği kendiniz yapın.

Büyük ihtimalle bunu belirli bir saat dilimi için soruyorsunuz. Saniyenin kesri büyük olasılıkla aynı olacaktır, Instantancak zaman dilimlerinde çok fazla anormallik var, bu varsayımı yapmaktan çekiniyorum.

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

Kesirli saniye için sorgulayın. Soru milisaniye olarak soruldu , ancak java.time sınıfları nanosaniye gibi daha hassas bir çözünürlük kullanıyor . Bu, nanosaniye sayısının 0 ile 999.999.999 arasında değişeceği anlamına gelir.

long nanosFractionOfSecond = zdt.getNano();

Gerçekten milisaniye istiyorsanız, daha ince verileri bir milyona bölerek kesin. Örneğin, yarım saniye 500.000.000 nanosaniye ve ayrıca 500 milisaniyedir.

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

Java.time hakkında

Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date, Calendar& SimpleDateFormat.

Şu anda bakım modunda olan Joda-Time projesi, java.time sınıflarına geçişi tavsiye ediyor .

Daha fazla bilgi edinmek için Oracle Eğitimi'ne bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .

Java.time derslerini nereden edinebilirim?

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time uygulamasına gelecekteki olası eklemeler için kanıtlayıcı bir zemindir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


13

Yukarıdakilerden birkaçını denedim ama @ 1000'de sıfırlanıyor gibi görünüyor

Bu kesinlikle işe yarıyor ve yılı da dikkate almalı

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

ve gerekirse bitiş zamanı için aynısını yapın.


1
Yanlış soruyu cevaplamak. Bu çağın şu anki mili, şimdiki zamanın mili değil.
Sean Van Gorder

5
  1. long timeNow = System.currentTimeMillis();
  2. System.out.println(new Date(timeNow));

04 Nisan Cuma 14:27:05 PDT 2014


3

Joda-Time

Bunu yapmak için Joda-Time'ı kullanabileceğinizi düşünüyorum . DateTimeSınıfa ve getMillisOfSecondyöntemine bir göz atın . Gibi bir şey

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

Derleme hatası: " getMillis()korumalı erişime sahip"; get()bunun yerine kullanmanız gerekir . Ayrıca, new DateTime(new Date())bunun basitçe yazmaya eşdeğer olduğunu unutmayın new DateTime().
Jonik

Yöntem millisOfSecondbir nesneye erişir ve sonraki çağrı o nesneden getbir ilkeli çıkarır int. Rahatlık getirici yöntemini kullanarak iki çağrıyı daraltabilirsiniz getMillisOfSecond. Joda-Time, özelliklerinin çoğu için bu modeli takip eder.
Basil Bourque

1
Bilginize, Joda-Time projesi şu anda bakım modunda ve ekip java.time sınıflarına geçişi tavsiye ediyor .
Basil Bourque

0

Java 8'de şunları yapabilirsiniz:

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

döndürür: 1970-01-01T00: 00: 00Z döneminden bu yana geçen milisaniye sayısı


1
[A] Sorunun istediği bu değil . Dönem referans tarihinden bu yana milisaniye sayısını istemediklerini açıkça söylüyorlar . [B] ZonedDateTime'ı bırakarak bunu kısaltabilirsiniz:Instant.now().toEpochMilli()
Basil Bourque

0

Testi java 8 kullanarak yaptım Oluşturucunun her zaman 0 milisaniye aldığı sıra ve 26 ila 33 milisaniye arasındaki birleştirme ve 1000 bitiştirmenin yinelemesi önemli değil

Umarım fikrinizle denemeye yardımcı olur

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
Bazı saat dilimlerinde çalışmaz. Bazı bölgelerde, bazı tarihlerde gün 00: 00: 00'da başlamayabilir. Ve gün 24 saat uzun olmayabilir, birkaç saat veya dakika ekleyebilir veya atlayabilir. LocalDateTimeSınıf bu saat dilimi sorunlarını izleyemez nedenle zaman dilimine herhangi bir kavram eksik, bir an temsil veya ofset-den-UTC ve olamaz.
Basil Bourque

0

Milisaniye cinsinden zaman almak için java.util.Calendar sınıfını kullanabilirsiniz. Misal:

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));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.