2015-01-27 2 views
6

Где функция, чтобы получить последний день месяца в моем сервисе?Неправильный последний день месяца

DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); 
     Date date = format.parse(stringDate); 
     Calendar calendar = Calendar.getInstance(); 
     calendar.setTime(date); 

     calendar.add(Calendar.MONTH, 1); 
     calendar.set(Calendar.DAY_OF_MONTH, 1); 
     calendar.add(Calendar.DATE, -1); 

     Date lastDayOfMonth = calendar.getTime(); 

     DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 

     return sdf.format(lastDayOfMonth); 

Таким образом, этот метод работает правильно в другом месте, но в США последний день всегда 29 (последний день - 1)

stringDate является дата в формате "гггг-ММ-дд"

+1

Что такое 'значение stringDate'? –

+2

Поскольку он начинается с 0, см. API. – Maroun

+0

@waldermar, вы предоставили нам ** формат ** 'stringDate', но ** не ** ** фактическое значение **' stringDate'. Предоставьте нам 2 или более фактических значения, которые подтвердят ваш вопрос, включая вашу дату в США (если вы получите мой вопрос). –

ответ

1

Java Дата имеет очень плохой API. Вместо этого я бы рекомендовал вам использовать Joda Time.

В Joda это будет выглядеть следующим образом:

LocalDate endOfMonth = date.dayOfMonth().withMaximumValue(); 
+2

не делайте этого, у Java 8 намного лучше Дата API – Mysterion

+0

Не намного лучше, но немного. PS Не каждому так повезло использовать Java 8;) – MAGx2

0

Если у вас нет Java 8, это очень компактный с JodaTime.

import org.joda.time.DateTime; 

public class SoLastDay { 
    public DateTime lastDay(final String yyyy_MM_dd) { 
     DateTime givenDate = new DateTime(yyyy_MM_dd); 
     return givenDate.dayOfMonth().withMaximumValue(); 
    } 
} 

И небольшой тест ...

@Test 
public void testLastDay() throws Exception { 
    SoLastDay soLastDay = new SoLastDay(); 

    String date1 = "2015-01-27"; 
    System.out.printf("Date %s becomes %s.\n", date1, soLastDay.lastDay(date1).toString("yyyy-MM-dd")); 

    String date2 = "2015-02-02"; 
    System.out.printf("Date %s becomes %s.\n", date2, soLastDay.lastDay(date2).toString("yyyy-MM-dd")); 

} 

И результаты испытаний:

Date 2015-01-27 becomes 2015-01-31. 
Date 2015-02-02 becomes 2015-02-28. 
0

Если вы сделать есть Java 8, можно использовать такой код:

import java.time.LocalDate; 
import java.time.format.DateTimeFormatter; 
import java.time.temporal.TemporalAdjusters; 

public class SoLastDayJava8 { 
    static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 

    public LocalDate lastDay(final String yyyy_MM_dd) { 
     LocalDate givenDate = LocalDate.parse(yyyy_MM_dd, formatter); 
     return givenDate.with(TemporalAdjusters.lastDayOfMonth()); 
    } 
} 

Тестовый код изменяется немного.

public class SoLastDayJava8Test { 

    @Test 
    public void testLastDay() throws Exception { 
     SoLastDayJava8 soLastDay = new SoLastDayJava8(); 

     String date1 = "2015-01-27"; 
     System.out.printf("Date %s becomes %s.\n", date1, soLastDay.lastDay(date1)); 

     String date2 = "2015-02-02"; 
     System.out.printf("Date %s becomes %s.\n", date2, soLastDay.lastDay(date2)); 

    } 
} 

Но результаты одинаковы.

Дата 2015-01-27 становится 2015-01-31.

Дата 2015-02-02 - 2015-02-28.

0

Вы возитесь с TimeZones.

При выполнении Date date = format.parse(stringDate); вы создаете объект Date с TimeZone объекта DateFormat. Теоретически, если TimeZone одинаково для всех ваших объектов DateFormat и Calendar, все должно быть хорошо. Проверьте, соответствуют ли они методу getTimeZone().

Если TimeZone первого DateFormat неправильно (например, ваш TimeZone или UTC или GMT), вы получите UTC-008 преобразования во втором TimeZone (и в Calendar), в результате недостающий дня, так как вы начинаете с полночь.

Судя из вашего кода является stringDate сам, что было неправильно конвертированы где-то еще ...