วิธีการรับปีเดือนวันชั่วโมงนาทีวินาทีและมิลลิวินาทีของช่วงเวลาปัจจุบันใน Java?


104

ฉันจะหาปีเดือนวันชั่วโมงนาทีวินาทีและมิลลิวินาทีของช่วงเวลาปัจจุบันใน Java ได้อย่างไร Stringsผมอยากจะมีพวกเขาเป็น

คำตอบ:


255

คุณสามารถใช้ getters java.time.LocalDateTimeสำหรับสิ่งนั้น

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

หรือเมื่อคุณยังไม่ได้ใช้ Java 8 ให้ใช้ประโยชน์จาก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);

ไม่ว่าจะด้วยวิธีใดสิ่งนี้จะพิมพ์ ณ ตอนนี้:

2010-04-16 15: 15: 17.816

แปลงintที่จะใช้ประโยชน์จากStringString#valueOf()


หากเจตนาของคุณคือหลังจากทั้งหมดจะจัดให้มีและแสดงไว้ในรูปแบบสตริงของมนุษย์ที่เป็นมิตรใช้แล้วดีขึ้นทั้ง Java8 ของjava.time.format.DateTimeFormatter( กวดวิชาที่นี่ )

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

หรือเมื่อคุณยังไม่ได้ใช้ Java 8 ให้ใช้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);

ไม่ว่าจะด้วยวิธีใดสิ่งนี้ให้ผล:

2010-04-16T15: 15: 17.816
ศ. 16 เมษายน 2010 15:15:17 GMT
20100416151517

ดูสิ่งนี้ด้วย:


หากคุณกำลังจะใช้ printf คุณอาจใช้รูปแบบสำหรับ Date / Times แทนการใช้ขั้นตอนตัวกลางเช่น "% 1 $ tm% 1 $ te,% 1 $ tY", c (ดู java.util ตัวจัดรูปแบบสำหรับไวยากรณ์แบบเต็ม)
M. Jessup

1
@ ม. Jessup: นั่นดีกว่าจริงๆ อย่างไรก็ตามฉันไม่เคยใช้เลยดังนั้นฉันจึงไม่สามารถป้อนจากด้านบนของศีรษะด้านบนเป็นเพียงเพื่อการสาธิตเท่านั้น ไม่ว่าฉันอยากจะคว้าSimpleDateFormatหรือDateTimeFormatterเพื่องานนั้น ๆ :)
BalusC

ฉันขอแนะนำอย่างยิ่งให้ใช้ joda-time เนื่องจาก API ที่ดีกว่าและเข้าใจได้มากเมื่อเทียบกับวันที่และปฏิทินที่ออกแบบมาไม่ดีที่ Java เสนอโดยตรง
Kaitsu

ฉันชอบอันนี้โดยเฉพาะในงาน i18n เพื่อรับ startTime หรือ endTime:new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).format(new Date());
Eddy

1
มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับโครงการ
Basil Bourque

30

เปลี่ยนเป็นjoda-timeและคุณสามารถทำได้ในสามบรรทัด

DateTime jodaTime = new DateTime();

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

คุณยังสามารถเข้าถึงแต่ละฟิลด์ของวันที่ได้โดยตรงโดยไม่ต้องใช้ปฏิทิน

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

ผลลัพธ์มีดังนี้:

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

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

อ้างอิงจากhttp://www.joda.org/joda-time/

Joda-Time เป็นไลบรารีวันที่และเวลามาตรฐานโดยพฤตินัยสำหรับ Java ตั้งแต่ Java SE 8 เป็นต้นไประบบจะขอให้ผู้ใช้ย้ายไปที่ java.time (JSR-310)


1
FYI โครงการ Joda-Time อยู่ในระหว่างการบำรุงรักษาโดยทีมงานจะให้คำแนะนำในการโยกย้ายไปยังคลาส java.time ทั้ง Joda-Time และ java.time นำโดยชายคนเดียวกัน 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()));

คำตอบนี้ตอบคำถามซึ่งถามเกี่ยวกับการเข้าถึงส่วนประกอบของค่าวันที่ - เวลา (ไม่ใช่สตริงที่จัดรูปแบบตามปกติ)
Basil Bourque

6

ด้วย Java 8 และต่อมาใช้แพคเกจ java.time

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

ZonedDateTime.now()เป็นวิธีการคงที่ที่ส่งคืนวันที่ - เวลาปัจจุบันจากนาฬิการะบบในไทม์โซนเริ่มต้น เมธอด get ทั้งหมดส่งคืนintค่า


LocalDateTimeเป็นคลาสที่ไม่ถูกต้องสำหรับสิ่งนี้ ไม่มีแนวคิดเกี่ยวกับเขตเวลาหรือ offset-from-UTC จึงไม่สามารถใช้เพื่อติดตามช่วงเวลาที่เฉพาะเจาะจงได้จึงไม่ใช่จุดบนไทม์ไลน์ การใช้งานInstant, ZonedDateTimeหรือOffsetDateTimeแทน
Basil Bourque

คุณถูก. ฉันได้แก้ไขคำตอบให้ใช้ไฟล์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

การจับภาพขณะปัจจุบันเท่าที่เห็นในเวลาผนังนาฬิกาที่ใช้โดยผู้คนในภูมิภาคโดยเฉพาะ (โซนเวลา), ZonedDateTimeการใช้งาน

เขตเวลามีความสำคัญอย่างยิ่งในการกำหนดวันที่ ในแต่ละช่วงเวลาวันที่จะแตกต่างกันไปทั่วโลกตามโซน ยกตัวอย่างเช่นไม่กี่นาทีหลังเที่ยงคืนในกรุงปารีสประเทศฝรั่งเศสเป็นวันใหม่ขณะที่ยังคง“เมื่อวานนี้” ในมอนทรีออควิเบก

หากไม่ได้ระบุเขตเวลา JVM จะใช้โซนเวลาเริ่มต้นปัจจุบันโดยปริยาย ค่าเริ่มต้นนั้นอาจเปลี่ยนแปลงได้ตลอดเวลาระหว่างรันไทม์ (!) ดังนั้นผลลัพธ์ของคุณอาจแตกต่างกันไป ควรระบุเขตเวลาที่คุณต้องการ / ที่คาดไว้อย่างชัดเจนเป็นอาร์กิวเมนต์

ระบุชื่อโซนเวลาที่เหมาะสมในรูปแบบของcontinent/regionเช่นAmerica/Montreal, หรือAfrica/Casablanca Pacific/Aucklandอย่าใช้อักษรย่อ 3-4 ตัวเช่นESTหรือISTเนื่องจากไม่ใช่เขตเวลาจริงไม่เป็นมาตรฐานและไม่ซ้ำกัน (!)

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

โทรหานักเตะคนใดคนหนึ่งเพื่อดึงวันที่ - เวลาออกมา

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

java.timeเรียนมีมติให้นาโนวินาที คำถามของคุณถามหาเสี้ยววินาทีในมิลลิวินาที เห็นได้ชัดว่าคุณสามารถหารด้วยหนึ่งล้านเพื่อตัดทอนนาโนวินาทีเป็นมิลลิวินาทีโดยเสียค่าใช้จ่ายของข้อมูลที่อาจสูญหายได้ หรือใช้TimeUnitenum สำหรับการแปลงดังกล่าว

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

DateTimeFormatter

ในการสร้างข้อความStringเพื่อรวมส่วนต่างๆให้ใช้DateTimeFormatterคลาส ค้นหา Stack Overflow สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสิ่งนี้

Instant

โดยปกติดีที่สุดในการติดตามช่วงเวลาใน UTC หากต้องการปรับจากวันที่ - เวลาแบบแบ่งเขตเป็น UTC ให้แยก a Instant.

Instant instant = zdt.toInstant() ;

และกลับไปอีกครั้ง.

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

LocalDateTime

คำตอบอีกสองสามคำใช้ในLocalDateTimeชั้นเรียน คลาสนั้นไม่เหมาะสมกับวัตถุประสงค์ในการติดตามช่วงเวลาจริงช่วงเวลาที่เฉพาะเจาะจงบนไทม์ไลน์เนื่องจากจงใจไม่มีแนวคิดเรื่องเขตเวลาหรือออฟเซ็ตจาก UTC

แล้วอะไรLocalDateTimeดีล่ะ? ใช้LocalDateTimeเมื่อคุณต้องการใช้วันที่และเวลากับท้องที่ใด ๆหรือทุกท้องที่แทนที่จะใช้เฉพาะท้องที่ใดท้องที่หนึ่ง

ตัวอย่างเช่นคริสต์มาสปีนี้เริ่มต้นที่LocalDateTime.parse( "2018-12-25T00:00:00" ). ค่านั้นไม่มีความหมายจนกว่าคุณจะใช้เขตเวลา (a ZoneId) เพื่อรับไฟล์ZonedDateTime. คริสต์มาสเกิดขึ้นครั้งแรกในคิริบาสต่อมาในนิวซีแลนด์และเอเชียตะวันออกไกล ชั่วโมงต่อมาคริสต์มาสจะเริ่มในอินเดีย อีกชั่วโมงต่อมาในแอฟริกาและยุโรป และยังไม่ใช่คริสต์มาสในทวีปอเมริกาจนกระทั่งหลายชั่วโมงต่อมา คริสมาสต์เริ่มต้นในการใด ๆหนึ่งในZonedDateTimeสถานที่ที่ควรจะแสดงด้วย คริสต์มาสทุกที่จะแสดงด้วยไฟล์LocalDateTime.


เกี่ยวกับjava.time

java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date, และCalendarSimpleDateFormat

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

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

คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่ต้องมีสตริงไม่ต้องมีjava.sql.*คลาส

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

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

2

หรือใช้ java.sql.Timestamp ปฏิทินค่อนข้างหนักฉันไม่แนะนำให้ใช้ในรหัสการผลิต Joda ดีกว่า

import java.sql.Timestamp;

public class DateTest {

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

ฉันคิดว่าคุณเข้าใจผิดทั้งคำถามและการใช้การประทับเวลา sql ปกติคุณจะใช้new Date()ที่นี่ แต่คุณจะได้รับชิ้นส่วนที่แยกจากกันอย่างง่ายดายตามที่ร้องขอได้อย่างไร?
BalusC

FYI java.sql.Timestampถูกแทนที่java.time.Instantด้วยการมาถึงของ JDBC 4.2
Basil Bourque

0

ใน java 7 Calendar หนึ่งบรรทัด

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

1
ตอนนี้ปฏิทินและคลาส SimpleDateFormat ที่เป็นปัญหาล้าสมัยแล้วโดยแทนที่คลาส java.time ทั้งหมด ดูคำตอบโดย BalusCสำหรับแนวทางที่ทันสมัย มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับโครงการ
Basil Bourque

-2

ดูเอกสารประกอบ API สำหรับคลาส java.util.Calendar และอนุพันธ์ (คุณอาจสนใจคลาส GregorianCalendar เป็นพิเศษ)


FYI, ลำบากเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และต่อมา ดูการสอนโดยออราเคิล
Basil Bourque

-2

Calendar now = new Calendar () // หรือ new GregorianCalendar () หรือรสชาติที่คุณต้องการ

now.MONTH now.HOUR

เป็นต้น


3
สวัสดีฉันมีช่วงเวลาที่ยากลำบากในการทำความเข้าใจว่าทำไมคุณถึงตอบซ้ำคำตอบที่ให้ไปแล้วในลักษณะที่ไม่ดี กรุณาอธิบายให้ละเอียด :)
BalusC

3
MONTHและHOURเป็นค่าคงที่ของCalendarคุณสมบัติของอินสแตนซ์ไม่ได้
Joseph Earl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.