Chuyển đổi java.util.Date thành Chuỗi


407

Tôi muốn chuyển đổi một java.util.Date đối tượng thành một Stringtrong Java.

Định dạng là 2010-05-30 22:15:52



@harschware 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 . Xem Hướng dẫn của Oracle .
Basil Bourque

1
Tôi khuyên bạn không nên sử dụng và Datevào năm 2019. Lớp học đó được thiết kế kém và lỗi thời. Thay vì sử dụng Instanthoặc một lớp khác từ java.time, API ngày và giờ Java hiện đại .
Ole VV

Câu trả lời:


757

Chuyển đổi một ngày thành một chuỗi bằng DateFormat#formatphương thức:

String pattern = "MM/dd/yyyy HH:mm:ss";

// Create an instance of SimpleDateFormat used for formatting 
// the string representation of date according to the chosen pattern
DateFormat df = new SimpleDateFormat(pattern);

// Get the today date using Calendar object.
Date today = Calendar.getInstance().getTime();        
// Using DateFormat format method we can create a string 
// representation of a date with the defined format.
String todayAsString = df.format(today);

// Print the result!
System.out.println("Today is: " + todayAsString);

Từ http://www.kodejava.org/examples/86.html


25
Tại sao sử dụng Calendarthay vì đồng bằng new Date()? Có sự khác biệt?
Alexander Malakhov

10
Chú ý: SimpleDateFormat không phải là chủ đề an toàn. stackoverflow.com/questions/6840804/
Mạnh

23
Lịch là một lớp trừu tượng, ngày là cụ thể. Date không biết gì về TimeZone, Locale hoặc bất kỳ thứ hay ho nào mà tất cả chúng ta không bao giờ sử dụng.
nckbrz

30
Các MM/dd/yyyyđịnh dạng là ngu ngốc và bị hỏng. Đừng sử dụng nó. Luôn luôn sử dụng dd/MM/yyyyhoặc yyyy-MM-dd.
SystemParadox

13
@SystemParadox - Thật ngu ngốc, nhưng điều đó không làm cho nó trở nên vô nghĩa. Tôi đặc biệt được yêu cầu sử dụng nó vì nó phù hợp với những gì mọi người mong đợi trên các báo cáo. (Tôi thích yyyy-MM-ddở mọi nơi, nhưng bạn có thể làm gì?).
Mùa thu Leonard

223
Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = formatter.format(date);

63

Commons-lang DateFormatUtils có rất nhiều quà tặng (nếu bạn có commons-lang trong đường dẫn của bạn)

//Formats a date/time into a specific pattern
 DateFormatUtils.format(yourDate, "yyyy-MM-dd HH:mm:SS");

Yêu cầu nullkiểm tra bổ sung .
Farrukh Chishti

23

tl; dr

myUtilDate.toInstant()  // Convert `java.util.Date` to `Instant`.
          .atOffset( ZoneOffset.UTC )  // Transform `Instant` to `OffsetDateTime`.
          .format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )  // Generate a String.
          .replace( "T" , " " )  // Put a SPACE in the middle.

2014/11/14 14:05:09

java.time

Cách hiện đại là với các lớp java.time mà bây giờ thay thế các lớp thời gian cũ kế thừa rắc rối.

Đầu tiên chuyển đổi của bạn java.util.Dateđể một Instant. Các Instantlớp đại diện cho một thời điểm trên Timeline trong UTC với độ phân giải nano giây (lên đến chín (9) chữ số của một phân số thập phân).

Chuyển đổi đến / từ java.time được thực hiện bằng các phương thức mới được thêm vào các lớp cũ.

Instant instant = myUtilDate.toInstant();

Cả bạn java.util.Datejava.time.Instantđang ở UTC . Nếu bạn muốn xem ngày và giờ là UTC, thì hãy là nó. Gọi toStringđể tạo Chuỗi theo định dạng ISO 8601 tiêu chuẩn .

String output = instant.toString();  

2014-11-14T14: 05: 09Z

Đối với các định dạng khác, bạn cần chuyển đổi Instantthành linh hoạt hơn OffsetDateTime.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );

odt.toString (): 2020-05-01T21: 25: 35.957Z

Xem đó chạy trực tiếp tại IdeOne.com .

Để có được một Chuỗi ở định dạng mong muốn của bạn, chỉ định a DateTimeFormatter. Bạn có thể chỉ định một định dạng tùy chỉnh. Nhưng tôi sẽ sử dụng một trong các trình định dạng được xác định trước ( ISO_LOCAL_DATE_TIME) và thay thế Tđầu ra của nó bằng SPACE.

String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
                   .replace( "T" , " " );

2014/11/14 14:05:09

Bằng cách này, tôi không đề xuất loại định dạng này khi bạn cố tình làm mất thông tin bù từ UTC hoặc múi giờ. Tạo sự mơ hồ về ý nghĩa của giá trị thời gian ngày của chuỗi đó.

Ngoài ra, hãy cẩn thận với việc mất dữ liệu, vì bất kỳ giây phân đoạn nào đang bị bỏ qua (bị cắt ngắn một cách hiệu quả) trong biểu diễn chuỗi giá trị ngày của bạn.

Để xem cùng thời điểm đó qua ống kính của thời gian đồng hồ treo tường của một số khu vực cụ thể , hãy áp dụng a ZoneIdđể có được a ZonedDateTime.

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

zdt.toString (): 2014-11-14T14: 05: 09-05: 00 [Mỹ / Montreal]

Để tạo một chuỗi được định dạng, làm tương tự như trên nhưng thay thế odtbằng zdt.

String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
                   .replace( "T" , " " );

2014/11/14 14:05:09

Nếu thực thi mã này một số lần rất lớn, bạn có thể muốn hiệu quả hơn một chút và tránh cuộc gọi đến String::replace. Bỏ cuộc gọi đó cũng làm cho mã của bạn ngắn hơn. Nếu muốn, chỉ định mẫu định dạng của riêng bạn trong DateTimeFormatterđối tượng của riêng bạn . Cache trường hợp này là một hằng số hoặc thành viên để sử dụng lại.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" );  // Data-loss: Dropping any fractional second.

Áp dụng định dạng đó bằng cách chuyển thể hiện.

String output = zdt.format( f );

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ác lớp học ngày thời gian cũ phiền hà như java.util.Date, .Calendar, & java.text.SimpleDateFormat.

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

Để 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.

Phần lớn chức năng java.time được chuyển ngược lại sang Java 6 & 7 trong ThreeTen-Backport và được điều chỉnh thêm cho Android trong ThreeTenABP (xem Cách sử dụng Thẻ ).

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.


Dưới đây là các ví dụ mã về định dạng với API thời gian Java 8: stackoverflow.com/a/43457343/603516
Vadzim

mã này không hoạt động OffsetDateTime odt = Instant.at Offerset (Zone Offerset.UTC); odt.toString (): 2014-11-14T14: 05: 09 + 00: 00 Có mã Java 8 mới để có cùng định dạng 2014-11-14T14: 05: 09 + 00: 00 không? Cảm ơn bạn
Bob Bolden

@BobBolden Bạn đúng, Zđược sử dụng thay vì +00:00mặc định. Tôi đã sửa câu trả lời, cảm ơn. FYI, những điều đó có nghĩa tương tự : Z, phát âm là Zulu, có nghĩa là phần bù 0 giờ-phút-giây, giống như +00:00. Các tiêu chuẩn ISO 8601 tiêu chuẩn hỗ trợ cả phong cách.
Basil Bourque

@BasilBourque xin lỗi, điều này không rõ ràng. Tôi có Java 8 và không có ngay lập tức. Bạn có thể vui lòng tư vấn mã chính xác nào để Java 8 có cùng định dạng 2014-11-14T14: 05: 09 + 00: 00 mà không có ngay lập tức.at Offerset () không? Tôi hơi lạc lõng :(
Bob Bolden

@BobBolden Thực sự có một atOffsetphương thức trên Instantlớp trong Java 8. Xem Javadoc : Instant::atOffset. Trong Java 8, một cuộc gọi như Instant.now().atOffset( ZoneOffset.UTC ).toString()sẽ chạy. Kiểm tra importbáo cáo của bạn . Xác minh IDE / dự án của bạn được đặt để chạy Java 8 trở lên thay vì phiên bản Java cũ hơn. Xem mã chạy trực tiếp tại IdeOne.com: ideone.com/2Vm2O5
Basil Bourque

19

Một lớp lót nóng bỏng trong java cũ:

String.format("The date: %tY-%tm-%td", date, date, date);

String.format("The date: %1$tY-%1$tm-%1$td", date);

String.format("Time with tz: %tY-%<tm-%<td %<tH:%<tM:%<tS.%<tL%<tz", date);

String.format("The date and time in ISO format: %tF %<tT", date);

Này sử dụng Formattertương đối lập chỉ mục thay vì SimpleDateFormatđược không thread-safe , btw.

Hơi lặp đi lặp lại nhiều hơn nhưng chỉ cần một tuyên bố. Điều này có thể có ích trong một số trường hợp.


1
Đây là (trong) thiên tài. Hiệu suất tốt hơn nhiều cho các môi trường bị hạn chế
Ruslan

9

Tại sao bạn không sử dụng Joda (org.joda.time.DateTime)? Về cơ bản, nó là một lớp lót.

Date currentDate = GregorianCalendar.getInstance().getTime();
String output = new DateTime( currentDate ).toString("yyyy-MM-dd HH:mm:ss");

// output: 2014-11-14 14:05:09

Tôi cũng đề nghị chuyển DateTimeZone, thay vì chỉ định múi giờ mặc định hiện tại của JVM cho DateTimeđối tượng. new DateTime( currentDate , DateTimeZone.forID( "America/Montreal" ) )
Basil Bourque

7

Có vẻ như bạn đang tìm kiếm SimpleDateFormat .

Định dạng: yyyy-MM-dd kk: mm: ss


"Kk" có làm gì đặc biệt không? Tôi nghĩ Eric muốn nó trong thời gian 24 giờ.
Charlie Salts

2
Vâng, giờ trong ngày (1-24), nhưng đây có thể không phải là những gì OP cần. HH(0-23) là phổ biến hơn.
BalusC

1
@Cahrlie Salts kk đi từ 1-24, trong đó HH đi từ 0-23 và có lẽ tôi hơi tự phụ khi cho rằng anh ta muốn 1-24 @BalusC Đối tượng DateFormat cả phân tích và định dạng.
pickypg

Tôi không hiểu sự liên quan của bình luận cuối cùng của bạn. Nhận xét của tôi là Charlie.
BalusC

Tôi đã quen với các định dạng .Net, trong đó HH là 24 lần và hh là sáng / chiều. Do đó gãi đầu.
Charlie Salts

5

Trong một lần bắn;)

Để có được ngày

String date = new SimpleDateFormat("yyyy-MM-dd",   Locale.getDefault()).format(new Date());

Để có được thời gian

String time = new SimpleDateFormat("hh:mm", Locale.getDefault()).format(new Date());

Để có được ngày và thời gian

String dateTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefaut()).format(new Date());

Chúc mừng mã hóa :)


1
FYI, các lớp thời gian cũ rắc rối như java.util.Date, java.util.Calendarjava.text.SimpleDateFormathiện là di sản , được thay thế bởi các lớp java.time được tích hợp trong Java 8 & Java 9. Xem Hướng dẫn của Oracle .
Basil Bourque

4
public static String formateDate(String dateString) {
    Date date;
    String formattedDate = "";
    try {
        date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",Locale.getDefault()).parse(dateString);
        formattedDate = new SimpleDateFormat("dd/MM/yyyy",Locale.getDefault()).format(date);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return formattedDate;
}

4

Cách dễ nhất để sử dụng nó như sau:

currentISODate = new Date().parse("yyyy-MM-dd'T'HH:mm:ss", "2013-04-14T16:11:48.000");

trong đó "yyyy-MM-dd'T'HH: mm: ss" là định dạng của ngày đọc

đầu ra: CN ngày 14 tháng 4 16:11:48 EEST 2013

Lưu ý: HH vs hh - HH đề cập đến định dạng thời gian 24h - hh đề cập đến định dạng thời gian 12h


Câu hỏi là về chuyển đổi ngược lại.
Vadzim

4

Nếu bạn chỉ cần thời gian từ ngày, bạn chỉ có thể sử dụng tính năng của Chuỗi.

Date test = new Date();
String dayString = test.toString();
String timeString = dayString.substring( 11 , 19 );

Điều này sẽ tự động cắt phần thời gian của Chuỗi và lưu nó vào bên trong timeString.


Điều này có thể phá vỡ với địa phương khác nhau.
Vadzim

4

Dưới đây là các ví dụ về việc sử dụng API thời gian Java 8 mới để định dạng di sản java.util.Date :

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS Z")
        .withZone(ZoneOffset.UTC);
    String utcFormatted = formatter.format(date.toInstant()); 

    ZonedDateTime utcDatetime = date.toInstant().atZone(ZoneOffset.UTC);
    String utcFormatted2 = utcDatetime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS Z"));
    // gives the same as above

    ZonedDateTime localDatetime = date.toInstant().atZone(ZoneId.systemDefault());
    String localFormatted = localDatetime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
    // 2011-12-03T10:15:30+01:00[Europe/Paris]

    String nowFormatted = LocalDateTime.now().toString(); // 2007-12-03T10:15:30.123

Điều tuyệt vời DateTimeFormatterlà nó có thể được lưu trữ hiệu quả vì nó an toàn cho luồng (không giống như SimpleDateFormat).

Danh sách các fomatters được xác định trước và tham chiếu ký hiệu mẫu .

Tín dụng:

Làm cách nào để phân tích / định dạng ngày với LocalDateTime? (Java 8)

Java8 java.util.Date chuyển đổi sang java.time.ZencedDateTime

Định dạng tức thì thành chuỗi

Sự khác biệt giữa java 8 ZencedDateTime và OffsetDateTime là gì?


2

Thử cái này,

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class Date
{
    public static void main(String[] args) 
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strDate = "2013-05-14 17:07:21";
        try
        {
           java.util.Date dt = sdf.parse(strDate);         
           System.out.println(sdf.format(dt));
        }
        catch (ParseException pe)
        {
            pe.printStackTrace();
        }
    }
}

Đầu ra:

2013-05-14 17:07:21

Để biết thêm về định dạng ngày và thời gian trong java tham khảo các liên kết dưới đây

Trung tâm trợ giúp của Oracle

Ví dụ ngày giờ trong java


1
public static void main(String[] args) 
{
    Date d = new Date();
    SimpleDateFormat form = new SimpleDateFormat("dd-mm-yyyy hh:mm:ss");
    System.out.println(form.format(d));
    String str = form.format(d); // or if you want to save it in String str
    System.out.println(str); // and print after that
}

1

Chúng ta hãy cố gắng này

public static void main(String args[]) {

    Calendar cal = GregorianCalendar.getInstance();
    Date today = cal.getTime();
    DateFormat df7 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try {           
        String str7 = df7.format(today);
        System.out.println("String in yyyy-MM-dd format is: " + str7);          
    } catch (Exception ex) {
      ex.printStackTrace();
    }
}

Hoặc một chức năng tiện ích

public String convertDateToString(Date date, String format) {
    String dateStr = null;
    DateFormat df = new SimpleDateFormat(format);

    try {
        dateStr = df.format(date);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return dateStr;
}

Từ ngày chuyển đổi thành chuỗi trong Java


1
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String date = "2010-05-30 22:15:52";
    java.util.Date formatedDate = sdf.parse(date); // returns a String when it is parsed
    System.out.println(sdf.format(formatedDate)); // the use of format function returns a String

1
Date date = new Date();
String strDate = String.format("%tY-%<tm-%<td %<tH:%<tM:%<tS", date);

1

Tùy chọn một dòng

Tùy chọn này có được một dòng dễ dàng để viết ngày thực tế.

Xin lưu ý rằng điều này đang sử dụng Calendar.classSimpleDateFormat, sau đó không hợp lý khi sử dụng nó trong Java8.

yourstringdate =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());

1
FYI, các lớp học ngày thời gian khủng khiếp phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle .
Basil Bourque

1
(1) Câu trả lời sai (Tôi vừa nhận được 2019-20-23 09:20:22- tháng 20 ??) (2) Tôi không thể thấy rằng câu trả lời cung cấp bất cứ điều gì chưa được đề cập trong các câu trả lời khác. (3) Xin đừng dạy những người trẻ tuổi sử dụng SimpleDateFormatlớp học lỗi thời và nổi tiếng là rắc rối . Ít nhất không phải là lựa chọn đầu tiên. Và không phải không có bất kỳ đặt phòng. Ngày nay chúng ta có rất nhiều thứ tốt hơn java.time, API ngày và thời gian hiện đại của Java và của nó DateTimeFormatter.
Ole VV

Vâng .... tôi đã làm một lỗi và quên sửa nó. Tôi đã thêm nó một cách nhanh chóng, và đã không nhớ .. xin lỗi !! và cảm ơn ý kiến ​​của bạn các bạn
Alejandro Teixeira Muñoz

@ OleV.V. Không phải ai cũng có quyền truy cập vào dữ liệu Java hiện đại và thời gian api ...... vì vậy ... Nó cũng hợp lệ câu trả lời này ...
Alejandro Teixeira Muñoz

1
Cám ơn bạn đã góp ý. Nếu bạn muốn cung cấp câu trả lời cho Java 5 hoặc cho Java 6 và 7 mà không có bất kỳ sự phụ thuộc bên ngoài nào, rất tốt, điều đó rất đáng hoan nghênh, chỉ xin vui lòng làm rõ rằng đó là những gì bạn đang làm. Và câu trả lời của bạn vẫn sai, bạn sẽ nhận được những điều bất ngờ vào dịp năm mới.
Ole VV
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.