Làm thế nào tôi có thể có được số mili giây kể từ nửa đêm cho hiện tại?


124

Lưu ý, tôi KHÔNG muốn millis từ epoch. Tôi muốn số mili giây hiện tại trên đồng hồ.

Vì vậy, ví dụ, tôi có bit code này.

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

Có cách nào để có được mili giây với ngày không? Có một cách khác để làm điều này?

Lưu ý: System.currentTimeMillis() cung cấp cho tôi millis từ epoch không phải là thứ tôi đang tìm kiếm.


2
Ý bạn là, "mili giây trong giây", vậy giá trị luôn nằm trong khoảng [0, 999], đúng không? @thinksteep đọc câu cuối cùng.
Matt Ball

@Lemonio Đưa ra một ví dụ sẽ làm cho Câu hỏi của bạn rõ ràng hơn.
Basil Bourque

FYI, các lớp thời gian cũ rắc rối như java.util.Datebây giờ là di sản , được thay thế bởi các lớp java.time .
Basil Bourque

FYI, các lớp thời gian cũ rắc rối như java.util.Datebây giờ là di sản , được thay thế bởi các lớp java.time . Xem Hướng dẫn của Oracle .
Basil Bourque

1
@ChrisNeve JEP 150 được chứng thực bởi Brian Goetz , JSR 310 đã thông qua , một bài viết kỹ thuật được xuất bản bởi Oracle và thay thế Hướng dẫn Oracle thời gian cũ bằng Hướng dẫn java.time mới .
Basil Bourque

Câu trả lời:


197

Ý bạn là?

long millis = System.currentTimeMillis() % 1000;

BTW Windows không cho phép thời gian biểu đến năm 1969

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

8
Lưu ý rằng nếu bạn du hành ngược thời gian đến trước thời đại Unix, điều này sẽ mang lại giá trị âm trong khi c.get(Calendar.MILLISECOND)không nên sử dụng . Luôn luôn nghĩ về các trường hợp góc!
Jon Skeet

và nếu ai đó xác định múi giờ không ở biên thứ hai hoặc thêm một bước nhảy trong một phần nghìn giây thì sẽ phá vỡ. =))
Markus Mikkolainen

35
Java không hỗ trợ du hành thời gian.
R. Martinho Fernandes

1
@MarkusMikkolainen: Không, System.currentTimeMillis()không bị ảnh hưởng bởi múi giờ.
Jon Skeet

1
@PeterLawrey: Vâng, nó có thể hoặc không. Đó là tùy thuộc vào việc thực hiện. Từ các tài liệu cho Ngày: "Một giây được biểu thị bằng một số nguyên từ 0 đến 61; các giá trị 60 và 61 chỉ xảy ra trong giây nhuận và thậm chí sau đó chỉ trong các triển khai Java thực sự theo dõi bước nhảy vọt chính xác. Vì cách thức nhảy vọt Hiện tại giây được giới thiệu, rất khó có khả năng hai giây nhuận sẽ xảy ra trong cùng một phút, nhưng thông số kỹ thuật này tuân theo các quy ước ngày và giờ cho ISO C. "
Jon Skeet

24

Sử dụng lịch

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

hoặc là

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

Trong thực tế mặc dù tôi nghĩ rằng nó sẽ gần như luôn luôn bằng System.cienTimeMillis ()% 1000; trừ khi ai đó có bước nhảy vọt trong một phần nghìn giây hoặc một số lịch được xác định với một epoch không nằm trên ranh giới thứ hai.


Lịch đã là thời gian hiện tại theo mặc định và không có s tại MILLISECOND.
kgautron


13

tl; dr

Bạn yêu cầu tỷ lệ một giây của thời gian hiện tại là một số mili giây ( không tính từ kỷ nguyên).

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

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

  1. Lấy giây thứ hai tính bằng nano giây (tỷ).
  2. Chia cho một nghìn để cắt ngắn đến mili giây (hàng ngàn).

Xem này chạy trực tiếp tại IdeOne.com .

Sử dụng java.time

Cách hiện đại là với các lớp java.time.

Ghi lại khoảnh khắc hiện tại trong UTC.

Instant.now()

Sử dụng Instant.getphương pháp để thẩm vấn giá trị của a TemporalField. Trong trường hợp của chúng tôi, TemporalFieldchúng tôi muốn là ChronoField.MILLI_OF_SECOND.

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

Hoặc tự làm toán.

Nhiều khả năng bạn đang yêu cầu điều này cho một múi giờ cụ thể. Phần của một giây có thể giống như với Instantnhưng có quá nhiều dị thường với các múi giờ, tôi ngần ngại đưa ra giả định đó.

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

Thắc mắc cho phân đoạn thứ hai. Câu hỏi yêu cầu mili giây , nhưng các lớp java.time sử dụng độ phân giải nano giây tốt hơn . Điều đó có nghĩa là số lượng nano giây sẽ nằm trong khoảng từ 0 đến 999.999.999.

long nanosFractionOfSecond = zdt.getNano();

Nếu bạn thực sự muốn một phần nghìn giây, hãy cắt bớt dữ liệu tốt hơn bằng cách chia cho một triệu. Ví dụ: nửa giây là 500.000.000 nano giây và cũng là 500 mili giây.

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

Giới thiệu về java.time

Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date, Calendar, &SimpleDateFormat .

Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.

Để tìm hiểu thêm, xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Nơi để có được các lớp java.time?

  • Java SE 8 SE 9 trở lên
    • Được xây dựng trong.
    • Một phần của API Java tiêu chuẩn với việc triển khai đi kèm.
    • Java 9 thêm một số tính năng nhỏ và sửa lỗi.
  • Java SE 6 SE 7
    • Phần lớn chức năng java.time được chuyển ngược lại sang Java 6 & 7 trong ThreeTen-Backport .
  • Android

Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là một nền tảng chứng minh cho các bổ sung có thể trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval, YearWeek, YearQuarter, và nhiều hơn nữa .


12

Tôi đã thử một vài cái ở trên nhưng chúng dường như đặt lại @ 1000

Điều này chắc chắn hoạt động, và cũng nên xem xét năm

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

và sau đó làm tương tự cho thời gian kết thúc nếu cần.


1
Trả lời sai câu hỏi. Đó là millis hiện tại từ epoch, không phải là millis của thời điểm hiện tại.
Sean Van Gorder

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

Thứ Sáu 04 Tháng Tư 14:27:05 PDT 2014


2

Joda-Thời gian

Tôi nghĩ bạn có thể sử dụng Joda-Time để làm điều này. Hãy nhìn vào DateTimelớp và getMillisOfSecondphương pháp của nó . Cái gì đó như

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

Lỗi biên dịch: " getMillis()có quyền truy cập được bảo vệ"; cần sử dụng get()thay thế. Cũng lưu ý rằng new DateTime(new Date())tương đương với viết đơn giản new DateTime().
Jonik

Phương thức millisOfSecondtruy cập một đối tượng và gọi thêm để gettrích xuất một nguyên thủy inttừ đối tượng đó. Bạn có thể thu gọn hai cuộc gọi bằng phương thức getter tiện lợi , getMillisOfSecond. Joda-Time theo mô hình này cho nhiều thuộc tính của nó.
Basil Bourque

1
FYI, dự án Joda-Time hiện đang ở chế độ bảo trì , với nhóm tư vấn di chuyển đến các lớp java.time .
Basil Bourque

0

Trong Java 8, bạn có thể chỉ cần làm

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

trả về: số mili giây kể từ kỷ nguyên 1970-01-01T00: 00: 00Z


1
[A] Đây không phải là những gì Câu hỏi yêu cầu. Rõ ràng nói rằng họ không muốn đếm một phần nghìn giây kể từ ngày tham chiếu kỷ nguyên. [B] Bạn có thể rút ngắn điều đó bằng cách bỏ ZencedDateTime:Instant.now().toEpochMilli()
Basil Bourque

0

Tôi đã thực hiện thử nghiệm bằng java 8 Không có vấn đề gì khi trình xây dựng luôn mất 0 mili giây và concat trong khoảng từ 26 đến 33 mili giây và lặp lại 1000 lần ghép

Hy vọng nó sẽ giúp thử nó với ide của bạn

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
Không hoạt động trong một số múi giờ. Ở một số khu vực, vào một số ngày, ngày có thể không bắt đầu lúc 00:00:00. Và ngày có thể không dài 24 giờ, có thể thêm hoặc bỏ qua vài giờ hoặc vài phút. Các LocalDateTimelớp không thể đại diện cho một thời điểm, thiếu bất kỳ khái niệm về múi giờ hoặc bù đắp-từ-UTC, và do đó không thể theo dõi những vấn đề múi giờ.
Basil Bourque

0

Bạn có thể sử dụng lớp java.util.CalWiki để có thời gian tính bằng mili giây. Thí dụ:

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));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.