ฉันจะนับมิลลิวินาทีตั้งแต่เที่ยงคืนสำหรับปัจจุบันได้อย่างไร


125

หมายเหตุฉันไม่ต้องการมิลลิวินาทีจากยุค ฉันต้องการจำนวนมิลลิวินาทีบนนาฬิกา

ตัวอย่างเช่นฉันมีรหัสนี้

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

มีวิธีรับมิลลิวินาทีพร้อมวันที่หรือไม่? มีวิธีอื่นในการทำเช่นนี้หรือไม่?

หมายเหตุ: System.currentTimeMillis()ให้เวลาเป็นมิลลิวินาทีจากยุคซึ่งไม่ใช่สิ่งที่ฉันกำลังมองหา


2
คุณหมายถึง "มิลลิวินาทีวินาทีในวินาที" ดังนั้นค่าจึงอยู่ในช่วงเวลาเสมอ[0, 999]ถูกต้อง? @thinksteep อ่านประโยคสุดท้าย
Matt Ball

@Lemonio การยกตัวอย่างจะทำให้คำถามของคุณชัดเจนยิ่งขึ้น
Basil Bourque

FYI คลาสวันที่และเวลาเก่าที่มีปัญหาเช่นjava.util.Dateตอนนี้เป็นแบบดั้งเดิมแทนที่ด้วยคลาสjava.time
Basil Bourque

FYI คลาสวันที่และเวลาเก่าที่มีปัญหาเช่นjava.util.Dateตอนนี้เป็นแบบดั้งเดิมแทนที่ด้วยคลาสjava.time ดูการสอนโดยออราเคิล
Basil Bourque

1
@ChrisNeve JEP 150รับรองโดยไบรอันเก๊ , JSR 310 เอกฉันท์เป็นบทความเทคนิคการตีพิมพ์โดย Oracle, และการเปลี่ยนเก่าวันเวลาของออราเคิลการสอนใหม่java.time กวดวิชา
Basil Bourque

คำตอบ:


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)ไม่ควรใช้ มักจะนึกถึงกรณีมุม!
Jon Skeet

และถ้าใครสักคนกำหนดเขตเวลาที่ไม่อยู่บนเส้นขอบที่สองหรือเพิ่มก้าวกระโดดเป็นมิลลิวินาทีนี้ =))
Markus Mikkolainen

35
Java ไม่รองรับการเดินทางข้ามเวลา
R.Martinho Fernandes

1
@MarkusMikkolainen: ไม่ System.currentTimeMillis()ไม่ไม่ได้รับผลกระทบจากเขตเวลา
Jon Skeet

1
@PeterLawrey: มันอาจจะหรือไม่ก็ได้ มันขึ้นอยู่กับการนำไปใช้งาน จากเอกสารสำหรับวันที่: "วินาทีจะแสดงด้วยจำนวนเต็มตั้งแต่ 0 ถึง 61 ค่า 60 และ 61 เกิดขึ้นเพียงวินาทีอธิกสุรทินเท่านั้นและในการใช้งาน Java เท่านั้นที่ติดตามอธิกวินาทีได้อย่างถูกต้องจริง ๆ เนื่องจากลักษณะการก้าวกระโดด มีการนำเสนอวินาทีในปัจจุบันไม่น่าเป็นไปได้อย่างยิ่งที่จะเกิดอธิกวินาทีสองวินาทีในนาทีเดียวกัน แต่ข้อกำหนดนี้เป็นไปตามข้อกำหนดวันที่และเวลาสำหรับ ISO C "
จอน Skeet

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; เว้นแต่จะมีใครบางคนมีเวลาก้าวกระโดดหรือบางปฏิทินกำหนดด้วยยุคที่ไม่อยู่ในขอบเขตที่สอง


ปฏิทินเป็นเวลาปัจจุบันตามค่าเริ่มต้นอยู่แล้วและไม่มีวินาทีที่มิลลิวินาที
kgautron


14

TL; DR

คุณขอเศษเสี้ยววินาทีของเวลาปัจจุบันเป็นจำนวนมิลลิวินาที ( ไม่นับจากยุค)

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วิธีการซักถามเพื่อหาค่าของTemporalField. ในกรณีของเราที่เราต้องการคือTemporalFieldChronoField.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, และCalendarSimpleDateFormat

โครงการJoda-Timeขณะนี้อยู่ในโหมดการบำรุงรักษาแนะนำการโยกย้ายไปยังคลาสjava.time

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย ข้อมูลจำเพาะคือJSR 310310

จะหาคลาส java.time ได้ที่ไหน?

  • Java SE 8และ SE 9และใหม่กว่า
    • Built-in
    • ส่วนหนึ่งของ Java API มาตรฐานพร้อมการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android

โครงการThreeTen-Extraขยาย java.time ด้วยคลาสเพิ่มเติม โปรเจ็กต์นี้เป็นพื้นที่พิสูจน์สำหรับการเพิ่ม java.time ในอนาคต คุณอาจพบว่าการเรียนที่มีประโยชน์บางอย่างที่นี่เช่นInterval, YearWeek, YearQuarterและอื่น ๆ อีกมากมาย


13

ฉันลองสองสามข้อด้านบน แต่ดูเหมือนว่าจะรีเซ็ต @ 1000

สิ่งนี้ได้ผลแน่นอนและควรคำนึงถึงปีด้วย

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

จากนั้นทำเช่นเดียวกันสำหรับเวลาสิ้นสุดหากจำเป็น


1
ตอบคำถามผิด นั่นคือมิลลิวินาทีปัจจุบันจากยุคไม่ใช่ส่วนมิลลิวินาทีของเวลาปัจจุบัน
Sean Van Gorder


3

Joda เวลา

ฉันคิดว่าคุณสามารถใช้Joda-Timeเพื่อทำสิ่งนี้ได้ ดูDateTimeคลาสและgetMillisOfSecondวิธีการ สิ่งที่ต้องการ

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

ข้อผิดพลาดในการคอมไพล์: " getMillis()has protected access"; จำเป็นต้องใช้get()แทน นอกจากนี้โปรดทราบว่าnew DateTime(new Date())เทียบเท่ากับการเขียนเพียงอย่างnew DateTime()เดียว
โจนิก

เมธอดmillisOfSecondเข้าถึงอ็อบเจ็กต์และการเรียกใช้เพิ่มเติมเพื่อgetดึงข้อมูลดั้งเดิมintจากอ็อบเจ็กต์นั้น getMillisOfSecondคุณสามารถยุบสองสายโดยใช้วิธีการความสะดวกสบายทะเยอทะยานที่ Joda-Time เป็นไปตามรูปแบบนี้สำหรับคุณสมบัติหลายประการ
Basil Bourque

1
FYI ตอนนี้โปรเจ็กต์Joda-Timeอยู่ในโหมดการบำรุงรักษาโดยทีมงานจะแนะนำการย้ายข้อมูลไปยังคลาสjava.time
Basil Bourque

0

ใน Java 8 คุณสามารถทำได้

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

ผลตอบแทน: จำนวนมิลลิวินาทีตั้งแต่ยุค 1970-01-01T00: 00: 00Z


1
[A] นี่ไม่ใช่สิ่งที่คำถามถาม กล่าวโดยชัดแจ้งว่าพวกเขาไม่ต้องการนับมิลลิวินาทีนับตั้งแต่วันที่อ้างอิงยุค [B] คุณสามารถทำให้สั้นลงได้โดยการวาง ZonedDateTime:Instant.now().toEpochMilli()
Basil Bourque

0

ฉันทำการทดสอบโดยใช้ java 8 มันไม่สำคัญว่าคำสั่งที่ตัวสร้างจะใช้เวลา 0 มิลลิวินาทีเสมอและการต่อกันระหว่าง 26 ถึง 33 มิลลิวินาทีภายใต้และการวนซ้ำของการเรียงต่อกัน 1,000 ครั้ง

หวังว่าจะช่วยให้ลองใช้กับอุดมคติของคุณ

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 และดังนั้นจึงไม่สามารถติดตามประเด็นโซนเวลาเหล่านี้
Basil Bourque

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));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.