Я хочу получить последнюю дату месяца и добавить к ней n месяцев, но экземпляр календаря занимает всего 30 дней в Java - PullRequest
1 голос
/ 25 апреля 2020
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calender = Calendar.getInstance();
calender.set(Calendar.DAY_OF_MONTH, calender.getActualMaximum(Calendar.DATE));
int months = 1;
calender.add(Calendar.MONTH, months );
String time = sdf .format(calender .getTime());
System.out.println(time);

Поскольку текущий месяц апрель, а последняя дата 2020-04-30 В следующем месяце последняя дата, я должен получить 2020-05-31, но я получаю последнюю дату как 2020-05-30

Что-то я делаю не так?

Ответы [ 3 ]

3 голосов
/ 25 апреля 2020

java .time

Я рекомендую использовать java .time, современный Java API даты и времени, для вашей работы с датами. Работать с ней гораздо приятнее, чем со старыми классами Calendar и SimpleDateFormat.

    LocalDate endOfNextMonth = 
            YearMonth                            // Represent an entire month in a particular year.
            .now(ZoneId.of("Europe/Volgograd"))  // Capture the current year-month as seen in a particular time zone. Returns a `YearMonth` object.
            .plusMonths(1)                       // Move to the next month. Returns another `YearMonth` object.
            .atEndOfMonth();                     // Determine the last day of that year-month. Returns a `LocalDate` object.

    String time = endOfNextMonth.toString();     // Represent the content of the `LocalDate` object by generating text in standard ISO 8601 format.

    System.out.println("Last day of next month: " + time);

Вывод при работе сегодня:

Последний день следующего месяца: 2020-05 -31

A YearMonth, как следует из названия, это год и месяц без дня месяца. У него есть метод atEndOfMonth, который удобно дает нам последний день месяца как LocalDate. LocalDate - это дата без времени суток, так что нам здесь нужно. И его метод toString удобно дает желаемый формат (это ISO 8601).

В зависимости от причины, по которой вы хотите в последний день другого месяца, есть несколько других подходов, которые вы можете рассмотреть. Если вам нужно обработать диапазоны дат, которые всегда начинаются и заканчиваются на границах месяца, вы можете:

  1. Представить свой диапазон как диапазон YearMonth объектов. Освободит ли это вас от знания последнего дня месяца в целом?
  2. Представляет конец вашего диапазона как первое число следующего месяца exclusive . Делать математику 1-го числа каждого месяца проще, поскольку это всегда день 1. Независимо от продолжительности месяца.

Что пошло не так в вашем коде?

Не важно, используете ли вы Calendar, LocalDate или какой-то другой класс, который вам нужен, чтобы делать вещи в обратном порядке: сначала добавьте один месяц, а затем найдите конец месяца. Как вы знаете, месяцы имеют разную продолжительность, поэтому важной частью является получение конца того месяца, в который вы хотите получить последний день . Другими словами: установка LocalDate или Calendar на последний день месяца корректно устанавливает его на последний день месяца в quration, но не указывает ему остаться в последний день месяца после последующих изменений его значения, таких как добавление месяца. Если вы добавите месяц к 29 апреля, вы получите 29 мая. Если вы добавите месяц к 30 апреля, вы получите 30 мая. Здесь не имеет значения, что 30 - последний день апреля, а 30 - не последний день Май.

Ссылки

2 голосов
/ 25 апреля 2020

Вам лучше использовать LocalDate вот так:

LocalDate now = LocalDate.now();
LocalDate lastDay = now.withDayOfMonth(now.lengthOfMonth());
LocalDate nextMonth = lastDay.plusMonths(1);
1 голос
/ 25 апреля 2020

Не использовать устаревшие классы из java.util.*.

Использовать классы из java.time.*.

Пример с LocalDate:

public class Testing {
    public static void main(String args[]) {
      DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
      LocalDate date = LocalDate.now();
      int months = 1;
      date = date.plusMonths(months);
      date = date.withDayOfMonth(date.lengthOfMonth());
      System.out.println(date.format(dateTimeFormatter));
    }
}

Вывод:

2020-05-31

Пример с Calendar:

 public class Testing {
      public static void main(String args[]) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calender = Calendar.getInstance();
        int months = 1;
        calender.add(Calendar.MONTH, months);
        calender.set(Calendar.DAY_OF_MONTH, calender.getActualMaximum(Calendar.DAY_OF_MONTH));
        String time = sdf.format(calender.getTime());
        System.out.println(time);
    }
}

Выход:

 2020-05-31
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...