java.time
java.time рамки встроены в Java 8 и более поздних версий. Большая часть этой функциональности была перенесена на Java 6 & 7 и на Android.
Я предоставляю некоторые фрагменты кода примера здесь, но untested - никогда не запускать. Должен заставить вас идти в правильном направлении.
Два сложных частей к этой проблеме:
- Год
Вопрос говорит назначить год. Это не относится к дате остановки в январе с датой начала, которая, как оказалось, находится в предыдущем месяце, декабре. Вы хотите, чтобы предыдущий год был в таком случае. Решение состоит в том, чтобы позволить java.time вычитать месяц и обрабатывать математику Jan-to-Dec для вас.
- Длина месяца
Различные месяцы имеют разную длину, разное количество дней, очевидно. Имейте в виду, что вы не можете попытаться установить день месяца 31
по апрель. Если ваши входные данные всегда чисты и действительны, а наш алгоритм ниже, это должно быть не проблема. Тем не менее, я бы, конечно, добавил код исключения для моего кода примера ниже, чтобы уловить любую попытку создать недопустимую дату.
Я пропущу часть, разделяющую струны, и предположим, что у вас есть номер (день месяца) из первой части и строка даты со второй части.
long dayOfMonth = Long.longValue("31");
Эта дата не в standard format, поэтому мы должны указать formatting pattern. A LocalDate
представляет собой значение даты только без времени и без часового пояса.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
LocalDate stop = LocalDate.parse("21.05.2016" , formatter);
Мы можем извлечь день-месяц для сравнения.
LocalDate start = null;
int d = localDate.getDayOfMonth();
Проведите сравнение.
if(dayOfMonth >=d) { // If start is in previous month…
start = stop.minusMonths(1).withDayOfMonth(dayOfMonth);
} else if (dayOfMonth < d) { // If start is in same month…
start = stop.withDayOfMonth(dayOfMonth);
} else {
// FIXME: handle impossible condition as error. The 'if' statements are flawed.
}
Кстати, формат данных ввода неудобен и, откровенно говоря, глупым. Этот вид драгоценного «умения» создает дополнительную работу, дает возможность для путаницы и ошибок, совершенно бесполезен, не принося никакой пользы, и сводит меня с ума. Если у вас есть контроль над этими входными данными, я настоятельно рекомендую одно из двух возможных изменений.
Во-первых, если вы обмениваетесь данными в своем приложении, не используйте строки. Использовать объекты. Вы уже видели объект LocalDate
. Вы могли бы пройти мимо них. Или даже определите свой собственный класс LocalDateRange
для размещения пары объектов LocalDate
. Или см. this Question и особенно this Answer, который рассказывает об использовании класса Google GuavaRange
для хранения пары объектов LocalDate
.
Во-вторых, когда вы должны сериализовать значения даты и времени для строк, используйте стандартные форматы ISO 8601. Такое использование просто, поскольку классы java.time по умолчанию используют эти форматы при разборе/генерации строк. Значение даты только должно быть в порядке YYYY-MM-DD. A date range interval - это пара этих строк, связанных с косой чертой (SOLIDUS) или, альтернативно, пара дефисов, когда косая черта не подходит (например, имя файла или папки в файловой системе, связанной с Unix).
Возможный дубликат [Java строки для преобразования даты] (http://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – Learner
@DROY Нет, не дубликатом этого. Этот вопрос касается диапазона дат, а не одной даты. Кроме того, этот вопрос добавляет проблему определения того, является ли начальная дата (дается только как таинственный день месяца) в том же месяце, что и дата остановки или в предыдущем месяце. –
Это другой вопрос. Я знаю, как я могу обработать преобразование String to date, которое, я надеюсь, доказал, что на самом деле придумал псевдокод, который может решить проблему. Что я искал, есть ли какой-либо класс, например Interval, который примет формат, такой как dd. - dd.MM.yyyy и предоставит дату и дату. –