แยกวิเคราะห์สตริงเป็นวันที่ด้วยรูปแบบที่แตกต่างกันใน Java


93

ฉันต้องการแปลงStringเป็นDateรูปแบบอื่น

ตัวอย่างเช่น,

ฉันได้รับจากผู้ใช้

String fromDate = "19/05/2009"; // i.e. (dd/MM/yyyy) format

ฉันต้องการแปลงสิ่งนี้fromDateเป็นวัตถุวันที่ของ"yyyy-MM-dd"รูปแบบ

ฉันจะทำเช่นนี้ได้อย่างไร?


2
วัตถุวันที่ไม่มีรูปแบบเป็นเพียงตัวเลขที่แสดงวันที่ วันที่สามารถแสดงด้วยสตริงในรูปแบบ "yyyy-MM-dd"
user85421

คำตอบ:


182

ลองดูที่SimpleDateFormat. รหัสมีลักษณะดังนี้:

SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

try {

    String reformattedStr = myFormat.format(fromUser.parse(inputString));
} catch (ParseException e) {
    e.printStackTrace();
}

1
แทนที่จะรับรูปแบบสตริงฉันสามารถรับเอาต์พุตในDateรูปแบบได้หรือไม่
Rachel

4
@Rachel: แน่นอนว่าเพียงแค่ใช้และไม่ได้ไปparse แยกวิเคราะห์สตริงเป็นวันที่ formatparse
Michael Myers

3
แต่parseให้ฉันdate formatเป็นFri Jan 06 00:01:00 EST 2012แต่มันต้องการใน2012-01-06รูปแบบวันที่
Rachel

1
@Rachel เป็นเพราะเมื่อคุณเรียกSystem.out.println(anyDateObject)toString เริ่มต้น () Fri Jan 06 00:01:00 EST 2012วิธีการที่เรียกว่าซึ่งได้รับการกล่าวว่าการพิมพ์ในรูปแบบที่เช่น คุณจำเป็นต้องลบล้างเพื่อให้เหมาะกับความต้องการของคุณ
KNU

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

14

tl; dr

LocalDate.parse( 
    "19/05/2009" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) 
)

รายละเอียด

คำตอบอื่น ๆ ที่มีjava.util.Date, java.sql.DateและSimpleDateFormatจะล้าสมัยในขณะนี้

LocalDate

วิธีที่ทันสมัยที่จะทำวันที่เวลาคือการทำงานกับการเรียน java.time LocalDateโดยเฉพาะ LocalDateชั้นหมายถึงค่าวันเท่านั้นโดยไม่ต้องเวลาของวันและไม่มีโซนเวลา

DateTimeFormatter

หากต้องการแยกวิเคราะห์หรือสร้างสตริงที่แสดงค่าวันที่ - เวลาให้ใช้DateTimeFormatterคลาส

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "19/05/2009" , f );

อย่าเชื่อมวัตถุวันที่ - เวลาด้วยสตริงที่แสดงค่าของมัน วัตถุวันที่เวลามีไม่มีรูปแบบในขณะที่ String ไม่ ออบเจ็กต์วันที่และเวลาเช่นLocalDateสามารถสร้าง String เพื่อแสดงค่าภายในได้ แต่อ็อบเจ็กต์วันที่และสตริงเป็นอ็อบเจ็กต์ที่แตกต่างกัน

คุณสามารถระบุรูปแบบที่กำหนดเองเพื่อสร้าง String หรือปล่อยให้ java.time ทำงานในการแปลโดยอัตโนมัติ

DateTimeFormatter f = 
    DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                     .withLocale( Locale.CANADA_FRENCH ) ;
String output = ld.format( f );

ถ่ายโอนไปยังคอนโซล

System.out.println( "ld: " + ld + " | output: " + output );

ld: 2009-05-19 | ผลผลิต: mardi 19 mai 2009

ดูในการดำเนินการใน IdeOne.com


เกี่ยวกับ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 API มาตรฐานพร้อมการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android
    • การติดตั้งบันเดิล Android เวอร์ชันที่ใหม่กว่าของคลาส java.time
    • สำหรับก่อนหน้านี้ Android (<26) ที่ThreeTenABPโครงการปรับThreeTen-ย้ายกลับ (ดังกล่าวข้างต้น) ดูวิธีใช้ ThreeTenABP … .

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


12

ใช้SimpleDateFormatคลาส:

private Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = new SimpleDateFormat(format);
    return formatter.parse(date);
}

การใช้งาน:

Date date = parseDate("19/05/2009", "dd/MM/yyyy");

เพื่อประสิทธิภาพคุณต้องการจัดเก็บรูปแบบของคุณในแฮชแมป แฮชแมปเป็นสมาชิกแบบคงที่ของคลาส util ของคุณ

private static Map<String, SimpleDateFormat> hashFormatters = new HashMap<String, SimpleDateFormat>();

public static Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = hashFormatters.get(format);

    if (formatter == null)
    {
        formatter = new SimpleDateFormat(format);
        hashFormatters.put(format, formatter);
    }

    return formatter.parse(date);
}

9
ข้อแม้!! ความคิดดี แต่การนำไปใช้ไม่เป็น ต้องไม่จัดเก็บ DateFormats แบบคงที่เนื่องจากไม่ปลอดภัยต่อเธรด! หากใช้จากเธรดมากกว่าหนึ่งเธรด (และสิ่งนี้มีความเสี่ยงเสมอกับสถิตยศาสตร์) FindBugs มีเครื่องตรวจจับสำหรับสิ่งนี้ (ซึ่งฉันบังเอิญมีส่วนร่วมในตอนแรกหลังจากที่ฉันถูกกัดดูdschneller.blogspot.com/2007/04/… :-))
Daniel Schneller

รายการบล็อกของคุณเป็นสิ่งที่น่าอ่าน :-) จะเกิดอะไรขึ้นถ้าฉันซิงโครไนซ์เมธอด parseDate เอง ปัญหาคือมันอาจจะทำให้โค้ดช้าลง ...
Agora

1
ตราบใดที่เมธอด parseDate เป็นวิธีเดียวที่เข้าถึงแผนที่การซิงโครไนซ์ก็จะใช้ได้ อย่างไรก็ตามสิ่งนี้ - อย่างที่คุณพูด - แนะนำคอขวด
Daniel Schneller

8

แปลงวันที่สตริงเป็น java.sql.Date

String fromDate = "19/05/2009";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date dtt = df.parse(fromDate);
java.sql.Date ds = new java.sql.Date(dtt.getTime());
System.out.println(ds);//Mon Jul 05 00:00:00 IST 2010


3

แม้ว่าSimpleDateFormatจะเหมาะกับความต้องการของคุณ แต่คุณอาจต้องการตรวจสอบJoda Timeซึ่งเห็นได้ชัดว่าเป็นพื้นฐานสำหรับไลบรารี Date ที่ทำซ้ำใน Java 7 แม้ว่าฉันจะไม่ได้ใช้มันมากนัก แต่ฉันก็ไม่ได้ยินอะไรเลยนอกจากสิ่งดีๆ เกี่ยวกับเรื่องนี้และหากวันที่ที่คุณจัดการอย่างกว้างขวางในโครงการของคุณก็น่าจะคุ้มค่า


2

สมมติว่าคุณมีสตริงดังนี้:

String mDate="2019-09-17T10:56:07.827088"

ตอนนี้เราต้องการที่จะเปลี่ยนแปลงนี้Stringรูปแบบวันที่แยกต่างหากและเวลาในJavaและKotlin

Java:

เรามีวิธีการแยกวันที่ :

public String getDate() {
    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mDate);
        dateFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Return คือ: 17/09/2019

และเรามีวิธีการแยกเวลา :

public String getTime() {

    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mCreatedAt);
        dateFormat = new SimpleDateFormat("h:mm a", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Returnคือ: 10:56 น

คอตลิน:

เรามีฟังก์ชั่นสำหรับแยกวันที่ :

fun getDate(): String? {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val date = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US)
    return dateFormat.format(date!!)
}

Return คือ: 17/09/2019

และเรามีวิธีการแยกเวลา :

fun getTime(): String {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val time = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("h:mm a", Locale.US)
    return dateFormat.format(time!!)
}

Returnคือ: 10:56 น


โปรดอย่าสอนเด็ก ๆ ให้ใช้SimpleDateFormatชั้นเรียนที่ล้าสมัยและยุ่งยากมานาน อย่างน้อยก็ไม่ใช่ตัวเลือกแรก และไม่มีการจองใด ๆ วันนี้เรามีมากดีกว่าในการjava.timeที่ทันสมัย Java วันที่และเวลา API,DateTimeFormatterและ ยังSimpleDateFormatไม่สามารถแยกวิเคราะห์ทศนิยม 6 ตำแหน่งในวินาที (ไมโครวินาที) ได้อย่างถูกต้อง
Ole VV

เมื่อฉันเรียกใช้ตัวอย่างข้อมูลที่สองของคุณฉันไม่ได้รับ10:56 AMอย่างที่คุณบอก แต่ควรทำแทน11:09 AM(ทดสอบบน Oracle jdk-11.0.3)
Ole VV

@ OleV.V. , หากวิธีการล้าสมัยไปนาน, มันจะเลิกใช้งานโดยมีเส้นบนมันเป็นเครื่องหมาย, ถ้าเมธอดหรือคลาสไม่เลิกใช้เราสามารถใช้มันได้ฉันไม่ได้บอกว่ามันเป็นวิธีที่ดีที่สุดบางทีเราอาจมีวิธีที่ดีกว่า แต่วิธีนี้ เป็นเรื่องง่ายและเข้าใจได้หากวิธีการหรือคลาสเก่าไม่มีเหตุผลที่จะยุ่งยากและสำหรับการใช้งานที่DateTimeFormatterเราต้องการminsdk 26หรือสูงกว่านั้นก็ไม่ใช่สิ่งที่ดี
milad salimi

@ OleV.V. แต่ขอบคุณสำหรับความคิดเห็นของคุณและเกี่ยวกับความคิดเห็นที่สองของคุณฉันสามารถพูดได้ว่าฉันตรวจสอบหลายครั้งในสอง10:56 AM
แอปพลิเคชัน

1
@ OleV.V. , โอเค แต่ฉันใช้ไลบรารีเมื่อฉันไม่มีทางหรือ API (ไลบรารี) นั้นดีกว่ารหัสของฉันมากเพราะเมื่อคุณเพิ่มไลบรารีคุณจะเพิ่มรหัสบางอย่างในโปรเจ็กต์ของคุณซึ่งอาจไม่ได้ใช้และสิ่งนี้เกินกำลังสำหรับคุณ โครงการนี่คือแนวทางของฉันและแนวทางของคุณเป็นสิ่งที่น่านับถือสำหรับฉัน
milad salimi

1

วิธีง่ายๆในการจัดรูปแบบวันที่และแปลงเป็นสตริง

    Date date= new Date();

    String dateStr=String.format("%td/%tm/%tY", date,date,date);

    System.out.println("Date with format of dd/mm/dd: "+dateStr);

เอาต์พุต: วันที่ที่มีรูปแบบ dd / mm / dd: 21/10/2015


1

Dateวัตถุมีรูปแบบไม่มีมันเป็นตัวแทน วันที่สามารถนำเสนอด้วยStringกับรูปแบบที่คุณชอบ

เช่น " yyyy-MM-dd", " yy-MMM-dd", dd-MMM-yy"และอื่น ๆ

เพื่อให้บรรลุสิ่งนี้คุณสามารถใช้ไฟล์ SimpleDateFormat

ลองสิ่งนี้

        String inputString = "19/05/2009"; // i.e. (dd/MM/yyyy) format

        SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy"); 
        SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date dateFromUser = fromUser.parse(inputString); // Parse it to the exisitng date pattern and return Date type
            String dateMyFormat = myFormat.format(dateFromUser); // format it to the date pattern you prefer
            System.out.println(dateMyFormat); // outputs : 2009-05-19

        } catch (ParseException e) {
            e.printStackTrace();
        }

ผลลัพธ์นี้: 2009-05-19

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