Câu trả lời:
Lấy từ các tài liệu ở đây :
Thêm hoặc trừ lượng thời gian đã chỉ định vào trường lịch đã cho, dựa trên quy tắc của lịch. Ví dụ: để trừ 5 ngày kể từ thời điểm hiện tại của lịch, bạn có thể đạt được nó bằng cách gọi:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
Calendar.DAY_OF_MONTH
trong trường hợp này vì nó sẽ không xử lý cuộn giữa các tháng như bạn muốn. Sử dụng Calendar.DAY_OF_YEAR
thay thế
Bạn có thể sử dụng add
phương thức và truyền cho nó một số âm. Tuy nhiên, bạn cũng có thể viết một phương thức đơn giản hơn mà không sử dụng Calendar
lớp như sau
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
Điều này nhận giá trị dấu thời gian của ngày (mili giây kể từ kỷ nguyên) và thêm số mili giây thích hợp. Bạn có thể truyền một số nguyên âm cho tham số ngày để thực hiện phép trừ. Điều này sẽ đơn giản hơn giải pháp lịch "thích hợp":
public static void addDays(Date d, int days)
{
Calendar c = Calendar.getInstance();
c.setTime(d);
c.add(Calendar.DATE, days);
d.setTime( c.getTime().getTime() );
}
Lưu ý rằng cả hai giải pháp này đều thay đổi Date
đối tượng được truyền dưới dạng tham số thay vì trả về hoàn toàn mới Date
. Một trong hai chức năng có thể dễ dàng thay đổi để làm điều đó theo cách khác nếu muốn.
java.util.Calendar
bây giờ là di sản , được thay thế bởi các lớp java.time . Xem Hướng dẫn của Oracle .
Câu trả lời của Anson sẽ hoạt động tốt trong trường hợp đơn giản, nhưng nếu bạn sẽ thực hiện bất kỳ phép tính ngày phức tạp nào hơn, tôi khuyên bạn nên kiểm tra Joda Time . Nó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều.
FYI trong Joda Thời gian bạn có thể làm
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
LocalDate.now().minusDays( 10 )
Tốt hơn để xác định múi giờ.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Các lớp thời gian cũ được gói cùng với các phiên bản đầu tiên của Java, như java.util.Date
/ .Calendar
, đã được chứng minh là rắc rối, khó hiểu và thiếu sót. Tránh chúng.
Java 8 và sau đó thay thế các lớp cũ đó bằng khung java.time mới. Xem hướng dẫn . Được xác định bởi JSR 310 , lấy cảm hứng từ Joda-Time và được mở rộng bởi dự án ThreeTen-Extra . Dự án ThreeTen-Backport chuyển ngược các lớp sang Java 6 & 7; dự án ThreeTenABP cho Android.
Câu hỏi mơ hồ, không rõ ràng nếu nó yêu cầu chỉ ngày hoặc thời gian.
LocalDate
Đối với một ngày duy nhất, không có thời gian trong ngày, sử dụng LocalDate
lớp. Lưu ý rằng múi giờ rất quan trọng trong việc xác định ngày, chẳng hạn như "hôm nay".
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTime
Nếu bạn có nghĩa là một thời gian ngày, sau đó sử dụng Instant
lớp để có được một khoảnh khắc trên dòng thời gian trong UTC . Từ đó, điều chỉnh theo múi giờ để lấy ZonedDateTime
đối tượng.
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
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ái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date
, Calendar
, & SimpleDateFormat
.
Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.
Để 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. Đặc điểm kỹ thuật là JSR 310 .
Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của bạn. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*
lớp.
Nơi để có được các lớp java.time?
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. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval
, YearWeek
, YearQuarter
, và nhiều hơn nữa .
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
chỉnh sửa: trình phân tích cú pháp dường như không thích liên kết đến Javadoc, vì vậy đây là bản rõ:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/CalWiki.html#add(int , int)
Thay vì tự viết addDays
theo đề xuất của Eli, tôi thích sử dụng DateUtils
từ Apache . Nó rất tiện dụng đặc biệt là khi bạn phải sử dụng nó nhiều nơi trong dự án của bạn.
API nói:
addDays(Date date, int amount)
Thêm một số ngày vào một ngày trả lại một đối tượng mới.
Lưu ý rằng nó trả về một Date
đối tượng mới và không thay đổi đối tượng trước đó.
Nó có thể được thực hiện dễ dàng bằng cách sau đây
Calendar calendar = Calendar.getInstance();
// from current time
long curTimeInMills = new Date().getTime();
long timeInMills = curTimeInMills - 5 * (24*60*60*1000); // `enter code here`subtract like 5 days
calendar.setTimeInMillis(timeInMills);
System.out.println(calendar.getTime());
// from specific time like (08 05 2015)
calendar.set(Calendar.DAY_OF_MONTH, 8);
calendar.set(Calendar.MONTH, (5-1));
calendar.set(Calendar.YEAR, 2015);
timeInMills = calendar.getTimeInMillis() - 5 * (24*60*60*1000);
calendar.setTimeInMillis(timeInMills);
System.out.println(calendar.getTime());
LocalDate
đơn giản hơn nhiều và phù hợp hơn.
Có người đề nghị Joda Thời gian như vậy - Tôi đã được sử dụng này CalendarDate lớp http://calendardate.sourceforge.net
Đây là một dự án hơi cạnh tranh với Joda Time, nhưng cơ bản hơn nhiều chỉ có 2 lớp. Nó rất tiện dụng và hoạt động tốt cho những gì tôi cần vì tôi không muốn sử dụng gói lớn hơn dự án của mình. Không giống như các đối tác Java, đơn vị nhỏ nhất của nó là ngày nên nó thực sự là một ngày (không giảm xuống còn mili giây hoặc một cái gì đó). Khi bạn tạo ngày, tất cả những gì bạn làm để trừ là một cái gì đó như myDay.addDays (-5) để quay lại 5 ngày. Bạn có thể sử dụng nó để tìm ngày trong tuần và những thứ tương tự. Một vi dụ khac:
CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);
Và:
//print 4 previous days of the week and today
String dayLabel = "";
CalendarDate today = new CalendarDate(TimeZone.getDefault());
CalendarDateFormat cdf = new CalendarDateFormat("EEE");//day of the week like "Mon"
CalendarDate currDay = today.addDays(-4);
while(!currDay.isAfter(today)) {
dayLabel = cdf.format(currDay);
if (currDay.equals(today))
dayLabel = "Today";//print "Today" instead of the weekday name
System.out.println(dayLabel);
currDay = currDay.addDays(1);//go to next day
}
Tôi tin rằng một cách sạch sẽ và tốt đẹp để thực hiện phép trừ hoặc thêm bất kỳ đơn vị thời gian nào (tháng, ngày, giờ, phút, giây, ...) có thể đạt được bằng cách sử dụng java.time.Instant lớp .
Ví dụ để trừ 5 ngày kể từ thời điểm hiện tại và nhận kết quả là Ngày:
new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());
Một ví dụ khác để trừ 1 giờ và thêm 15 phút:
Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));
Nếu bạn cần độ chính xác cao hơn, Instance đo đến tối đa nano giây. Phương pháp thao tác phần nano giây:
minusNano()
plusNano()
getNano()
Ngoài ra, hãy nhớ rằng Ngày đó không chính xác như Tức thì.
Date.from(Instant.now().minus(5, ChronoUnit.DAYS))
Giải pháp thứ hai của Eli Courtwright là sai, cần phải là:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
addDays
; Giải pháp của anh ấy là chính xác. Nếu bạn muốn trừ ngày kể từ ngày, bạn chuyển vào một giá trị âm cho days
.
java.util.Calendar
bây giờ là di sản , được thay thế bởi các lớp java.time . Xem Hướng dẫn của Oracle .