Bagaimana cara mengurangi X hari dari objek Date di Java?


147

Saya ingin melakukan sesuatu seperti:

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

Bagaimana cara melakukannya?


4
Wajib "Gunakan Waktu Joda".
Steve McLeod

1
Tautan berikut mungkin berguna bagi Anda. [Masukkan uraian tautan di sini] [1] [masukkan uraian tautan di sini] [2] [1]: stackoverflow.com/questions/212321/… [2]: stackoverflow.com/questions/ 2623610 / ...
Ami

FYI, kelas tanggal-waktu lama bermasalah seperti java.util.Datesekarang warisan , digantikan oleh kelas java.time .
Basil Bourque

Jawaban:


280

Java 8 dan yang lebih baru

Dengan perubahan API tanggal waktu Java 8, Gunakan LocalDate

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

Demikian pula yang bisa Anda miliki

LocalDate date = someLocalDateInstance.minusDays(300);

Rujuk ke https://stackoverflow.com/a/23885950/260990 untuk terjemahan antara 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 dan sebelumnya

Gunakan Calendar's add()metode

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

22
Ini adalah untuk mengatur tanggal kustomInstance Anda jika Anda tidak ingin mempertimbangkan waktu tanggal saat ini
Jigar Joshi

11
Penanganan tanggal Java sangat membengkak!
Digo doo

1
Ini adalah jawaban 4 tahun. telah ada perubahan DateTime API baru yang dibuat untuk versi terbaru itu. Saya akan mengedit jawabannya
Jigar Joshi

FYI, merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleTextFormatsekarang warisan , digantikan oleh java.time kelas. Lihat Tutorial oleh Oracle .
Basil Bourque

@JigarJoshi akan luar biasa jika Anda memperbarui jawaban Anda dengan Java 8 API. Jawaban Anda adalah yang diterima yang dilihat orang terlebih dahulu.
jotaen

47

@JigarJoshi itu jawaban yang bagus, dan tentu saja juga rekomendasi @Tim untuk digunakan. joda-waktu .

Saya hanya ingin menambahkan lebih banyak kemungkinan untuk mengurangi hari dari a java.util.Date.

Apache-commons

Satu kemungkinan adalah menggunakan apache-commons-lang . Anda dapat melakukannya menggunakan DateUtilssebagai berikut:

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

Tentu saja menambahkan commons-langketergantungan untuk hanya melakukan kurangkan kurangi itu mungkin bukan pilihan yang baik, namun jika Anda sudah menggunakannya commons-langitu pilihan yang baik. Ada juga metode nyaman untuk addYears, addMonths, addWeeksdan sebagainya, kita lihat di api disini .

Java 8

Kemungkinan lain adalah untuk mengambil keuntungan LocalDatedari Java 8 menggunakan minusDays(long days)metode:

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

Tidak ada gunanya menggunakan LocalDateTimekarena kelas itu sengaja tidak memiliki konsep zona waktu atau offset-dari-UTC. Gunakan itu hanya ketika zona / offset tidak diketahui atau tidak relevan. Alih-alih menggunakan LocalDatedan meneruskan ZoneIdsaat memanggil nowmetode. Lihat Jawaban yang benar oleh Jacob van Lingen.
Basil Bourque

1
@ BasilBourque Setelah saran Anda, saya memeriksa api dan Anda benar, karena itu saya memperbarui jawabannya. Terima kasih.
albciff

Brian Montellano ingin komentar: ada tidak boleh ada sdi DateUtils, itu hanya DateUtil.
Ole VV

@ OleV.V. Brian Montellano salah, Anda dapat memeriksa DateUtilsdokumen
albciff

33

Cukup gunakan ini untuk mendapatkan tanggal sebelum 300 hari, ganti 300 dengan hari-hari Anda:

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

Sini,

DateTime adalah org.joda.time.DateTime;

Date adalah java.util.Date


7
Proyek Joda-Time sekarang dalam mode pemeliharaan , dan menyarankan migrasi ke kelas java.time .
Basil Bourque

13

API Java 8 Time:

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

Maksud saya Java 8 API, bukan 7. Dan menyebutkan paket java.timemungkin membantu. Juga, beberapa diskusi / penjelasan umumnya diharapkan pada Stack Overflow daripada hanya potongan kode. Anda harus menjelaskan Durationkarena itu adalah nilai tambah dari Jawaban Anda atas yang sudah ada oleh van Lingen .
Basil Bourque

Java 8 penyebabnya, diperbaiki
Grigory Kislin

begitu dekat, tetapi harus untuk memodifikasi objek tanggal yang sewenang-wenang, bukan "sekarang"
bharal

9

Seperti yang dapat Anda lihat DI SINI ada banyak manipulasi yang dapat Anda lakukan. Berikut ini contoh yang menunjukkan apa yang dapat Anda lakukan!

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: Saya tidak melihat jawaban Anda ... Haruskah saya menghapus milik saya?
waldyr.ar

FYI, sangat merepotkan tua kelas tanggal-waktu seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatsekarang warisan , digantikan oleh java.time kelas dibangun ke Jawa 8 dan kemudian. Lihat Tutorial oleh Oracle .
Basil Bourque

9

Dengan Java 8 sekarang sangat sederhana:

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

Panduan hebat untuk api baru dapat ditemukan di sini .


4
Saya sarankan selalu melewati zona waktu opsional (atau offset-dari-UTC) ke nowmetode itu. Jika dihilangkan, zona waktu default JVM saat ini secara implisit dan diam-diam diterapkan. Default itu berada di luar kendali Anda dan dapat berubah setiap saat, bahkan saat runtime. Contoh: LocalDate.now( ZoneId.of( "America/Montreal" ).
Basil Bourque

perlu pada objek tanggal sewenang-wenang sesuai pertanyaan, bukan "sekarang"
bharal

1

Saya telah membuat fungsi untuk mempermudah tugas.

  • Selama 7 hari setelah dateString: dateCalculate(dateString,"yyyy-MM-dd",7);

  • Untuk mendapatkan 7 hari Perbaruan terbaru: 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());
}

Ini Jawaban penggunaan merepotkan kelas tanggal-waktu lama seperti java.util.Date, java.util.Calendar, dan java.text.SimpleDateFormatyang sekarang warisan , digantikan oleh java.time kelas. Lihat Tutorial oleh Oracle .
Basil Bourque

Pertanyaan ini melibatkan objek waktu-tanggal, bukan menghasilkan string. Omong-omong, LocalDate.parse( "2017-01-23").plusWeeks( 1 )lebih sederhana daripada menulis metode Anda sendiri dan lebih mendokumentasikan diri sendiri.
Basil Bourque

0

Anda dapat dengan mudah mengurangi dengan kalender dengan 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
Selamat datang di SO. Harap hindari jawaban hanya kode. Lihat stackoverflow.com/help/how-to-answer . Dan tolong format kode Anda.
Uwe Allner
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.