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


339

Java 8 đã thêm API java.time mới để làm việc với ngày và giờ ( JSR 310 ).

Tôi có ngày và thời gian dưới dạng chuỗi (ví dụ "2014-04-08 12:30"). Làm thế nào tôi có thể có được một LocalDateTimethể hiện từ chuỗi đã cho?

Sau khi tôi hoàn thành công việc với LocalDateTimeđối tượng: Làm thế nào tôi có thể chuyển đổi LocalDateTimethể hiện trở lại thành một chuỗi có cùng định dạng như được hiển thị ở trên?


11
FYI, hầu hết mọi người hầu hết thời gian sẽ muốn một ZonedDateTimechứ không phải là một LocalDateTime. Tên là phản trực giác; các Localphương tiện bất kỳ địa phương nói chung chứ không phải là một múi giờ cụ thể. Như vậy, một LocalDateTimeđối tượng không bị ràng buộc với dòng thời gian. Để có ý nghĩa, để có được một thời điểm xác định trên dòng thời gian, bạn phải áp dụng múi giờ.
Basil Bourque

Xem câu trả lời của tôi để được giải thích về LocalDateTimeso với so với ZonedDateTimeso OffsetDateTimevới Instantso LocalDatevới LocalTime, làm thế nào để giữ bình tĩnh về lý do tại sao nó quá phức tạp và làm thế nào để làm điều đó ngay trong lần chụp đầu tiên.
Ondra ižka

1
Nếu nó không chính thức lâu, LocalDateTimecó lẽ đã được đặt tên ZonelessOffsetlessDateTime.
Ondra ižka

Câu trả lời:


533

Phân tích ngày giờ

Để tạo một LocalDateTimeđối tượng từ một chuỗi, bạn có thể sử dụng LocalDateTime.parse()phương thức tĩnh . Nó nhận một chuỗi và một DateTimeFormattertham số. Các DateTimeFormatterđược sử dụng để xác định mô hình ngày / giờ.

String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);

Định dạng ngày giờ

Để tạo một chuỗi định dạng ra một LocalDateTimeđối tượng, bạn có thể sử dụng format()phương thức.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"

Lưu ý rằng có một số định dạng ngày / giờ thường được sử dụng được xác định trước là hằng số trong DateTimeFormatter. Ví dụ: Sử dụng DateTimeFormatter.ISO_DATE_TIMEđể định dạng LocalDateTimethể hiện từ phía trên sẽ dẫn đến chuỗi "1986-04-08T12:30:00".

Các phương thức parse()format()có sẵn cho tất cả các đối tượng liên quan đến ngày / giờ (ví dụ LocalDatehoặc ZonedDateTime)


77
Chỉ cần lưu ý rằng DateTimeFormatter là bất biến và an toàn luồng, và do đó, cách tiếp cận được đề xuất là lưu trữ nó trong một hằng số tĩnh nếu có thể.
JodaStephen

@micha nếu tôi có "2016-12-31T07: 59: 00.000Z" ngày này thì sao?
Dawood Ahmed

14
@DawoodAbbasi thửDateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
Ray Hulha

1
@Loenix có thể đó là vì bạn đang cố gắng gọi format()lớp LocalDateTime thay vì trên ví dụ? Ít nhất, đó là những gì tôi đã làm: tôi nhầm lẫn DateTimevới dateTimeví dụ trên.
dán vào

2
Đừng quên chữ hoa trên MM
Wesos de Queso

159

Bạn cũng có thể sử dụng LocalDate.parse()hoặc LocalDateTime.parse()trên một Stringmà không cung cấp cho nó một mẫu, nếu đó Stringlà ở định dạng ISO-8601 .

ví dụ,

String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
System.out.println("Date: " + aLD);

String strDatewithTime = "2015-08-04T10:11:30";
LocalDateTime aLDT = LocalDateTime.parse(strDatewithTime);
System.out.println("Date with Time: " + aLDT);

Đầu ra ,

Date: 2015-08-04
Date with Time: 2015-08-04T10:11:30

DateTimeFormatterchỉ sử dụng nếu bạn phải đối phó với các mẫu ngày khác.

Chẳng hạn, trong ví dụ sau, dd MMM uuuu đại diện cho ngày của tháng (hai chữ số), ba chữ cái tên của tháng (tháng một, tháng hai, tháng ba, ...) và một năm có bốn chữ số:

DateTimeFormatter dTF = DateTimeFormatter.ofPattern("dd MMM uuuu");
String anotherDate = "04 Aug 2015";
LocalDate lds = LocalDate.parse(anotherDate, dTF);
System.out.println(anotherDate + " parses to " + lds);

Đầu ra

04 Aug 2015 parses to 2015-08-04

cũng nhớ rằng DateTimeFormatter đối tượng là hai chiều; nó có thể phân tích cú pháp đầu vào và đầu ra định dạng.

String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
DateTimeFormatter dTF = DateTimeFormatter.ofPattern("dd MMM uuuu");
System.out.println(aLD + " formats as " + dTF.format(aLD));

Đầu ra

2015-08-04 formats as 04 Aug 2015

(xem danh sách đầy đủ các Mẫu để Định dạng và Phân tích Ngày Định dạng )

  Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   G       era                         text              AD; Anno Domini; A
   u       year                        year              2004; 04
   y       year-of-era                 year              2004; 04
   D       day-of-year                 number            189
   M/L     month-of-year               number/text       7; 07; Jul; July; J
   d       day-of-month                number            10

   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
   Y       week-based-year             year              1996; 96
   w       week-of-week-based-year     number            27
   W       week-of-month               number            4
   E       day-of-week                 text              Tue; Tuesday; T
   e/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; T
   F       week-of-month               number            3

   a       am-pm-of-day                text              PM
   h       clock-hour-of-am-pm (1-12)  number            12
   K       hour-of-am-pm (0-11)        number            0
   k       clock-hour-of-am-pm (1-24)  number            0

   H       hour-of-day (0-23)          number            0
   m       minute-of-hour              number            30
   s       second-of-minute            number            55
   S       fraction-of-second          fraction          978
   A       milli-of-day                number            1234
   n       nano-of-second              number            987654321
   N       nano-of-day                 number            1234000000

   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
   z       time-zone name              zone-name         Pacific Standard Time; PST
   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

   p       pad next                    pad modifier      1

   '       escape for text             delimiter
   ''      single quote                literal           '
   [       optional section start
   ]       optional section end
   #       reserved for future use
   {       reserved for future use
   }       reserved for future use

11
Câu trả lời này đã chạm vào một chủ đề quan trọng: sử dụng các trình định dạng được xác định trước bất cứ khi nào có thể, ví dụ: KHÔNG tạo cơ sở định dạng trên "yyyy-MM-dd", thay vào đó, hãy sử dụng DateTimeFormatter.ISO_LOCAL_DATE. Nó sẽ làm cho mã của bạn trông sạch hơn rất nhiều. Hơn nữa, hãy cố gắng tối đa hóa việc sử dụng định dạng ISO8061, nó sẽ trả cổ tức trong thời gian dài.
Christopher Yang

Tôi muốn phân tích một ngày để xác thực như thế nào 2018-08-09 12:00:08nhưng khi tôi phân tích cú pháp tôi thấy một cái Tđược thêm vào mà tôi không cần. Có cách nào để làm điều đó ?
Raghuveer

@Raghuveer T chỉ là dấu phân cách ISO-8061 giữa ngày và giờ. Nếu bạn có một khoảng trắng trong định dạng của mình, bạn chỉ cần sử dụng mẫu yyyy-MM-dd hh:mm:ssđể phân tích cú pháp và định dạng. T sẽ luôn hiển thị ở định dạng mặc định (ISO-8061), nhưng bạn có thể sử dụng các mẫu của riêng bạn.
Egor Hans

39

Cả hai câu trả lời trên đều giải thích rất rõ câu hỏi liên quan đến các mẫu chuỗi. Tuy nhiên, chỉ trong trường hợp bạn đang làm việc với ISO 8601 , không cần phải áp dụng DateTimeFormattervì LocalDateTime đã được chuẩn bị cho nó:

Chuyển đổi LocalDateTime thành Chuỗi múi giờ ISO8601

LocalDateTime ldt = LocalDateTime.now(); 
ZonedDateTime zdt = ldt.atZone(ZoneOffset.UTC); //you might use a different zone
String iso8601 = zdt.toString();

Chuyển đổi từ Chuỗi ISO8601 trở lại LocalDateTime

String iso8601 = "2016-02-14T18:32:04.150Z";
ZonedDateTime zdt = ZonedDateTime.parse(iso8601);
LocalDateTime ldt = zdt.toLocalDateTime();

20

Phân tích một chuỗi với ngày và thời gian vào một thời điểm cụ thể (Java gọi đó là " Instant") khá phức tạp. Java đã giải quyết điều này trong một số lần lặp. Cái mới nhất, java.timejava.time.chrono, đáp ứng hầu hết tất cả các nhu cầu (ngoại trừ Time Dilation :)).

Tuy nhiên, sự phức tạp đó mang lại rất nhiều nhầm lẫn.

Chìa khóa để hiểu phân tích ngày là:

Tại sao Java có nhiều cách để phân tích một ngày

  1. Có một số hệ thống để đo thời gian. Ví dụ, lịch Nhật Bản lịch sử được bắt nguồn từ khoảng thời gian trị vì của hoàng đế hoặc triều đại tương ứng. Sau đó, có ví dụ như dấu thời gian UNIX. May mắn thay, toàn bộ thế giới (kinh doanh) quản lý để sử dụng như nhau.
  2. Trong lịch sử, các hệ thống đã được chuyển từ / sang, vì nhiều lý do . Ví dụ: từ lịch Julian đến lịch Gregorian năm 1582. Vì vậy, ngày 'tây' trước đó cần phải được đối xử khác nhau.
  3. Và tất nhiên sự thay đổi đã không xảy ra ngay lập tức. Bởi vì lịch xuất phát từ các trụ sở của một số tôn giáo và các khu vực khác của châu Âu tin vào các chế độ ăn kiêng khác, ví dụ, Đức đã không chuyển sang năm 1700.

... và tại sao LocalDateTime, ZonedDateTimeet al. quá phức tạp

  1. múi giờ . Múi giờ về cơ bản là một "dải" * [1] trên bề mặt Trái đất có chính quyền tuân theo các quy tắc tương tự khi nào nó có thời gian bù. Điều này bao gồm các quy tắc thời gian mùa hè.
    Các múi giờ thay đổi theo thời gian cho các khu vực khác nhau, chủ yếu dựa trên người chinh phục ai. Và quy tắc của một múi giờ cũng thay đổi theo thời gian .

  2. Có thời gian bù đắp. Điều đó không giống với múi giờ, bởi vì múi giờ có thể là "Prague", nhưng điều đó có thời gian bù vào mùa hè và thời gian bù vào mùa đông.
    Nếu bạn nhận được dấu thời gian với múi giờ, độ lệch có thể thay đổi, tùy thuộc vào phần nào của năm. Trong giờ nhuận, dấu thời gian có thể có nghĩa là 2 thời điểm khác nhau, vì vậy không có thông tin bổ sung, không thể tin cậy được chuyển đổi.
    Lưu ý: Theo dấu thời gian, tôi có nghĩa là "một chuỗi chứa ngày và / hoặc thời gian, tùy ý có múi giờ và / hoặc thời gian bù."

  3. Một số múi giờ có thể chia sẻ cùng thời gian bù cho các khoảng thời gian nhất định. Chẳng hạn, múi giờ GMT / UTC giống như múi giờ "London" khi thời gian bù mùa hè không có hiệu lực.

Để làm cho nó phức tạp hơn một chút (nhưng điều đó không quá quan trọng đối với trường hợp sử dụng của bạn):

  1. Các nhà khoa học quan sát động lực của Trái đất, thay đổi theo thời gian; dựa vào đó, họ thêm giây vào cuối năm riêng lẻ. (Vì vậy, 2040-12-31 24:00:00có thể là thời gian ngày hợp lệ.) Điều này cần cập nhật thường xuyên của siêu dữ liệu mà các hệ thống sử dụng để có quyền chuyển đổi ngày. Ví dụ: trên Linux, bạn nhận được các bản cập nhật thường xuyên cho các gói Java bao gồm các dữ liệu mới này.
  2. Các bản cập nhật không phải lúc nào cũng giữ hành vi trước đó cho cả dấu thời gian lịch sử và tương lai. Vì vậy, có thể xảy ra việc phân tích hai dấu thời gian xung quanh thay đổi của múi giờ so với chúng có thể cho kết quả khác nhau khi chạy trên các phiên bản phần mềm khác nhau. Điều đó cũng áp dụng để so sánh giữa múi giờ bị ảnh hưởng và múi giờ khác.

    Nếu điều này gây ra lỗi trong phần mềm của bạn, hãy xem xét sử dụng một số dấu thời gian không có các quy tắc phức tạp như dấu thời gian UNIX .

  3. Vì 7, cho những ngày trong tương lai, chúng tôi không thể chuyển đổi ngày chính xác một cách chắc chắn. Vì vậy, ví dụ, phân tích cú pháp hiện tại 8524-02-17 12:00:00có thể tắt một vài giây từ phân tích cú pháp trong tương lai.

API của JDK cho điều này phát triển với nhu cầu hiện đại

  • Các bản phát hành Java đầu tiên có java.util.Datecách tiếp cận hơi ngây thơ, giả sử rằng chỉ có năm, tháng, ngày và thời gian. Điều này nhanh chóng không đủ.
  • Ngoài ra, nhu cầu của cơ sở dữ liệu là khác nhau, do đó khá sớm, java.sql.Dateđã được giới thiệu, với những hạn chế riêng của nó.
  • Vì không bao gồm các lịch và múi giờ khác nhau, CalendarAPI đã được giới thiệu.
  • Điều này vẫn không bao gồm sự phức tạp của các múi giờ. Tuy nhiên, sự pha trộn của các API trên thực sự là một vấn đề khó khăn. Vì vậy, khi các nhà phát triển Java bắt đầu làm việc trên các ứng dụng web toàn cầu, các thư viện nhắm vào hầu hết các trường hợp sử dụng, như JodaTime, đã nhanh chóng trở nên phổ biến. JodaTime là tiêu chuẩn thực tế trong khoảng một thập kỷ.
  • Nhưng JDK không tích hợp với JodaTime, vì vậy làm việc với nó hơi cồng kềnh. Vì vậy, sau một cuộc thảo luận rất dài về cách tiếp cận vấn đề, JSR-310 được tạo ra chủ yếu dựa trên JodaTime .

Làm thế nào để đối phó với nó trong Java java.time

Xác định loại để phân tích dấu thời gian

Khi bạn đang sử dụng một chuỗi dấu thời gian, bạn cần biết nó chứa thông tin gì. Đây là điểm quan trọng. Nếu bạn không có quyền này, bạn sẽ có một ngoại lệ khó hiểu như "Không thể tạo tức thì" hoặc "Vùng bị thiếu" hoặc "id vùng không xác định", v.v.

Nó có chứa ngày và thời gian không?

  1. Nó có bù thời gian không?
    Một thời gian bù là +hh:mmmột phần. Đôi khi, +00:00có thể được thay thế bằng Z'Thời gian Zulu', UTCnhư Giờ phối hợp quốc tế, hoặc GMTlà Giờ trung bình của Greenwich. Những cái này cũng đặt múi giờ.
    Đối với những dấu thời gian này, bạn sử dụng OffsetDateTime.

  2. Nó có múi giờ không?
    Đối với những dấu thời gian này, bạn sử dụng ZonedDateTime.
    Vùng được chỉ định bởi

    • tên ("Prague", "Giờ chuẩn Thái Bình Dương", "PST") hoặc
    • "ID khu vực" ("America / Los_Angele", "Châu Âu / Luân Đôn"), được đại diện bởi java.time.ZoneId .

    Danh sách các múi giờ được biên soạn bởi "cơ sở dữ liệu TZ" , được hỗ trợ bởi ICAAN.

    Theo ZoneIdjavadoc, id của khu vực bằng cách nào đó cũng có thể được chỉ định là Zvà bù. Tôi không chắc làm thế nào bản đồ này đến khu vực thực. Nếu dấu thời gian, chỉ có TZ, rơi vào một giờ nhuận thay đổi thời gian, thì đó là mơ hồ, và việc giải thích là chủ đề ResolverStyle, xem bên dưới.

  3. Nếu nó không có , thì bối cảnh bị thiếu được giả định hoặc bỏ qua. Và người tiêu dùng phải quyết định. Vì vậy, nó cần được phân tích cú pháp LocalDateTimevà chuyển đổi thành OffsetDateTimebằng cách thêm thông tin còn thiếu:

    • Bạn có thể cho rằng đó là thời gian UTC. Thêm độ lệch UTC là 0 giờ.
    • Bạn có thể cho rằng đó là thời điểm diễn ra việc chuyển đổi. Chuyển đổi nó bằng cách thêm múi giờ của hệ thống.
    • Bạn có thể bỏ qua và chỉ sử dụng nó như là. Điều đó rất hữu ích, ví dụ để so sánh hoặc trừ hai lần (xem Duration) hoặc khi bạn không biết và điều đó không thực sự quan trọng (ví dụ: lịch trình xe buýt địa phương).

Thông tin bán thời gian

  • Dựa trên những gì các dấu thời gian chứa, bạn có thể mất LocalDate, LocalTime,OffsetTime , MonthDay, Year, hoặc YearMonthra khỏi nó.

Nếu bạn có thông tin đầy đủ, bạn có thể nhận được một java.time.Instant . Điều này cũng được sử dụng nội bộ để chuyển đổi giữa OffsetDateTimeZonedDateTime.

Tìm hiểu làm thế nào để phân tích nó

Có một tài liệu mở rộng DateTimeFormattermà cả hai có thể phân tích chuỗi dấu thời gian và định dạng thành chuỗi.

Các s được tạo trướcDateTimeFormatter sẽ bao gồm tất cả các định dạng dấu thời gian chuẩn. Ví dụ, ISO_INSTANTcó thể phân tích cú pháp 2011-12-03T10:15:30.123457Z.

Nếu bạn có một số định dạng đặc biệt, thì bạn có thể tạo DateTimeFormatter của riêng bạn (cũng là một trình phân tích cú pháp).

private static final DateTimeFormatter TIMESTAMP_PARSER = new DateTimeFormatterBuilder()
   .parseCaseInsensitive()
   .append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SX"))
   .toFormatter();

Tôi khuyên bạn nên xem mã nguồn của DateTimeFormattervà lấy cảm hứng về cách xây dựng một mã nguồn bằng cách sử dụngDateTimeFormatterBuilder . Trong khi bạn ở đó, cũng có một cái nhìn ResolverStyleđể kiểm soát xem trình phân tích cú pháp là LENIENT, SMART hay STRICT cho các định dạng và thông tin mơ hồ.

TemporalAccessor

Bây giờ, lỗi thường xuyên là đi vào sự phức tạp của TemporalAccessor. Điều này xuất phát từ cách các nhà phát triển đã được sử dụng để làm việc với SimpleDateFormatter.parse(String). Phải, DateTimeFormatter.parse("...")cho bạn TemporalAccessor.

// No need for this!
TemporalAccessor ta = TIMESTAMP_PARSER.parse("2011-... etc");

Nhưng, được trang bị kiến ​​thức từ phần trước, bạn có thể thuận tiện phân tích thành loại bạn cần:

OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z", TIMESTAMP_PARSER);

Bạn thực sự không cần phải DateTimeFormattermột trong hai. Các loại bạn muốn phân tích cú pháp có các parse(String)phương thức.

OffsetDateTime myTimestamp = OffsetDateTime.parse("2011-12-03T10:15:30.123457Z");

Về TemporalAccessor, bạn có thể sử dụng nó nếu bạn có một ý tưởng mơ hồ về thông tin nào có trong chuỗi và muốn quyết định khi chạy.

Tôi hy vọng tôi làm sáng tỏ tâm hồn của bạn :)

Lưu ý: Có một backport của java.timeJava 6 và 7: ThreeTen-Backport . Đối với Android, nó có ThreeTenABP .

[1] Không chỉ là chúng không phải là sọc, mà còn có một số thái cực kỳ lạ. Chẳng hạn, một số đảo Thái Bình Dương lân cận có múi giờ +14: 00 và -11: 00. Điều đó có nghĩa là, trong khi ở một hòn đảo, có ngày 1 tháng 3 ngày 3 tháng 5, ở một hòn đảo khác không xa, vẫn là ngày 30 tháng 4 ngày 12 tháng 4 (nếu tôi đếm đúng :))


3

NHẬN THỜI GIAN UTC HIỆN TẠI TRONG ĐỊNH DẠNG YÊU CẦU

// Current UTC time
        OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);

        // GET LocalDateTime 
        LocalDateTime localDateTime = utc.toLocalDateTime();
        System.out.println("*************" + localDateTime);

        // formated UTC time
        DateTimeFormatter dTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(" formats as " + dTF.format(localDateTime));

        //GET UTC time for current date
        Date now= new Date();
        LocalDateTime utcDateTimeForCurrentDateTime = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDateTime();
        DateTimeFormatter dTF2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(" formats as " + dTF2.format(utcDateTimeForCurrentDateTime));

0

Tôi thấy thật tuyệt vời khi bao gồm nhiều biến thể của định dạng thời gian ngày như thế này:

final DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS"))
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"))
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);

1
`` `static static DateTimeFormatter TIMESTAMP_XX = new DateTimeFormatterBuilder (). appendPotype (" [[uuuu] [- MM] [- dd]] [[HH] [: mm] [: ss] [. SSS]] "). parseDefaulting (ChronoField.YEAR, 2020) .parseDefaulting (ChronoField.MONTH_OF_YEAR, 1) .parseDefaulting , 0) .parseDefaulting (ChronoField.NANO_OF_SECOND, 0) .toFormatter (); `` `
Alan Stewart
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.