转换日期与序数(第11,22等)

Sou*_*abh 3 java java-8 java-time

如何转换具有以下格式的日期

2015年9月22日上午10:39:42

09/22/2015 10:39:42

在Java 8中?

我目前的代码:

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(); 
}
Run Code Online (Sandbox Code Playgroud)

Tun*_*aki 8

格式的棘手部分是处理序数(例如22nd),即处理正确的后缀.没有内置模式.为此,我们必须DateTimeFormatter在帮助下建立自己的DateTimeFormatterBuilder.

DateTimeFormatterBuilder有一个方法,appendText(field, textLookup)其目标是在给定的映射中查找读取文本,并将其替换为与此值关联的键.这意味着我们需要使用相应的后缀构建所有可能日期(1到31)的Map.

我从这个答案中获取了转换代码.

我们还需要确保解析忽略大小写的AM/PM标识符(默认情况下,它以大写形式查找AM和PM,但是您的大小写为小写).这是通过parseCaseInsensitive在为此附加模式之前调用来完成的.

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";
    }
}
Run Code Online (Sandbox Code Playgroud)