4

我想将 MM-dd 格式的字符串解析为 java 日期。由于未指定年份,因此解析日期应为当年。应该只解析有效的日期字符串,所以我应该使用setLenient(false)in SimpleDateFormat

public static Date parseDate(String ds) throws ParseException {
    SimpleDateFormat df = new SimpleDateFormat("MM-dd");
    df.setLenient(false);
    Date d = df.parse(ds);
    Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    cal.setTime(d);
    cal.set(Calendar.YEAR, year);
    return cal.getTime();
}

在我通过参数“02-29”之前,这似乎很有效。今年(2012)是闰年,2012-02-29是有效日期,“02-29”应该已经解析成功了。

我发现当我不指定年份部分时SimpleDateFormat,它会解析为 1970 年。而 1970 年不是闰年,“02-29”无法解析。因此,解析到 1970 年的日期并在解析策略后设置当前年份并不完美。

在 Java 中解析 MM-dd 格式字符串到日期(日期应设置为当前年份)的最佳方法是什么?

PS1:我搜索了这个话题,在本站找到了很多问题和答案,但都没有找到满意的答案。PS2:df.setLenient(false);很重要,因为只有有效的日期字符串才能成功解析。不应解析“01-32”、“02-30”等无效日期字符串。

提前致谢。

4

4 回答 4

4

这可能被认为有点 hacky,但您总是可以在解析之前将年份添加到日期字符串的末尾,如下所示:

ds += "-" + Calendar.getInstance().get(Calendar.YEAR);
SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy");
// Parse date as usual
于 2012-07-15T16:32:43.913 回答
4
于 2019-10-30T23:13:30.170 回答
2

像在代码中一样从日历中获取年份,将解析格式字符串设置为MM-dd-yyyy,然后执行

 Date d = df.parse(ds + "-" + year);
于 2012-07-15T16:33:14.577 回答
0

如果您知道您的字符串格式正确,那么关于附加当前年份的其他答案就足够了。

如果您需要处理未知格式的输入字符串(您不确定年份是否在字符串上),您可以首先尝试使用完整格式解析日期,然后使用覆盖的较短格式返回那一年。

public static Date parseDate(String ds) throws ParseException {
    SimpleDateFormat fullFormat = new SimpleDateFormat("MM-dd-yyyy");
    fullFormat.setLenient(false);
    try {
      return fullFormat.parse(ds);
    } catch (ParseException e) {}

    // Full format unsuccessful. Attempt short format.
    SimpleDateFormat shortFormat = new SimpleDateFormat("MM-dd");
    shortFormat.setLenient(false);
    Date d = shortFormat.parse(ds);
    Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    cal.setTime(d);
    cal.set(Calendar.YEAR, year);
    return cal.getTime();
}

奖励:如果您出于某种原因想要一个“包罗万象”的解析器,请定义一堆非宽松的日期格式并逐个检查它们。请注意,顺序很重要;第一个匹配的将返回。如果要设置默认年份,则必须更进一步,检查输入中是否以某种方式引用了默认的 1970 年:

public static Date parseDate(String ds) throws ParseException {
  Calendar cal = Calendar.getInstance();
  int currentYear = cal.get(Calendar.YEAR);

  for (DateFormat knownFormat : knownFormats) {
    try {
      Date d = knownFormat.parse(ds);
      cal.setTime(d);

      if (cal.get(Calendar.YEAR) == 1970 && !ds.contains("70")) {
        cal.set(Calendar.YEAR, currentYear);
      }

      return cal.getTime();
    } catch (ParseException e) {}
  }

  throw new ParseException("Unknown date format for String: " + ds);
}
于 2019-10-30T21:26:48.797 回答