2016-03-30 26 views
8

Tôi muốn đặt DateTimeFormatter của riêng mình làm trình định dạng chung. Khi tôi làm dòng sau:Java 8 Đặt định dạng thời gian toàn cầu

ZonedDateTime.now(); 

tôi nhận được:

2016-03-30T08:58:54.180-06:00[America/Chicago] 

Nếu tôi làm điều này:

ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME) 

tôi nhận được:

Wed, 30 Mar 2016 9:00:06 -0600 

Tôi muốn những gì đang in ở trên nhưng với am/pm vì vậy tôi đã thực hiện định dạng tùy chỉnh của mình và in ra thời gian như vậy:

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z"); 

ZonedDateTime.now().format(FORMATTER); 

nào đã cho tôi:

Wed, 30 Mar 2016 9:00:06 AM -0600 

Nhưng tôi sử dụng phương pháp .now() này ở khắp mọi nơi cho mục đích khai thác gỗ và Tôi không muốn xác định các định dạng ở khắp mọi nơi trong các mã. Có cách nào để định cấu hình trình định dạng làm định dạng mặc định để sử dụng khi gọi phương thức .now() không? Tôi đang nghĩ đến như phương pháp cấu hình đậu mùa xuân hoặc một cái gì đó .....

+2

Tại sao không tạo FORMATTER tĩnh đơn và truy cập ở mọi nơi? – Loc

+0

Tôi không chắc mình hiểu. 'ZonedDateTime.now()' không phụ thuộc vào bất kỳ trình định dạng nào. Và nếu bạn muốn một người duy nhất định dạng sau khi gọi 'định dạng', tại sao không chỉ có một hằng số ở đâu đó? – Tunaki

+0

Những gì bạn nhận được là kết quả toString: bạn đang sử dụng println? logger? một serializer? Nếu bạn đang ở trong trường hợp toString, không có nhiều việc phải làm. – pdem

Trả lời

5

Bạn chỉ có thể tuyên bố một hằng số trong một lớp học:

class UtilsOrWhatever { 
    public static final DateTimeFormater RFC_1123_DATE_TIME_AM_PM = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy hh:mm:ss a Z"); 
} 

và chỉ cần sử dụng trong mã của bạn:

ZonedDateTime.now().format(RFC_1123_DATE_TIME_AM_PM); //needs a static import 

Ngoài ra, với Java EE 7 thuần túy, bạn có thể tạo a DateTimeFormatter Producer với @Produces và sau đó chỉ cần @Inject nó.

import javax.enterprise.context.ApplicationScoped; 
import javax.enterprise.inject.Produces; 

@ApplicationScoped 
public class RfcFormatterProducer { 
    @Produces 
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy hh:mm:ss a Z"); 
} 

Trong mã của bạn:

@Inject DateTimeFormatter rfc; 

Bạn cũng có thể cung cấp cho nó một cái tên như thế nào trong các liên kết ở trên nếu bạn có nhiều trình định dạng.

+0

nhưng tôi sẽ phải tiêm vào tất cả các lớp mà tôi muốn in ra đúng giờ? Hay không? – Richard

+1

có bạn sẽ - không có cách nào để "ghi đè" hành vi của phương thức 'định dạng'. Định nghĩa một hằng số ở đâu đó 'public static final DateTimeFormater RFC_1123_DATE_TIME_AM_PM = ...' cũng là một tùy chọn. – assylias

+0

Xác định nó ở đâu đó và làm cho nó tĩnh là một ý tưởng tuyệt vời. Điều đó giữ mã hơi sạch. Nó không phải là giải pháp lý tưởng nhất nhưng giải pháp lý tưởng là không thể, vì vậy đây là điều tốt nhất tiếp theo. Cảm ơn bạn! – Richard

0

Hãy để tôi giải thích lý do tại sao bạn nhận được những gì bạn nhận được khi bạn không gọi định dạng. Các toString đang được gọi trên ZonedDateTime mà lần lượt gọi toString trên ngày DateTime và Offset, mà gọi toString trên LocalDate và LocalTime. Các toStrings này không sử dụng các trình định dạng, vì vậy ngay cả khi bạn có thể chỉ định một trình định dạng "mặc định", nó sẽ không được gọi khi chuyển đổi một cách rõ ràng một ZonedDateTime thành một chuỗi.

Có nhiều cách để sản xuất chuỗi định dạng dễ dàng hơn. Một cách sẽ là một lớp tiện ích mà bạn sẽ trao đổi cho tất cả các câu lệnh đăng nhập của bạn. Tôi không nhất thiết phải đề nghị sau đây, nhưng nó phù hợp chặt chẽ nhất những gì bạn đang yêu cầu:

public class MyAwesomeUtility { 
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z"); 

    public static String getFormattedZonedDateTime() { 
     return ZonedDateTime.now().format(FORMATTER); 
    } 
} 

Sau đây không phải là một lựa chọn như ZonedDateTime là cuối cùng như đã chỉ ra bởi @assylias. Để điều này ở đây trong mọi trường hợp.

Nếu bạn thực sự muốn làm những gì bạn hỏi trong câu hỏi, ghi đè phương thức now để trả về một đối tượng có định dạng được chỉ định khi toString được gọi là bạn sẽ phải làm như sau : đây là một antipattern không thực sự làm CNTT):.

public class DefaultFormattedZonedDateTime extends ZonedDateTime { 
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z"); 
    @Overwrite 
    public String toString() { 
     this.format(FORMATTER); 
    } 
} 

Sau đó, kể từ now trên ZonedDateTime là tĩnh và vẫn trả ZonedDateTime bạn sẽ phải sử dụng AspectJ (bạn có thể không có mặt ở AOP một phương pháp tĩnh với mùa xuân một mình) để bây giờ trả lại đối tượng mới này.

+5

ZonedDateTime là cuối cùng ... – assylias

+0

Bắt tốt. Tôi thậm chí còn không nhận ra điều đó. Tôi cập nhật câu trả lời để giải thích nó không thực sự là một lựa chọn. –

Các vấn đề liên quan