Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

java - Convert date with ordinal numbers (11th, 22nd, etc.)

How to convert a date having the following format

September 22nd 2015, 10:39:42 am

to

09/22/2015 10:39:42

in Java 8?

My current code:

String value = "September 22nd 2015, 10:39:42 am";
String format = "dd/MM/yyyy HH:mm:ss"; 
SimpleDateFormat sdf = new SimpleDateFormat(format); 
try { 
  Date date = sdf.parse(value); 
  System.out.println(date); 
  System.out.println(sdf.format(date)); 
}
catch (ParseException ex) {
   ex.printStackTrace(); 
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The tricky part of the format is to handle ordinal numbers (like 22nd), i.e. handle the right suffix. There is not built-in pattern. For this, we have to build our own DateTimeFormatter with the help of DateTimeFormatterBuilder.

DateTimeFormatterBuilder has a method appendText(field, textLookup) whose goal is to look for the read text in the given map and replace it by the key associated to this value. This means we need to build a Map of all possibles days (1 to 31) with their corresponding suffix.

I took the conversion code from this answer.

We also need to make sure to parse the AM/PM identifier ignoring the case (by default, it looks for AM and PM in uppercase but yours are in lowercase). This is done by calling parseCaseInsensitive before appending the pattern for this.

private static final Map<Long, String> DAYS_LOOKUP =
        IntStream.rangeClosed(1, 31).boxed().collect(toMap(Long::valueOf, i -> getOrdinal(i)));

public static void main(String[] args) throws Exception {
    DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("MMMM")
                                .appendLiteral(" ")
                                .appendText(ChronoField.DAY_OF_MONTH, DAYS_LOOKUP)
                                .appendLiteral(" ")
                                .appendPattern("yyyy")
                                .appendLiteral(", ")
                                .appendPattern("hh")
                                .appendLiteral(":")
                                .appendPattern("mm")
                                .appendLiteral(":")
                                .appendPattern("ss")
                                .appendLiteral(" ")
                                .parseCaseInsensitive()
                                .appendPattern("a")
                                .toFormatter(Locale.ENGLISH);
    LocalDateTime dateTime = formatter.parse("September 22nd 2015, 10:39:42 am", LocalDateTime::from);
    String text = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss").format(dateTime);
    System.out.println(text);
}

private static String getOrdinal(int n) {
    if (n >= 11 && n <= 13) {
        return n + "th";
    }
    switch (n % 10) {
        case 1:  return n + "st";
        case 2:  return n + "nd";
        case 3:  return n + "rd";
        default: return n + "th";
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...