Відповіді:
Взято з документів тут :
Додає або віднімає вказану кількість часу до заданого поля календаря, виходячи з правил календаря. Наприклад, відняти 5 днів від поточного часу календаря, ви можете досягти цього, зателефонувавши:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
Calendar.DAY_OF_MONTH
в цьому випадку, оскільки він не буде обробляти рулон між місяцями, як хочете. Використовуйте Calendar.DAY_OF_YEAR
замість цього
Ви можете використовувати add
метод і передавати йому від’ємне число. Однак ви також можете написати простіший метод, який не використовує такий Calendar
клас, як наведений нижче
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
Це отримує значення часової позначки дати (мілісекунд з епохи) і додає належну кількість мілісекунд. Ви можете передати від'ємне ціле число для параметра днів, щоб зробити віднімання. Це було б простіше, ніж "правильне" рішення календаря:
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() );
}
Зауважте, що обидва ці рішення змінюють Date
об'єкт, переданий як параметр, а не повернення абсолютно нового Date
. Будь-яку функцію можна легко змінити, щоб зробити її іншим способом, якщо бажаєте.
java.util.Calendar
які зараз неспокійні, такі, як зараз, застарілі , замінені класами java.time . Дивіться Підручник від Oracle .
Відповідь Ансона буде добре працювати у простому випадку, але якщо ви збираєтесь робити якісь складніші розрахунки дати, рекомендую перевірити Joda Time . Це значно полегшить ваше життя.
FYI в Joda Time ви могли б зробити
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
LocalDate.now().minusDays( 10 )
Краще вказати часовий пояс.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Старі класи дат у часі з ранніми версіями Java, такі як java.util.Date
/ .Calendar
, виявилися клопіткими, заплутаними та хибними. Уникайте їх.
Java 8 і новіші версії витісняють ті старі класи з новою рамкою java.time. Дивіться Підручник . Визначений JSR 310 , натхненний Joda-Time та розширений проектом ThreeTen-Extra . Проект ThreeTen-Backport підтримує класи на Java 6 і 7; проект ThreeTenABP для Android.
Питання є розпливчастим, не зрозумілим, чи запитує він лише дату чи дату.
LocalDate
Використовуйте LocalDate
клас лише для побачень без часу . Зауважте, що часовий пояс має вирішальне значення для визначення дати, наприклад "сьогодні".
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTime
Якщо ви мали на увазі дату-час, використовуйте Instant
клас, щоб отримати момент на часовій шкалі в UTC . Звідти налаштуйте часовий пояс, щоб отримати ZonedDateTime
об’єкт.
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date
, Calendar
, і SimpleDateFormat
.
Проект Joda-Time , який зараз знаходиться в режимі обслуговування , радить перейти до класів java.time .
Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .
Ви можете обмінюватися об'єктами java.time безпосередньо зі своєю базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або пізнішої версії. Немає потреби в струнах, немає потреби в java.sql.*
заняттях.
Де отримати класи java.time?
Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є доказом можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval
, YearWeek
, YearQuarter
, і більш .
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
редагувати: аналізатору, здається, не подобається посилання на Javadoc, тому ось він знаходиться в простому тексті:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int , int)
Замість того , щоб писати мій власний , addDays
як запропонував Елі, я вважав за краще б використовувати DateUtils
з Apache . Це зручно, особливо коли вам доведеться використовувати його у кількох місцях у своєму проекті.
API говорить:
addDays(Date date, int amount)
Додає число днів до дати повернення нового об’єкта.
Зауважте, що він повертає новий Date
об'єкт і не вносить змін до попереднього.
Це легко зробити наступним чином
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
набагато простіше і доцільніше.
Хтось рекомендував Joda Time так - я використовував цей клас CalendarDate http://calendardate.sourceforge.net
Це дещо конкуруючий проект на Joda Time, але набагато більш базовий лише у 2-х класах. Це дуже зручно і чудово працювало для того, що мені потрібно, оскільки я не хотів використовувати пакет, більший за мій проект. На відміну від аналогів Java, його найменшою одиницею є день, тому це дійсно дата (не маючи її до мілісекунд чи щось таке). Після створення дати все, що ви робите, щоб відняти, - це щось на зразок myDay.addDays (-5), щоб повернутися на 5 днів. Ви можете використовувати його для пошуку дня тижня і подібних речей. Ще один приклад:
CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);
І:
//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
}
Я вважаю, що за допомогою класу java.time.Instant можна досягти чистого і приємного способу віднімання чи додавання будь-якої одиниці часу (місяців, днів, годин, хвилин, секунд ...) .
Приклад віднімання 5 днів від поточного часу та отримання результату за датою:
new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());
Ще один приклад віднімання 1 години та додавання 15 хвилин:
Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));
Якщо вам потрібна більша точність, Instance вимірює до наносекунд. Методи маніпулювання наносекундною частиною:
minusNano()
plusNano()
getNano()
Також майте на увазі, що Дата не така точна, як Миттєва.
Date.from(Instant.now().minus(5, ChronoUnit.DAYS))
Друге рішення Елі Кордрайт неправильне, воно повинно бути:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
addDays
: його рішення правильне. Якщо ви хочете відняти дні від дати, ви перераховуєте від’ємне значення для days
.
java.util.Calendar
які зараз неспокійні, такі, як зараз, застарілі , замінені класами java.time . Дивіться Підручник від Oracle .