将字符串转换为java.util.Date

37

我正在以如下格式将日期存储在SQLite数据库中:

d-MMM-yyyy,HH:mm:ss aaa

当我使用这种格式检索日期时,一切都很好,除了小时。小时总是00。下面是我的输出:

String date--->29-Apr-2010,13:00:14 PM
After convrting Date--->1272479414000--Thu Apr 29 00:00:14 GMT+05:30 2010

以下是代码:

    Date lScheduledDate = CalendarObj.getTime();
    DateFormat formatter = new SimpleDateFormat("d-MMM-yyyy,HH:mm:ss aaa");
    SomeClassObj.setTime(formatter.format(lScheduledDate));

    String lNextDate = SomeClassObj.getTime();
    DateFormat lFormatter = new SimpleDateFormat("d-MMM-yyyy,HH:mm:ss aaa");
    Date lNextDate = (Date)lFormatter.parse(lNextDate);
    System.out.println("output here"+lNextDate);

我做错了什么?


3
好的,问题已解决。在格式中AM/PM字母"aaa"的问题是,由于我使用的是'HH',因此不应使用'aaa',如果您使用'aaa',则需指定为'hh'。 - Vinayak Bevinakatti
2
虽然在2010年,我们都使用java.util.Date类(以及DateFormatCalendar), 但是对于任何在2017年或之后出现的人来说,这些类现在已经过时了。今天,人们会使用java.time包中的类,例如LocalDateTimeDateTimeFormatter。有许多Stack Overflow上的答案可以向您展示如何使用它们。去搜索吧。 - Ole V.V.
4个回答

65

我认为你的日期格式不合理。没有13:00 PM这个时间。请删除你格式结尾处的"aaa"或将HH改成hh。

不过,对我来说,以下格式是可以正常工作的:

String testDate = "29-Apr-2010,13:00:14 PM";
DateFormat formatter = new SimpleDateFormat("d-MMM-yyyy,HH:mm:ss aaa");
Date date = formatter.parse(testDate);
System.out.println(date);

它会输出 "Thu Apr 29 13:00:14 CEST 2010"。


5

不相关,但DateFormat对象不是线程安全的,它们不应该被声明为静态的,因为这样更有可能在某些时候从不同的线程访问它们。 - Guillaume

2

您应该在DateFormat中设置一个时区,否则它将使用默认时区(取决于计算机的设置)。


我已经按字母z的格式指定了时区,问题仍然存在。 - Vinayak Bevinakatti
你的日期字符串没有时区信息,所以 z 字母并不能帮助你,而是应该在 SimpleDateFormat 对象上使用 setTimeZone(...) 方法。 - Guillaume

0

java.time

虽然在2010年,我们都使用java.util.Date类(以及DateFormatCalendar), 但是这些类一直设计得很差,现在已经过时了。今天,人们会使用Java的现代日期和时间API - java.time。

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MMM-yyyy,HH:mm:ss");

        String dateTimeStringFromSqlite = "29-Apr-2010,13:00:14";
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStringFromSqlite, formatter);
        System.out.println("output here: " + dateTime);

输出为:

这里是输出:2010-04-29T13:00:14

你的代码哪里出了问题?

在你的格式化字符串中,大写的 HHaaa 的组合并没有太多意义,因为 HH 表示的是一天中的小时数,而 aaa 则是表示上午或下午,二者的组合似乎有点多余。不过,这样做应该不会有什么问题,我也无法复现你所报告的精确结果。总之,不论使用老式的 SimpleDateFormat 还是现代的 DateTimeFormatter,你的评论都非常到位:

如果你使用 'aaa',则不应该再使用 'hh'

小写的 hh 表示的是上午或下午的小时数,范围是 01 至 12,因此需要指定一个上午或下午标记。

其他提示

  • 在你的数据库中,由于我了解到SQLite没有内置的datetime类型,请使用标准的ISO 8601格式并将时间存储在UTC中,例如2010-04-29T07:30:14Z(现代的Instant类解析和格式化这种字符串是默认的,即不需要任何显式的格式化器)。
  • 不要使用像GMT+05:30这样的偏移量来表示时区。优先选择真实的时区,例如Asia/Colombo、Asia/Kolkata或America/New_York。
  • 如果您想使用过时的DateFormat,它的parse方法返回一个Date,因此您不需要在Date lNextDate = (Date)lFormatter.parse(lNextDate);中进行转换。

问题:我可以在Android上使用java.time吗?

是的,在旧版和新版的Android设备上,java.time都可以很好地工作。它只需要至少Java 6

  • 在Java 8及更高版本以及新的Android设备(API级别26以上)中,现代API已经内置。
  • 在Java 6和7中,获取ThreeTen Backport,即现代类的后移版本(JSR 310的ThreeTen;请参见底部链接)。
  • 在(旧版)Android上使用ThreeTen Backport的Android版本。它被称为ThreeTenABP。并确保从org.threeten.bp导入日期和时间类及其子包。

链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接