日期格式更改

Date format changing

如果输入为 01-01-2015,则应更改为 2015-01-01
如果输入是 2015-01-01 它应该更改为 01-01-2015.
我使用了 SimpleDateFormat 但没有得到正确的输出:

//Class to change date dd-MM-yyyy to yyyy-MM-dd and vice versa
public class ChangeDate {
  static SimpleDateFormat formatY = new SimpleDateFormat("yyyy-MM-dd");
  static SimpleDateFormat formatD = new SimpleDateFormat("dd-MM-yyyy");

  //This function change dd-MM-yyyy to yyyy-MM-dd
  public static String changeDtoY(String date) {
    try {
      return formatY.format(formatD.parse(date));
    }
    catch(Exception e) {
      return null;
    }
  }

  //This function change yyyy-MM-dd to dd-MM-yyyy
  public static String changeYtoD(String date) {
    try {
      return formatD.format(formatY.parse(date));
    }
    catch(Exception e) {
      return null;
    }
  }
}

我想要一些自动检测日期模式并更改为其他格式的条件。

阅读 Pattern, Matcher 正则表达式

Java 代码(基于 OP):

if (date.matches("\d{2}-\d{2}-\d{4}")){
  //convert D format to Y format...
} else if(date.matches("\d{4}-\d{2}-\d{2}")){
  //convert Y to D...
} else {
  throw new IllegalArgumentException("Received date format is not recognized.");
}

注意:可以使用 capture groups 改进此匹配模式。
例如:"\d{4}(-\d{2}){2}""(-?\d{2}){2}\d{4}"

有2个选项:

  1. 尝试用正则表达式检查……喜欢:

    if (dateString.matches("\d{4}-\d{2}-\d{2}")) {
        ...
    }
    
  2. 尝试转换为第一种模式,如果抛出异常,尝试转换为另一种模式(但这样做是不好的做法)

只需比较第一个'-'字符在日期字符串中的位置。

正则表达式太过分了

对于日期时间工作,无需费心regex

只需尝试使用一种格式进行解析,捕获预期的异常。如果确实抛出异常,请尝试使用其他格式进行解析。如果抛出异常,那么您就知道输入意外地不是两种格式。

java.time

您正在使用旧的麻烦的日期时间 类,现在已被 java.time framework built into Java 8 and later. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Oracle Tutorial 取代。

LocalDate

新的 类 包括一个 LocalDate,用于没有时间的仅日期值。正是您所需要的。

格式化程序

您的第一个格式可能是标准 ISO 8601 格式,YYYY-MM-DD。在 java.time 中默认使用此格式。

如果第一次解析尝试失败,因为输入与 ISO 8601 格式不匹配,则会抛出 DateTimeParseException

LocalDate localDate = null;  
try {
    localDate = LocalDate.parse( input );  // ISO 8601 formatter used implicitly.
} catch ( DateTimeParseException e ) {
    // Exception means the input is not in ISO 8601 format.
}

其他格式必须由类似于您对 SimpleDateFormat 所做的编码模式指定。因此,如果我们从第一次尝试中捕获到异常,请进行第二次解析尝试。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy" );
LocalDate localDate = null;  
try {
    localDate = LocalDate.parse( input );
} catch ( DateTimeParseException e ) {
    // Exception means the input is not in ISO 8601 format.
    // Try the other expected format.
    try {
        localDate = LocalDate.parse( input , formatter );
    } catch ( DateTimeParseException e ) {
        // FIXME: Unexpected input fit neither of our expected patterns.
    }
}

参见:https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/datetime/iso/examples/StringConverter.java

非 ISO 日期转换 https://docs.oracle.com/javase/tutorial/datetime/iso/nonIso.html

添加一个新的年表来识别 ISO 日期是另一种兼容(防破解)的方法,可以输入日期数据并将其存储在正确的结构中(其他功能可以轻松地对数据进行操作)。参见:https://docs.oracle.com/javase/8/docs/api/java/time/chrono/Chronology.html

'regex method' 可以被错误的输入破坏,并且无法 return 一个标准错误来响应输入的任何内容(以在任何地方获得标准的相同结果)。

请参阅用户 "Tardate" 在此主题中提供的答案:How to sanity check a date in java .

您需要防弹输入并将其存储在正确识别的结构中,以便使用其他函数轻松地对其进行操作。