Подтвердить что ты не робот

Как создать дату с одного месяца и года на Java?

Мне нужно создать новый объект Date для даты истечения срока действия кредитной карты, у меня есть только месяц и год, как я могу сгенерировать дату на основе этих двух? Мне нужен самый простой способ. Здесь я читал некоторые другие ответы, но все они кажутся слишком сложными.

4b9b3361

Ответ 1

Вы можете использовать java.util.Calendar:

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.YEAR, year);
Date date = calendar.getTime();

Ответ 2

java.time

Использование рамки java.time, встроенной в Java 8

import java.time.YearMonth;

int year = 2015;
int month = 12;
YearMonth.of(year,month); // 2015-12

from String

YearMonth.parse("2015-12"); // 2015-12

с пользовательским DateTimeFormatter

import java.time.format.DateTimeFormatter;

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM yyyy");
YearMonth.parse("12 2015", formatter); // 2015-12

Конверсия Чтобы преобразовать YearMonth в более стандартное представление даты, которое равно LocalDate.

LocalDate startMonth = date.atDay(1); //2015-12-01
LocalDate endMonth = date.atEndOfMonth(); //2015-12-31

Ответ 3

Возможно, это не ответ, так как вы попросили java.util.Date, но, похоже, хорошая возможность указать, что большая часть работы с датами и временем и календарями в Java, вероятно, должна быть выполнена с помощью Joda-Time, и в этом случае

new LocalDate(year, month, 1)

приходит в голову.

Joda-Time имеет ряд других приятных вещей в отношении дней месяца. Например, если вы хотите узнать первый день текущего месяца, вы можете написать

LocalDate firstOfThisMonth = new LocalDate().withDayOfMonth(1);

В своем комментарии вы спрашиваете о передаче строки в конструктор java.util.Date, например:

new Date("2012-09-19")

Эта версия конструктора устарела, поэтому не используйте ее. Вы должны создать форматировщик даты и вызвать parse. Это хороший совет, потому что у вас, вероятно, будут year и month как целочисленные значения, и вам нужно будет создать хорошую строку, правильно дополненную и ограниченную, и все это, что невероятно сложно добиться во всех случаях. По этой причине используйте формат даты, который знает, как правильно позаботиться обо всех этих вещах.

Другие более ранние ответы показали, как это сделать.

Ответ 5

Наиболее распространенный подход - использовать конструктор Date ( "YYYY-MM-DD" ), даже если он устарел. Это самый простой способ создать дату на лету. Вверните кого-нибудь, кто решил это осудить. Да здравствует дата ( "ГГГГ-ММ-ДД" )!!!

Ответ 6

Не используйте этот ответ. Используйте ответы Przemek и Ray Toel. Как говорит Прземек, предпочитайте использовать YearMonth для представления года и месяца. Как говорят, если вы должны использовать дату, используйте LocalDate, ее дату без времени суток.

Если вам абсолютно необходим старомодный объект java.util.Date для устаревшего API, который вы не можете изменить, это простой способ его получить. Он может работать не так, как хотелось бы, он может не дать вам точно дату, которая вам нужна, это зависит от ваших точных требований.

    YearMonth expiration = YearMonth.of(2021, 8); // or .of(2021, Month.AUGUST);
    Date oldFashionedDateObject = Date.from(expiration
            .atDay(1)
            .atStartOfDay(ZoneId.systemDefault())
            .toInstant());
    System.out.println(oldFashionedDateObject);

На моем компьютере это печатает

Sun Aug 01 00:00:00 CEST 2021

То, что мы получили, - это первый месяц в полночь в моем местном часовом поясе - точнее, настройка часового пояса JVM. Это одно хорошее предположение о том, что ожидает ваш устаревший API, но это также опасно. Настройка часового пояса JVM может быть изменена под ногами другими частями программы или другими программами, запущенными в одной JVM. Другими словами, мы не можем быть уверены в том, что получим.

Проблема с часовым поясом становится еще хуже, если дата передается на компьютер, работающий в другом часовом поясе, например, от клиента к серверу или наоборот, или к базе данных, работающей в своем часовом поясе. Theres около 50% риска, что ваш Date будет проходить как время в предыдущем месяце.

Если вам известен часовой пояс, необходимый в конце, это поможет указать, например, ZoneId.of("America/New_York") вместо системного значения по умолчанию в приведенном выше фрагменте.

Если ваш API является снисходительным и ему просто нужен какой-то момент в течение правильного месяца, вам будет лучше дать ему 2-й месяц UTC или 3-го месяца в вашем часовом поясе. Вот как это сделать:

    Date oldFashionedDateObject = Date.from(expiration
            .atDay(2)
            .atStartOfDay(ZoneOffset.UTC)
            .toInstant());