Làm cách nào để lấy năm, tháng, ngày, giờ, phút, giây và mili giây của thời điểm hiện tại trong Java?


104

Làm cách nào để lấy năm, tháng, ngày, giờ, phút, giây và mili giây của thời điểm hiện tại trong Java? Tôi muốn có chúng như Strings.

Câu trả lời:


254

Bạn có thể sử dụng getters của java.time.LocalDateTimecho điều đó.

LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
int millis = now.get(ChronoField.MILLI_OF_SECOND); // Note: no direct getter available.

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);

Hoặc, khi bạn chưa sử dụng Java 8, hãy tận dụng java.util.Calendar.

Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH) + 1; // Note: zero based!
int day = now.get(Calendar.DAY_OF_MONTH);
int hour = now.get(Calendar.HOUR_OF_DAY);
int minute = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);
int millis = now.get(Calendar.MILLISECOND);

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);

Dù bằng cách nào, bản in này kể từ bây giờ:

2010-04-16 15: 15: 17.816

Để chuyển đổi một intthành String, hãy sử dụng String#valueOf().


Nếu ý định của bạn là sau khi tất cả để sắp xếp và hiển thị chúng trong một định dạng chuỗi thân thiện với con người, sử dụng sau đó tốt hơn hoặc Java8 của java.time.format.DateTimeFormatter( hướng dẫn ở đây ),

LocalDateTime now = LocalDateTime.now();
String format1 = now.format(DateTimeFormatter.ISO_DATE_TIME);
String format2 = now.atZone(ZoneId.of("GMT")).format(DateTimeFormatter.RFC_1123_DATE_TIME);
String format3 = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss", Locale.ENGLISH));

System.out.println(format1);
System.out.println(format2);
System.out.println(format3);

hoặc khi bạn chưa sử dụng Java 8, hãy sử dụng java.text.SimpleDateFormat:

Date now = new Date(); // java.util.Date, NOT java.sql.Date or java.sql.Timestamp!
String format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(now);
String format2 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH).format(now);
String format3 = new SimpleDateFormat("yyyyMMddHHmmss", Locale.ENGLISH).format(now);

System.out.println(format1);
System.out.println(format2);
System.out.println(format3);

Dù bằng cách nào, điều này mang lại:

2010-04-16T15: 15: 17.816
T6, 16/04/2010 15:15:17 GMT
20100416151517

Xem thêm:


Nếu bạn định sử dụng printf thì bạn cũng có thể chỉ sử dụng các định dạng cho Ngày / Giờ thay vì sử dụng bước trung gian, tức là "% 1 $ tm% 1 $ te,% 1 $ tY", c (xem java.util. Định dạng cho cú pháp đầy đủ)
M. Jessup

1
@M. Jessup: Điều đó thực sự đẹp hơn. Tuy nhiên, tôi chưa bao giờ sử dụng nó, vì vậy tôi không thể nhập nó từ đầu, ở trên chỉ dành cho mục đích demo. Bất kể, tôi muốn lấy SimpleDateFormathoặc DateTimeFormattercho nhiệm vụ cụ thể đó :)
BalusC

Tôi thực sự khuyên bạn nên sử dụng joda-time, vì API của nó đẹp hơn và dễ hiểu hơn nhiều so với Ngày và Lịch được thiết kế tồi mà Java cung cấp trực tiếp.
Kaitsu

Tôi thích cái này hơn, đặc biệt là trong i18n làm việc để có startTime hoặc endTime:new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).format(new Date());
Eddy

1
Phần lớn chức năng java.time được chuyển ngược sang Java 6 & 7 trong dự án ThreeTen-Backport .
Basil Bourque

30

Chuyển sang joda-time và bạn có thể làm điều này trong ba dòng

DateTime jodaTime = new DateTime();

DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS");
System.out.println("jodaTime = " + formatter.print(jodaTime));

Bạn cũng có quyền truy cập trực tiếp vào các trường riêng lẻ của ngày mà không cần sử dụng Lịch.

System.out.println("year = " + jodaTime.getYear());
System.out.println("month = " + jodaTime.getMonthOfYear());
System.out.println("day = " + jodaTime.getDayOfMonth());
System.out.println("hour = " + jodaTime.getHourOfDay());
System.out.println("minute = " + jodaTime.getMinuteOfHour());
System.out.println("second = " + jodaTime.getSecondOfMinute());
System.out.println("millis = " + jodaTime.getMillisOfSecond());

Đầu ra như sau:

jodaTime = 2010-04-16 18:09:26.060

year = 2010
month = 4
day = 16
hour = 18
minute = 9
second = 26
millis = 60

Theo http://www.joda.org/joda-time/

Joda-Time là thư viện ngày và giờ chuẩn trên thực tế cho Java. Từ Java SE 8 trở đi, người dùng được yêu cầu chuyển sang java.time (JSR-310).


1
FYI, dự án Joda-Time hiện đang được bảo trì, với nhóm của nó tư vấn chuyển sang các lớp java.time. Cả Joda-Time và java.time đều được dẫn dắt bởi cùng một người đàn ông, Stephen Colebourne.
Basil Bourque

7
    // Java 8
    System.out.println(LocalDateTime.now().getYear());       // 2015
    System.out.println(LocalDateTime.now().getMonth());      // SEPTEMBER
    System.out.println(LocalDateTime.now().getDayOfMonth()); // 29
    System.out.println(LocalDateTime.now().getHour());       // 7
    System.out.println(LocalDateTime.now().getMinute());     // 36
    System.out.println(LocalDateTime.now().getSecond());     // 51
    System.out.println(LocalDateTime.now().get(ChronoField.MILLI_OF_SECOND)); // 100

    // Calendar
    System.out.println(Calendar.getInstance().get(Calendar.YEAR));         // 2015
    System.out.println(Calendar.getInstance().get(Calendar.MONTH ) + 1);   // 9
    System.out.println(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); // 29
    System.out.println(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));  // 7
    System.out.println(Calendar.getInstance().get(Calendar.MINUTE));       // 35
    System.out.println(Calendar.getInstance().get(Calendar.SECOND));       // 32
    System.out.println(Calendar.getInstance().get(Calendar.MILLISECOND));  // 481

    // Joda Time
    System.out.println(new DateTime().getYear());           // 2015
    System.out.println(new DateTime().getMonthOfYear());    // 9
    System.out.println(new DateTime().getDayOfMonth());     // 29
    System.out.println(new DateTime().getHourOfDay());      // 7
    System.out.println(new DateTime().getMinuteOfHour());   // 19
    System.out.println(new DateTime().getSecondOfMinute()); // 16
    System.out.println(new DateTime().getMillisOfSecond()); // 174

    // Formatted
    // 2015-09-28 17:50:25.756
    System.out.println(new Timestamp(System.currentTimeMillis()));

    // 2015-09-28T17:50:25.772
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(new Date()));

    // Java 8
    // 2015-09-28T17:50:25.810
    System.out.println(LocalDateTime.now());

    // joda time
    // 2015-09-28 17:50:25.839
    System.out.println(DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS").print(new org.joda.time.DateTime()));

Câu trả lời này thực sự giải quyết Câu hỏi, hỏi về việc truy cập các thành phần của giá trị ngày-giờ (không phải các chuỗi được định dạng thông thường).
Basil Bourque

6

Với Java 8 trở lên, hãy sử dụng gói java.time .

ZonedDateTime.now().getYear();
ZonedDateTime.now().getMonthValue();
ZonedDateTime.now().getDayOfMonth();
ZonedDateTime.now().getHour();
ZonedDateTime.now().getMinute();
ZonedDateTime.now().getSecond();

ZonedDateTime.now()là một phương thức tĩnh trả về ngày-giờ hiện tại từ đồng hồ hệ thống trong múi giờ mặc định. Tất cả các phương thức get đều trả về một intgiá trị.


LocalDateTimechính xác là lớp sai cho điều này. Thiếu bất kỳ khái niệm nào về múi giờ hoặc chênh lệch từ UTC, nó không thể được sử dụng để theo dõi một thời điểm cụ thể, nó không phải là một điểm trên dòng thời gian. Sử dụng Instant, ZonedDateTimehoặc OffsetDateTimethay thế.
Basil Bourque vào

Bạn đúng. Tôi đã sửa đổi câu trả lời của mình để sử dụng a ZonedDateTime.
Ortomala Lokni

3

tl; dr

ZonedDateTime.now(                    // Capture current moment as seen in the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "America/Montreal" )   // Specify desired/expected time zone. Or pass `ZoneId.systemDefault` for the JVM’s current default time zone.
)                                     // Returns a `ZonedDateTime` object.
.getMinute()                          // Extract the minute of the hour of the time-of-day from the `ZonedDateTime` object.

42

ZonedDateTime

Để ghi lại khoảnh khắc hiện tại theo giờ đồng hồ treo tường được sử dụng bởi người dân của một khu vực cụ thể (một múi giờ), hãy sử dụng ZonedDateTime .

Múi giờ rất quan trọng trong việc xác định ngày. Đối với bất kỳ thời điểm nhất định nào, ngày thay đổi trên toàn cầu theo khu vực. Ví dụ: một vài phút sau nửa đêm ở Paris Pháp là một ngày mới trong khi vẫn là "ngày hôm qua" ở Montréal Québec .

Nếu không có múi giờ nào được chỉ định, JVM sẽ áp dụng hoàn toàn múi giờ mặc định hiện tại của nó. Mặc định đó có thể thay đổi bất kỳ lúc nào trong thời gian chạy (!), Vì vậy kết quả của bạn có thể thay đổi. Tốt hơn là chỉ định múi giờ mong muốn / dự kiến của bạn một cách rõ ràng làm đối số.

Chỉ định một tên múi giờ thích hợp trong các định dạng của continent/region, chẳng hạn như America/Montreal, Africa/Casablancahoặc Pacific/Auckland. Không bao giờ sử dụng từ viết tắt 3-4 chữ cái, chẳng hạn như ESThoặc ISTvì chúng không phải là múi giờ thực, không được tiêu chuẩn hóa và thậm chí không phải là duy nhất (!).

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

Gọi cho bất kỳ người nào trong số rất nhiều người để lấy ra các phần của ngày-giờ.

int    year        = zdt.getYear() ;
int    monthNumber = zdt.getMonthValue() ;
String monthName   = zdt.getMonth().getDisplayName( TextStyle.FULL , Locale.JAPAN ) ;  // Locale determines human language and cultural norms used in localizing. Note that `Locale` has *nothing* to do with time zone.
int    dayOfMonth  = zdt.getDayOfMonth() ;
String dayOfWeek   = zdt.getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 
int    hour        = zdt.getHour() ;  // Extract the hour from the time-of-day.
int    minute      = zdt.getMinute() ;
int    second      = zdt.getSecond() ;
int    nano        = zdt.getNano() ;

Các lớp java.time phân giải thành nano giây . Câu hỏi của bạn yêu cầu phần giây tính bằng mili giây . Rõ ràng, bạn có thể chia cho một triệu để cắt ngắn nano giây thành mili giây, với chi phí có thể mất dữ liệu. Hoặc sử dụng TimeUnitenum để chuyển đổi như vậy.

long millis = TimeUnit.NANOSECONDS.toMillis( zdt.getNano() ) ;

DateTimeFormatter

Để tạo ra một Stringkết hợp các phần văn bản, hãy sử dụng DateTimeFormatterlớp. Tìm kiếm Stack Overflow để biết thêm thông tin về điều này.

Instant

Thường tốt nhất để theo dõi các khoảnh khắc trong giờ UTC. Để điều chỉnh từ ngày-giờ được khoanh vùng thành UTC, hãy trích xuất a Instant.

Instant instant = zdt.toInstant() ;

Và quay lại lần nữa.

ZonedDateTime zdt = instant.atZone( ZoneId.of( "Africa/Tunis" ) ) ;

LocalDateTime

Một số Câu trả lời khác sử dụng LocalDateTimelớp. Lớp đó không phù hợp với mục đích theo dõi những khoảnh khắc thực tế, những khoảnh khắc cụ thể trên dòng thời gian, vì nó cố ý thiếu bất kỳ khái niệm nào về múi giờ hoặc khoảng chênh lệch từ UTC.

Vậy LocalDateTimetốt để làm gì? Sử dụng LocalDateTimekhi bạn định áp dụng ngày và giờ cho bất kỳ địa phương nào hoặc tất cả các địa phương , thay vì một địa phương cụ thể.

Ví dụ: Giáng sinh năm nay bắt đầu lúc LocalDateTime.parse( "2018-12-25T00:00:00" ). Giá trị đó không có ý nghĩa cho đến khi bạn áp dụng múi giờ (a ZoneId) để nhận được a ZonedDateTime. Giáng sinh diễn ra đầu tiên ở Kiribati , sau đó ở New Zealand và vùng viễn đông châu Á. Vài giờ sau, Giáng sinh bắt đầu ở Ấn Độ. Nhiều giờ sau ở Châu Phi & Châu Âu. Và vẫn chưa Xmas ở châu Mỹ cho đến vài giờ sau đó. Giáng sinh bắt đầu trong bất kỳ một vị trí nên được đại diện với ZonedDateTime. Giáng sinh ở khắp mọi nơi được đại diện bằng a LocalDateTime.


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, hãy xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow để có nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của mình. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*lớp.

Lấy các lớp java.time ở đâu?


2

Hoặc sử dụng java.sql.Timestamp. Lịch khá nặng, tôi khuyên bạn không nên sử dụng nó trong mã sản xuất. Joda tốt hơn.

import java.sql.Timestamp;

public class DateTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(new Timestamp(System.currentTimeMillis()));
    }
}

Tôi nghĩ rằng bạn đã hiểu sai cả câu hỏi và việc sử dụng dấu thời gian sql. Bạn thường sử dụng new Date()ở đây. Nhưng làm thế nào bạn có thể lấy các bộ phận riêng biệt từ nó một cách dễ dàng theo yêu cầu?
BalusC

FYI, java.sql.Timestampđược thay thế bởi java.time.Instantsự xuất hiện của JDBC 4.2.
Basil Bourque

0

trong java 7 Lịch một dòng

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(Calendar.getInstance().getTime())

1
Các lớp Lịch và SimpleDateFormat rắc rối hiện đã lỗi thời, được thay thế hoàn toàn bởi các lớp java.time. Xem Câu trả lời của BalusC để biết cách tiếp cận hiện đại. Phần lớn chức năng java.time được chuyển ngược sang Java 6 & 7 trong dự án ThreeTen-Backport .
Basil Bourque


-2

Lịch bây giờ = lịch mới () // hoặc GregorianCalendar () mới, hoặc bất kỳ hương vị nào bạn cần

ngay bây giờ.MONTH ngay bây giờ.HOUR

Vân vân.


3
Xin chào, tôi rất khó hiểu tại sao bạn lại lặp lại câu trả lời đã cho một cách kém duyên. Xin vui lòng giải thích :)
BalusC

3
MONTHHOURlà các hằng số tĩnh của Calendar, không phải thuộc tính cá thể.
Joseph Earl
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.