Bagaimana cara mendapatkan tahun, bulan, hari, jam, menit, detik dan milidetik dari momen saat ini di Java?

104

Bagaimana saya bisa mendapatkan tahun, bulan, hari, jam, menit, detik dan milidetik dari momen saat ini di Java? Saya ingin mereka sebagai Strings.

Roma
sumber

Jawaban:

254

Anda dapat menggunakan getter dari java.time.LocalDateTimeuntuk itu.

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);

Atau, jika Anda belum menggunakan Java 8, manfaatkan 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);

Bagaimanapun, ini mencetak seperti yang sekarang:

2010-04-16 15: 15: 17.816

Untuk mengkonversi intke String, membuat penggunaan String#valueOf().


Jika tujuan Anda adalah setelah semua untuk mengatur dan menampilkan mereka dalam format string ramah manusia, maka lebih baik digunakan baik Java8 ini java.time.format.DateTimeFormatter( tutorial disini ),

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);

atau jika Anda belum menggunakan Java 8, gunakan 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);

Bagaimanapun, ini menghasilkan:

2010-04-16T15: 15: 17.816
Jum, 16 Apr 2010 15:15:17 GMT
20100416151517

Lihat juga:

BalusC
sumber
Jika Anda akan menggunakan printf maka Anda sebaiknya menggunakan format untuk Tanggal / Waktu daripada menggunakan langkah perantara yaitu "% 1 $ tm% 1 $ te,% 1 $ tY", c (lihat java.util. Pemformat untuk sintaks lengkap)
M. Jessup
1
@. Jessup: Itu memang lebih bagus. Namun saya tidak pernah menggunakannya, jadi saya tidak bisa memasukkannya dari atas kepala, di atas hanya untuk tujuan demo. Terlepas dari itu, saya lebih suka mengambil SimpleDateFormatatau DateTimeFormatteruntuk tugas khusus itu :)
BalusC
Saya sangat menyarankan menggunakan joda-time, karena API-nya jauh lebih baik dan mudah dimengerti dibandingkan dengan Tanggal dan Kalender yang dirancang dengan buruk yang ditawarkan Java secara langsung.
Kaitsu
Saya lebih suka yang ini, terutama dalam pekerjaan i18n untuk mendapatkan startTime atau endTime:new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).format(new Date());
Eddy
1
Sebagian besar fungsionalitas java.time di-back-port ke Java 6 & 7 dalam proyek ThreeTen-Backport .
Basil Bourque
30

Ganti ke joda-time dan Anda dapat melakukannya dalam tiga baris

DateTime jodaTime = new DateTime();

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

Anda juga memiliki akses langsung ke setiap bidang tanggal tanpa menggunakan Kalender.

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());

Outputnya adalah sebagai berikut:

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

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

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

Joda-Time adalah perpustakaan tanggal dan waktu standar de facto untuk Java. Dari Java SE 8 dan seterusnya, pengguna diminta untuk bermigrasi ke java.time (JSR-310).

Crowne
sumber
1
FYI, proyek Joda-Time sekarang sedang dalam pemeliharaan, dengan timnya menyarankan migrasi ke kelas java.time. Baik Joda-Time dan java.time dipimpin oleh orang yang sama, 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()));
blueberry0xff
sumber
Jawaban ini benar-benar menjawab Pertanyaan, yang menanyakan tentang mengakses komponen nilai tanggal-waktu (bukan string yang diformat seperti biasa).
Basil Bourque
6

Dengan Java 8 dan yang lebih baru, gunakan paket java.time .

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

ZonedDateTime.now()adalah metode statis yang mengembalikan tanggal-waktu saat ini dari jam sistem di zona waktu default. Semua metode get mengembalikan intnilai.

Ortomala Lokni
sumber
LocalDateTimeadalah kelas yang salah untuk ini. Karena tidak memiliki konsep zona waktu atau offset-dari-UTC, ini tidak dapat digunakan untuk melacak momen tertentu, ini bukan titik pada garis waktu. Gunakan Instant,, ZonedDateTimeatau OffsetDateTimesebagai gantinya.
Basil Bourque
Kamu benar. Saya telah mengubah jawaban saya untuk menggunakan 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

Untuk menangkap momen saat ini seperti yang terlihat pada waktu jam dinding yang digunakan oleh orang-orang di wilayah tertentu (zona waktu), gunakan ZonedDateTime.

Zona waktu sangat penting dalam menentukan tanggal. Untuk saat tertentu, tanggal bervariasi di seluruh dunia menurut zona. Misalnya, beberapa menit setelah tengah malam di Paris Prancis adalah hari baru sementara masih "kemarin" di Montréal Québec .

Jika tidak ada zona waktu yang ditentukan, JVM secara implisit menerapkan zona waktu default saat ini. Default tersebut dapat berubah setiap saat selama runtime (!), Jadi hasil Anda mungkin berbeda. Lebih baik menentukan zona waktu yang Anda inginkan / diharapkan secara eksplisit sebagai argumen.

Tentukan nama zona waktu yang tepat dalam format continent/region, seperti America/Montreal, Africa/Casablanca, atau Pacific/Auckland. Jangan pernah menggunakan singkatan 3-4 huruf seperti ESTatau ISTkarena itu bukan zona waktu yang sebenarnya, tidak standar, dan bahkan tidak unik (!).

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

Panggil salah satu dari banyak pengambil untuk menarik bagian dari tanggal-waktu.

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() ;

The java.time kelas memutuskan untuk nanodetik . Pertanyaan Anda menanyakan sepersekian detik dalam milidetik . Jelas, Anda dapat membagi dengan satu juta untuk memotong nanodetik menjadi milidetik, dengan mengorbankan kemungkinan kehilangan data. Atau gunakan TimeUnitenum untuk konversi tersebut.

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

DateTimeFormatter

Untuk menghasilkan Stringuntuk menggabungkan potongan teks, gunakan DateTimeFormatterclass. Cari Stack Overflow untuk info lebih lanjut tentang ini.

Instant

Biasanya paling baik untuk melacak momen dalam UTC. Untuk menyesuaikan dari tanggal-waktu yang dikategorikan ke UTC, ekstrak a Instant.

Instant instant = zdt.toInstant() ;

Dan kembali lagi.

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

LocalDateTime

Beberapa Jawaban lainnya menggunakan LocalDateTimekelas. Kelas tersebut tidak sesuai untuk tujuan melacak momen aktual, momen spesifik di timeline, karena kelas tersebut secara sengaja tidak memiliki konsep zona waktu atau offset-from-UTC.

Jadi apa LocalDateTimegunanya? Gunakan LocalDateTimejika Anda ingin menerapkan tanggal & waktu ke suatu tempat atau semua tempat , bukan di satu tempat tertentu.

Misalnya, Natal tahun ini dimulai pada LocalDateTime.parse( "2018-12-25T00:00:00" ). Nilai itu tidak ada artinya sampai Anda menerapkan zona waktu (a ZoneId) untuk mendapatkan a ZonedDateTime. Natal pertama kali terjadi di Kiribati , kemudian di Selandia Baru dan Asia Timur Jauh. Beberapa jam kemudian, Natal dimulai di India. Lebih jam kemudian di Afrika & Eropa. Dan masih belum Natal di Amerika sampai beberapa jam kemudian. Natal yang dimulai di satu tempat harus diwakili dengan ZonedDateTime. Natal dimana - mana diwakili dengan a LocalDateTime.


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 .

Anda dapat bertukar objek java.time langsung dengan database Anda. Gunakan driver JDBC yang sesuai dengan JDBC 4.2 atau yang lebih baru. Tidak perlu string, tidak perlu java.sql.*kelas.

Dimana mendapatkan kelas java.time?

Basil Bourque
sumber
2

Atau gunakan java.sql.Timestamp. Kalender agak berat, saya sarankan untuk tidak menggunakannya dalam kode produksi. Joda lebih baik.

import java.sql.Timestamp;

public class DateTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(new Timestamp(System.currentTimeMillis()));
    }
}
pavel
sumber
Saya pikir Anda salah paham baik pertanyaan dan penggunaan cap waktu sql. Anda biasanya menggunakan di new Date()sini. Tetapi bagaimana Anda bisa mendapatkan bagian-bagian terpisah darinya dengan mudah seperti yang diminta?
BalusC
FYI, java.sql.Timestampdigantikan oleh java.time.Instantkedatangan JDBC 4.2.
Basil Bourque
0

di java 7 Kalender satu baris

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(Calendar.getInstance().getTime())
Lucke
sumber
1
Kelas Kalender dan SimpleDateFormat yang merepotkan sekarang sudah usang, digantikan sepenuhnya oleh kelas java.time. Lihat Answer by BalusC untuk pendekatan modern. Sebagian besar fungsionalitas java.time di-back-port ke Java 6 & 7 dalam proyek ThreeTen-Backport .
Basil Bourque
-2

Lihat dokumentasi API untuk kelas java.util.Calendar dan turunannya (Anda mungkin tertarik secara khusus pada kelas GregorianCalendar).

M. Jessup
sumber
FYI, merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque
-2

Kalender sekarang = Kalender baru () // atau GregorianCalendar () baru, atau rasa apa pun yang Anda butuhkan

sekarang.MONTH sekarang.JAM

dll.

llappall
sumber
3
Hai, saya kesulitan memahami mengapa Anda mengulangi jawaban yang sudah diberikan dengan cara yang buruk. Harap jelaskan :)
BalusC
3
MONTHdan HOURmerupakan konstanta statis Calendar, bukan properti instance.
Joseph Earl