Làm cách nào để trừ ngày X khỏi một đối tượng Date trong Java?


146

Tôi muốn làm một cái gì đó như:

Date date = new Date(); // current date
date = date - 300; // substract 300 days from current date and I want to use this "date"

Làm thế nào để làm nó?


4
Nhận xét bắt buộc "Sử dụng thời gian Joda".
Steve McLeod

1
Các liên kết sau đây có thể hữu ích cho bạn [nhập liên kết mô tả ở đây] [1] [nhập liên kết mô tả ở đây] [2] [1]:. Stackoverflow.com/questions/212321/... [2]: stackoverflow.com/questions/ 2623610 / Lọ
Ami

FYI, các lớp thời gian cũ rắc rối như java.util.Datebây giờ là di sản , được thay thế bởi các lớp java.time .
Basil Bourque

Câu trả lời:


279

Java 8 trở lên

Với thay đổi API thời gian của Java 8, Sử dụng LocalDate

LocalDate date = LocalDate.now().minusDays(300);

Tương tự bạn có thể có

LocalDate date = someLocalDateInstance.minusDays(300);

Tham khảo https://stackoverflow.com/a/23885950/260990 để dịch giữa java.util.Date <-> java.time.LocalDateTime

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

Java 7 trở về trước

Sử dụng Calendar's add()phương pháp

Calendar cal = Calendar.getInstance();
cal.setTime(dateInstance);
cal.add(Calendar.DATE, -30);
Date dateBefore30Days = cal.getTime();

22
Đó là đặt ngày tùy chỉnh của bạn trong trường hợp bạn không muốn xem xét thời gian ngày hiện tại
Jigar Joshi

11
Xử lý ngày của Java là rất lớn !
digoo doo

1
Đây là câu trả lời 4 tuổi. đã có những thay đổi API DateTime mới được thực hiện cho các phiên bản gần đây của nó. Tôi sẽ chỉnh sửa câu trả lời
Jigar Joshi

FYI, người già lớp ngày thời gian phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleTextFormatbây giờ là di sản , thay thế bởi sự java.time lớp. Xem Hướng dẫn của Oracle .
Basil Bourque

@JigarJoshi sẽ thật tuyệt vời nếu bạn cập nhật câu trả lời của mình với API Java 8. Câu trả lời của bạn là câu trả lời mà mọi người nhìn thấy đầu tiên.
jotaen

47

@JigarJoshi đó là câu trả lời tốt, và tất nhiên cũng khuyến nghị @Tim sử dụng. Joda thời gian .

Tôi chỉ muốn thêm nhiều khả năng để trừ ngày từ a java.util.Date.

Thông tin chung

Một khả năng là sử dụng apache-commons-lang . Bạn có thể làm điều đó bằng cách sử dụng DateUtilsnhư sau:

Date dateBefore30Days = DateUtils.addDays(new Date(),-30);

Tất nhiên, thêm commons-langphụ thuộc để chỉ trừ ngày có lẽ không phải là một lựa chọn tốt, tuy nhiên nếu bạn đang sử dụng commons-langthì đó là một lựa chọn tốt. Ngoài ra còn có phương pháp thuận tiện để addYears, addMonths, addWeeksvà như vậy, hãy nhìn vào các api đây .

Java 8

Một khả năng khác là tận dụng lợi thế mới LocalDatetừ Java 8 bằng minusDays(long days)phương thức:

LocalDate dateBefore30Days = LocalDate.now(ZoneId.of("Europe/Paris")).minusDays(30);

Không có điểm nào để sử dụng LocalDateTimevì lớp đó cố tình không có khái niệm về múi giờ cũng như không bù từ UTC. Chỉ sử dụng khi vùng / offset không xác định hoặc không liên quan. Thay vào đó sử dụng LocalDatevà vượt qua ZoneIdkhi gọi nowphương thức của nó . Xem câu trả lời đúng của Jacob van Lingen.
Basil Bourque

1
@BasilBourque Sau lời khuyên của bạn, tôi kiểm tra api và bạn hoàn toàn đúng, do đó tôi cập nhật câu trả lời. cảm ơn.
albciff

Brian Montellano muốn bình luận: không nên có bất kỳ stại DateUtils, nó chỉ là DateUtil.
Ole VV

@ OleV.V. Brian Montellano đã sai, bạn có thể kiểm tra DateUtilstài liệu
albciff

33

Chỉ cần sử dụng điều này để có được ngày trước 300 ngày, thay thế 300 bằng ngày của bạn:

Date date = new Date(); // Or where ever you get it from
Date daysAgo = new DateTime(date).minusDays(300).toDate();

Đây,

DateTimeorg.joda.time.DateTime;

Datejava.util.Date


7
Các Joda thời gian dự án hiện đang trong chế độ bảo trì , và khuyên chuyển đổi sang các java.time lớp.
Basil Bourque

13

API thời gian Java 8:

Instant now = Instant.now(); //current date
Instant before = now.minus(Duration.ofDays(300));
Date dateBefore = Date.from(before);

Tôi phải có nghĩa là API Java 8, không phải 7. Và đề cập đến gói java.timecó thể giúp ích. Ngoài ra, một số thảo luận / giải thích thường được mong đợi trên Stack Overflow thay vì chỉ là một đoạn mã. Bạn chắc chắn nên giải thích Durationvì đó là giá trị gia tăng của Câu trả lời của bạn so với câu trả lời hiện có của van Lingen .
Basil Bourque

Java 8 nguyên nhân, đã được sửa
Grigory Kislin

rất gần, nhưng nên để sửa đổi một đối tượng ngày tùy ý, không phải "bây giờ"
bharal

9

Như bạn có thể thấy TẠI ĐÂY có rất nhiều thao tác bạn có thể làm. Dưới đây là một ví dụ cho thấy những gì bạn có thể làm!

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();

//Add one day to current date.
cal.add(Calendar.DATE, 1);
System.out.println(dateFormat.format(cal.getTime()));

//Substract one day to current date.
cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
System.out.println(dateFormat.format(cal.getTime()));

/* Can be Calendar.DATE or
*  Calendar.MONTH, Calendar.YEAR, Calendar.HOUR, Calendar.SECOND
*/

@Jigar Joshi: Tôi không thấy câu trả lời của bạn ... Tôi có nên xóa câu trả lời của tôi không?
waldyr.ar

FYI, người già lớp 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

9

Với Java 8 bây giờ thực sự đơn giản:

 LocalDate date = LocalDate.now().minusDays(300);

Một hướng dẫn tuyệt vời cho api mới có thể được tìm thấy ở đây .


4
Tôi đề nghị luôn luôn vượt qua múi giờ tùy chọn (hoặc offset-từ-UTC) cho nowphương thức đó . Nếu bị bỏ qua, múi giờ mặc định hiện tại của JVM sẽ được áp dụng ngầm và âm thầm. Mặc định đó nằm ngoài tầm kiểm soát của bạn và có thể thay đổi bất cứ lúc nào, ngay cả trong thời gian chạy. Ví dụ : LocalDate.now( ZoneId.of( "America/Montreal" ).
Basil Bourque

cần phải ở trên một đối tượng ngày tùy ý theo câu hỏi, không phải "bây giờ"
bharal

1

Tôi đã tạo ra một chức năng để làm cho nhiệm vụ dễ dàng hơn.

  • Trong 7 ngày sau dateString: dateCalculate(dateString,"yyyy-MM-dd",7);

  • Để có được 7 ngày cho đến ngàyString: dateCalculate(dateString,"yyyy-MM-dd",-7);


public static String dateCalculate(String dateString, String dateFormat, int days) {
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat s = new SimpleDateFormat(dateFormat);
    try {
        cal.setTime(s.parse(dateString));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    cal.add(Calendar.DATE, days);
    return s.format(cal.getTime());
}

Đây trả lời sử dụng phiền hà lớp ngày thời gian cũ như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time lớp. Xem Hướng dẫn của Oracle .
Basil Bourque

Câu hỏi liên quan đến các đối tượng thời gian, không tạo ra chuỗi. Nhân tiện, LocalDate.parse( "2017-01-23").plusWeeks( 1 )đơn giản hơn là viết phương pháp của riêng bạn và tự viết tài liệu nhiều hơn.
Basil Bourque

0

Bạn có thể dễ dàng trừ đi với lịch với SimpleDateFormat

 public static String subtractDate(String time,int subtractDay) throws ParseException {


        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
        cal.setTime(sdf.parse(time));
        cal.add(Calendar.DATE,-subtractDay);
        String wantedDate = sdf.format(cal.getTime());

        Log.d("tag",wantedDate);
        return wantedDate;

    }

-4
c1.set(2017, 12 , 01); //Ex: 1999 jan 20    //System.out.println("Date is : " + sdf.format(c1.getTime()));
  c1.add(Calendar.MONTH, -2); // substract 1 month
  System.out.println
  ("Date minus 1 month : "
      + sdf.format(c1.getTime()));

2
Chào mừng đến với SO. Xin vui lòng kiềm chế chỉ mã câu trả lời. Xem stackoverflow.com/help/how-to-answer . Và hãy định dạng mã của bạn.
Uwe Allner
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.