tl; dr
LocalDate
.now(ZoneId.of("Pacific/Auckland")) // Get the date-only value for the current moment in a specified time zone.
.minusWeeks(1) // Go back in time one week.
.atStartOfDay(ZoneId.of("Pacific/Auckland")) // Determine the first moment of the day for that date in the specified time zone.
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) // Generate a string in standard ISO 8601 format.
.replace("T" , " ") // Replace the standard "T" separating date portion from time-of-day portion with a SPACE character.
java.time
Cách tiếp cận hiện đại sử dụng các lớp java.time.
Lớp LocalDate
đại diện cho giá trị chỉ có ngày không có thời gian trong ngày và không có múi giờ.
Múi giờ rất quan trọng trong việc xác định ngày. Đối với bất kỳ thời điểm cụ thể nào, ngày thay đổi trên toàn cầu theo múi giờ. Ví dụ: một vài phút sau nửa đêm ở Paris France là một ngày mới trong khi vẫn “ngày hôm qua” trong Montréal Québec.
Chỉ định proper time zone name ở định dạng continent/region
, chẳng hạn như America/Montreal
, Africa/Casablanca
hoặc Pacific/Auckland
. Không bao giờ sử dụng từ viết tắt 3-4 ký tự như EST
hoặc IST
vì chúng là không múi giờ thực, không được chuẩn hóa và thậm chí không độc đáo (!).
ZoneId z = ZoneId.forID("America/Montreal") ;
LocalDate now = LocalDate.now (z) ;
Thực hiện một số phép tính sử dụng phương pháp minus…
và plus…
.
LocalDate weekAgo = now.minusWeeks(1);
Hãy để java.time xác định thời điểm đầu tiên trong ngày cho múi giờ mong muốn của bạn. Đừng cho rằng ngày bắt đầu tại 00:00:00
. Bất thường như Daylight Saving Time có nghĩa là ngày có thể bắt đầu vào một thời điểm khác như 01:00:00
.
ZonedDateTime weekAgoStart = weekAgo.atStartOfDay(z) ;
Tạo chuỗi đại diện cho đối tượng ZonedDateTime
sử dụng đối tượng DateTimeFormatter
. Tìm kiếm Stack Overflow cho nhiều cuộc thảo luận hơn về lớp này.
DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_DATE_TIME ;
String output = weekAgoStart.format(f) ;
Định dạng chuẩn gần với những gì bạn muốn, nhưng có một số T
ở giữa vị trí bạn muốn một không gian. Vì vậy, thay thế SPACE cho T
.
output = output.replace("T" , " ") ;
Về java.time
Khung java.time được xây dựng vào Java 8 và sau đó. Các lớp này thay thế các lớp học ngày giờ legacy phiền hà cũ như java.util.Date
, Calendar
, & SimpleDateFormat
.
Dự án Joda-Time, hiện đang ở maintenance mode, khuyên di chuyển đến các lớp java.time.
Để tìm hiểu thêm, hãy xem Oracle Tutorial. Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310.
Nơi lấy các lớp java.time?
Joda thời gian
Cập nhật: Dự án Joda-Thời gian bây giờ là trong chế độ bảo trì. Nhóm này khuyên bạn nên di trú sang các lớp java.time.
Sử dụng thư viện Joda-Time giúp công việc ngày giờ dễ dàng hơn nhiều.
Lưu ý việc sử dụng múi giờ. Nếu bỏ qua, bạn đang làm việc trong UTC hoặc múi giờ mặc định hiện tại của JVM.
DateTime now = DateTime.now (DateTimeZone.forID("America/Montreal")) ;
DateTime weekAgo = now.minusWeeks(1);
DateTime weekAgoStart = weekAgo.withTimeAtStartOfDay();
Tôi nghĩ bạn nên sử dụng Calendar.roll() thay vì Calendar.add() nếu bạn muốn xử lý quyền thay đổi tháng/năm. Ví dụ của bạn có thể sai giữa ngày 1 và 6 tháng 1. –
Tôi nghĩ điều ngược lại là đúng: roll() không xử lý các thay đổi tháng/năm khi được gọi vào ngày tháng, trong khi add() thực hiện. –
Ok, xấu của tôi! ;-) –