Simpledateformat 不可解析的日期

新手上路,请多包涵

我在数据库( match.getDate )中有一个 String --- 具有以下日期格式:

2018-01-04

这是我要格式化的日期,存储为日/月/年。我想为我的 Android 应用程序格式化它。

我想将日期格式化为:

2018 年 4 月 1 日,星期日

我的代码如下:

 SimpleDateFormat fDate = new SimpleDateFormat("dd/MM/yyyy");
try {
    textViewDate.setText(fDate.parse(match.getDate()).toString());
} catch (ParseException ex) {
    System.out.println(ex.toString());
}

这输出:

2018 年 4 月 8 日星期日 00:00:00 GMT+00:00。

我也试过 "EE, MM d, yyyy" ,但它给了我:

java.text.ParseException:无法解析的日期:“01/04/2018”

原文由 Carl Bruiners 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 442
2 个回答

使用我创建的这个日期格式化程序方法

    public static String dateFormater(String dateFromJSON, String expectedFormat, String oldFormat) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(oldFormat);
    Date date = null;
    String convertedDate = null;
    try {
        date = dateFormat.parse(dateFromJSON);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(expectedFormat);
        convertedDate = simpleDateFormat.format(date);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return convertedDate;
}

并像这样调用此方法

dateFormater(" 01/04/2018" , "EE dd MMM yyyy" , "dd/MM/yyyy")

你会得到想要的输出

原文由 Harsh Patel 发布,翻译遵循 CC BY-SA 3.0 许可协议

其他答案解决了您的问题,但我认为了解一些概念以及您第一次尝试失败的原因很重要。

日期表示日期的文本 之间存在差异。

示例:今天的日期是 2018 年 3 月 9 日。那个日期只是一个概念,一个“我们日历系统中的特定点”的想法。

不过,同一日期可以用多种格式 表示。它可以是“图形化的”,形式是一张纸上的一个数字周围有一个圆圈,并以某种特定顺序包含许多其他数字,或者它可以是 纯文本,例如:

  • 09/03/2018(日/月/年)
  • 03/09/2018(月/日/年)
  • 2018-03-09( ISO8601格式
  • 2018 年 3 月 9日
  • 2018 年 3 月 9 日(葡萄牙语)
  • 2018年3月5日(日文)
  • 等等…

请注意,文本表示形式不同,但它们都表示相同的日期(相同的值)。

考虑到这一点,让我们看看 Java 如何使用这些概念。

  • 文本由 String 表示。这个类只包含一个字符序列,仅此而已。这些字符可以代表任何东西;在这种情况下,这是一个日期
  • 日期最初由 java.util.Date 表示,然后由 java.util.Calendar ,但 这些类充满了问题,你应该尽可能避免它们。 今天我们有一个更好的 API

在 Android 中,您可以使用 java.time 类(如果在您正在使用的 API 级别中可用),或者为低于该级别的 API 级别使用 threeten backport在此处查看如何使用它)。您将拥有更简单、更可靠的工具来处理日期。

在您的情况下,您有一个 String (代表日期的文本)并且您想要将其转换为另一种格式。您必须分两步完成:

  1. String 转换为某种日期类型(将文本转换为数字日/月/年值)——这称为 解析
  2. convert this date-type value to some format(将数值转换为特定格式的文本)——这称为 格式化

为什么你的尝试没有奏效:

  • 第一次尝试给了你错误的格式,因为你调用了 Date::toString() 方法,它产生了该格式的输出(文本表示)( Sun Apr 08 00:00:00 GMT+00:00 2018 ) - 所以解析是正确的,但是格式化不是
  • 在第二次尝试中,您使用了输出模式( EE dd MMM yyyy ,您应该用于格式化的模式)来解析日期(这导致了 ParseException )。

对于第 1 步,您可以使用 LocalDate ,一种表示日期的类型(日、月和年,没有小时和时区),因为这就是您的输入:

 String input = "01/04/2018";
DateTimeFormatter inputParser = DateTimeFormatter.ofPattern("dd/MM/yyyy");
// parse the input
LocalDate date = LocalDate.parse(input, inputParser);

这比 SimpleDateFormat 更可靠,因为它解决 了许多旧 API 的奇怪错误和问题

现在我们有了 LocalDate 对象,我们可以执行第 2 步:

 // convert to another format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EE dd MMM yyyy", Locale.ENGLISH);
String output = date.format(formatter);

请注意,我使用了 java.util.Locale 。那是因为你想要的输出有英文的星期几和月份名称,如果你没有指定语言环境,它将使用 JVM 的默认值(谁保证它总是英文?最好告诉API 您正在使用的语言而不是依赖于默认配置,因为这些可以随时更改,甚至可以由在同一 JVM 中运行的其他应用程序更改)。

我怎么知道 DateTimeFormatter 中必须使用哪些字母?好吧,我刚刚阅读了 javadoc

原文由 shind 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题