3

I need to print a DateTime in the form of, for example, Wednesday, January 9th, where the day of month automatically gets the proper suffix, e.g. January 2 would be January 2nd. How can I get a DateTimeFormatter that does this?

LuxuryMode
  • 33,401
  • 34
  • 117
  • 188

3 Answers3

4

There is no support for this in Joda, but with some limitations, you can use the ICU library, since it includes localized rules for formatting ordinal numbers:

import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.text.SimpleDateFormat;

...

SimpleDateFormat sdf = 
    new SimpleDateFormat("EEEE, MMMM d", Locale.ENGLISH);

sdf.setNumberFormat(
    new RuleBasedNumberFormat(
        Locale.ENGLISH, RuleBasedNumberFormat.ORDINAL));

System.out.println(sdf.format(new Date()));

Note that you can only specify one NumberFormat instance for the SimpleDateFormat instance, so that this approach only works if the "day of month" is the only number in the date pattern. Adding "yyyy" to the date pattern will e.g. format the year as "2,013th".

The ICU classes interface with the Date and Calendar classes from the standard API, so if you really have to use Joda in the first place, you would have to create a java.util.Date from your Joda DateTime instance.

jarnbjo
  • 33,923
  • 7
  • 70
  • 94
  • Nice answer. I'm actually gonna just implement the logic myself though since I happen to only need the day of month formatted. – LuxuryMode Jan 09 '13 at 16:17
  • 1
    Yes, I should perhaps have added that if you don't need any other ICU functionality, it is probably better to write a few lines of code to do this yourself instead of adding the 9MB ICU library :) – jarnbjo Jan 09 '13 at 16:25
1

In Joda, for simply getting the proper suffix for the day of month, something as simple as the following should be sufficient:

        String dayOfMonth = now.dayOfMonth().getAsText();

        String suffix = "";
        if(dayOfMonth.endsWith("1")) suffix = "st";
        if(dayOfMonth.endsWith("2")) suffix = "nd";
        if(dayOfMonth.endsWith("3")) suffix= "rd";
        if(dayOfMonth.endsWith("0") || dayOfMonth.endsWith("4") || dayOfMonth.endsWith("5") || dayOfMonth.endsWith("6")
                || dayOfMonth.endsWith("7") || dayOfMonth.endsWith("8") || dayOfMonth.endsWith("9")) suffix = "th";
LuxuryMode
  • 33,401
  • 34
  • 117
  • 188
  • That would not work for the 10th, 11th, 12th, 13th, 20th and 30th. – jarnbjo Jan 09 '13 at 16:51
  • If you just want a simple java method to add the suffixes without the missing links mentioned above, [this solution](https://stackoverflow.com/questions/6810336/is-there-a-way-in-java-to-convert-an-integer-to-its-ordinal) might be what you're looking for – Grant Jul 01 '17 at 17:16
0

I dont like the solution of using another library, so I solve this using a regular expression to preprocess the string and remove the ordinal suffix

val dateString1 = "6th December 2016"
dateString1.replaceFirst("^(\\d+).*? (\\w+ \\d+)", "$1 $2")
val dtf = DateTimeFormat.forPattern("dd MMMM yyyy").withLocale(Locale.ENGLISH)
val d1 = dtf.parseLocalDate(cured)

now d1 should be d1: org.joda.time.LocalDate = 2016-12-06

Benoit
  • 3,569
  • 2
  • 22
  • 20