1
private static final String LONG_DATE_PATTERN = "YYYY-MMM-dd hh:mm:ss a";
private static final SimpleDateFormat longDateFormat = new SimpleDateFormat(LONG_DATE_PATTERN);

    public static String formatWith12HourClock(Date date) {
        return longDateFormat.format(date);
    }

This will produce 2019-Dec-31 12:00:00 AM for date 2018-Dec-31 which is incorrect.

xingbin
  • 23,890
  • 7
  • 43
  • 79
  • 2
    Can you show how you got the input date? – Henry Dec 31 '18 at 06:01
  • Hope this will be helpful: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html – dkb Dec 31 '18 at 06:11
  • You should never have a static `SimpleDateFormat` instance as it is not thread-safe. See https://stackoverflow.com/questions/4021151/java-dateformat-is-not-threadsafe-what-does-this-leads-to – lance-java Dec 31 '18 at 06:59
  • I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated, it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Dec 31 '18 at 07:39

5 Answers5

3

As said in other answers, you should use yyyy instead of YYYY. If you are woking with java8 or higher, you can also use DateTimeFormatterBuilder to avoid the raw pattern, for example:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(ChronoField.YEAR_OF_ERA, 4, 19, SignStyle.EXCEEDS_PAD)
        .appendLiteral("-")
        .appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
        .appendLiteral("-")
        .appendValue(ChronoField.DAY_OF_MONTH, 2)
        .appendLiteral(" ")
        .appendValue(ChronoField.CLOCK_HOUR_OF_AMPM, 2)
        .appendLiteral(":")
        .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
        .appendLiteral(":")
        .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
        .appendLiteral(" ")
        .appendText(ChronoField.AMPM_OF_DAY, TextStyle.SHORT)
        .toFormatter();

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(formatter.format(localDateTime));
xingbin
  • 23,890
  • 7
  • 43
  • 79
2

Change YYYY to yyyy for correct output. You are getting 2019 as capital 'Y' is Week year. Ref: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html Date and Time Patterns

DEVENDRA
  • 174
  • 1
  • 11
1

Change Your Format Pattern to yyyy-MM-dd to Obtain 2018-12-31

private static final String LONG_DATE_PATTERN = "yyyy-MM-dd";
private static final SimpleDateFormat longDateFormat = new SimpleDateFormat(LONG_DATE_PATTERN);

    public static String formatWith12HourClock(Date date) {
        return longDateFormat.format(date);
    } 
ThivankaW
  • 386
  • 4
  • 15
0

Here is what I have tried based on OP,

public class App {
private static final String LONG_DATE_PATTERN = "yyyy-MMM-dd hh:mm:ss a";
private static final String SHORT_DATE_PATTERN = "yyyy-MMM-dd";
    private static final SimpleDateFormat longDateFormat = new SimpleDateFormat(LONG_DATE_PATTERN);
    private static final SimpleDateFormat shortDateFormat = new SimpleDateFormat(SHORT_DATE_PATTERN);

 public static void main(String[] args) throws Exception {
        Calendar cal = Calendar.getInstance();
        //Input date 2018-Dec-31 12:00:00 AM
        cal.set(2018, 11, 31, 0, 0, 0);

        Date date = cal.getTime();

        System.out.println(longDateFormat.format(date));
        System.out.println(shortDateFormat.format(date));
}
}

output:

2018-Dec-31 12:00:00 AM

2018-Dec-31

There was an issue with your simple date format

  • y --> Year
  • Y --> Week year

You should Change YYYY with yyyy in Date Pattern.

Ref: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

dkb
  • 3,238
  • 3
  • 26
  • 41
0

Use yyyy instead of YYYY since YYYY converts in comparison to weeks in SimpleDateFormat. An average year is exactly 52.1775 weeks long, which means that eventually a year might have either 52 or 53 weeks considering indivisible weeks.
Don't use YYYY in your date format template