-1

Is there any specific format in date API which can print st, nd, rd, and th after a specific date. Say Dec 26 should be as Dec 26th.

Also any specific format for the time like 10.30 a.m. The format should be exactly the same.

Require only inbuilt pattern for solving this.

I have written below codes for the scenarios but not getting any desired output

    //Checking date format
    String pattern = "EEE, MMM.dd";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    String date = simpleDateFormat.format(new Date());
    System.out.println(date);

    //checking time format

    DateFormat dateFormat2 = new SimpleDateFormat("hh.mm aa.");
    String dateString2 = dateFormat2.format(new Date()).toString();
    System.out.println(dateString2);
Tanveer Munir
  • 1,956
  • 1
  • 12
  • 27
Sudipto Das
  • 151
  • 1
  • 2
  • 14
  • 1
    See [this question](https://stackoverflow.com/questions/4011075/how-do-you-format-the-day-of-the-month-to-say-11th-21st-or-23rd-ordinal/4011232) for your first issue. I don't understand what you're asking in regard to AM/PM – Joakim Danielson Mar 12 '19 at 09:35
  • 1
    While we're at the subject – you shouldn't use the `SimpleDateFormat`, `Date` and `Calendar` classes. Use the classes from the `java.time` package. [The old ones have some issues](https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api). – MC Emperor Mar 12 '19 at 09:36
  • @JoakimDanielson the time should display as 10.30 a.m. not 10.30 AM. Is there any inbuilt pattern to solve this. I am not asking through code manipulation. – Sudipto Das Mar 12 '19 at 09:39
  • You should really ask one question at a time but the answers are, No there is no built in support for st,rd,th and No there is no built in support for custom variants of AM/PM – Joakim Danielson Mar 12 '19 at 09:44
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` , `LocalTime` and `DateTimeFormatter`, all from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Mar 12 '19 at 14:08
  • `DateTimeFormatter` (and `SimpleDateFormat`) format AM/PM according to a locale. So if your locale uses `a.m.` and `p.m.`, just specify that locale, for example `DateTimeFormatter.ofPattern("hh.mm a.", Locale.forLanguageTag("es-US"))`. – Ole V.V. Mar 12 '19 at 14:12

3 Answers3

2

No, there is no such format. As you can see in the documentation, the date and time patterns of SimpleDateFormat don't provide things like 26th.

1

Solution for the first problem:

SimpleDateFormat format = new SimpleDateFormat("d");
String date = format.format(new Date());

if(date.endsWith("1") && !date.endsWith("11"))
    format = new SimpleDateFormat("EE MMM d'st', yyyy");
else if(date.endsWith("2") && !date.endsWith("12"))
    format = new SimpleDateFormat("EE MMM d'nd', yyyy");
else if(date.endsWith("3") && !date.endsWith("13"))
    format = new SimpleDateFormat("EE MMM d'rd', yyyy");
else 
    format = new SimpleDateFormat("EE MMM d'th', yyyy");

String yourDate = format.format(new Date());

Solution for second problem:

public static String getTimeFromHours(long time) {
    int min = (int) (time / 60);
    int hours = min / 60;
    int remaining_min = min % 60;

    if (hours > 12) {
        return String.format(Locale.ENGLISH, "%02d:%02d %s", hours - 12, remaining_min, "PM");
    } else if (hours < 12) {
        return String.format(Locale.ENGLISH, "%02d:%02d %s", hours, remaining_min, "AM");
    } else {
        return String.format(Locale.ENGLISH, "%02d:%02d %s", hours, remaining_min, "PM");
    }
}

Try this, it should work fine for you.

TiiJ7
  • 3,332
  • 5
  • 25
  • 37
Richa Shah
  • 930
  • 3
  • 12
  • 27
1

I would recommend to use java.time. You can build a custom formater using DateTimeFormatterBuilder() by passing a custom map to the appendText() method.

Example for am/pm for LocalTime:

    LocalTime localTime = LocalTime.now();        

    Map<Long, String> map = new HashMap<>();
    map.put(0L, "a.m");
    map.put(1L, "p.m");

    DateTimeFormatter aMpM_formatter = new DateTimeFormatterBuilder()
        .appendPattern("hh:mm:ss ")
        .appendText(ChronoField.AMPM_OF_DAY, map)   // without your custom map 0 is mapped to AM and 1 is mapped to PM
        .toFormatter();

    System.out.println(localTime.format(aMpM_formatter));

Example for LocalDate with ordinal suffixes:

    LocalDate localDate = LocalDate.now();
    Map<Long, String> daysWithSuffix = new HashMap<>(); // map values
    daysWithSuffix.put(1L,  "1st");
    daysWithSuffix.put(2L,  "2nd");
    daysWithSuffix.put(3L,  "3rd");
    daysWithSuffix.put(21L, "21st");
    daysWithSuffix.put(22L, "22nd");
    daysWithSuffix.put(23L, "23rd");
    daysWithSuffix.put(31L, "31st");
    for (long d = 1; d <= 31; d++) {
        daysWithSuffix.putIfAbsent(d, d + "th");
    }

    DateTimeFormatter thFormatter = new DateTimeFormatterBuilder()
            .appendPattern("EEE, MMM ") 
            .appendText(ChronoField.DAY_OF_MONTH, daysWithSuffix)   // mapped values from your custom map              
            .toFormatter();

    System.out.println(localDate.format(thFormatter));
    System.out.println(LocalDate.of(2019, Month.MARCH, 1).format(thFormatter));
    System.out.println(LocalDate.of(2019, Month.MARCH, 23).format(thFormatter));

Example for LocalDateTime with ordinal suffixes for date and customized am/pm:

    DateTimeFormatter both  = new DateTimeFormatterBuilder()
            .appendPattern("EEE, MMM ") 
            .appendText(ChronoField.DAY_OF_MONTH, daysWithSuffix)
            .appendLiteral(" ")
            .appendPattern("hh:mm:ss ")
            .appendText(ChronoField.AMPM_OF_DAY, map)
            .toFormatter();

    System.out.println(LocalDateTime.now().format(both));
Eritrean
  • 15,851
  • 3
  • 22
  • 28