在 Java 中以不同的格式将字符串解析为日期

Posted

技术标签:

【中文标题】在 Java 中以不同的格式将字符串解析为日期【英文标题】:Parse String to Date with Different Format in Java 【发布时间】:2010-10-27 07:32:30 【问题描述】:

我想将String 转换成不同格式的Date

例如,

我从用户那里得到,

String fromDate = "19/05/2009"; // i.e. (dd/MM/yyyy) format

我想将此fromDate 转换为"yyyy-MM-dd" 格式的日期对象

我该怎么做?

【问题讨论】:

一个 Date 对象没有格式,它只是一个代表日期的数字。日期可以用字符串表示,格式为“yyyy-MM-dd”。 You can NOT create a formatted Date object 【参考方案1】:

看看SimpleDateFormat。代码是这样的:

SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

try 

    String reformattedStr = myFormat.format(fromUser.parse(inputString));
 catch (ParseException e) 
    e.printStackTrace();

【讨论】:

我可以得到Date格式而不是字符串格式的输出吗? @Rachel:当然,只需使用parse,不要继续使用formatparse 将字符串解析为日期。 但是parse 给了我date format 作为Fri Jan 06 00:01:00 EST 2012 但它需要2012-01-06 日期格式 @Rachel 这是因为当您调用System.out.println(anyDateObject) 时,会调用默认的 toString() 方法,据说该方法会以该格式打印,例如Fri Jan 06 00:01:00 EST 2012。您需要覆盖它以满足您的需求。 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 和 Java 中内置的 java.time 类所取代9. 见Tutorial by Oracle。【参考方案2】:

tl;博士

LocalDate.parse( 
    "19/05/2009" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) 
)

详情

java.util.Datejava.sql.DateSimpleDateFormat 的其他答案现已过时。

LocalDate

处理日期时间的现代方法是使用 java.time 类,特别是 LocalDateLocalDate 类表示没有时间和时区的仅日期值。

DateTimeFormatter

要解析或生成表示日期时间值的字符串,请使用DateTimeFormatter 类。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "19/05/2009" , f );

不要将日期时间对象与表示其值的字符串混为一谈。日期时间对象没有格式,而字符串有。日期时间对象,例如LocalDate,可以生成一个字符串来表示其内部值,但日期时间对象和字符串是不同的不同对象。

您可以指定任何自定义格式来生成字符串。或者让 java.time 做自动本地化的工作。

DateTimeFormatter f = 
    DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                     .withLocale( Locale.CANADA_FRENCH ) ;
String output = ld.format( f );

转储到控制台。

System.out.println( "ld: " + ld + " | output: " + output );

日期:2009-05-19 |输出:狂欢节 2009 年 5 月 19 日

See in action in IdeOne.com.


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

Java SE 8Java SE 9 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些小功能和修复。 Java SE 6Java SE 7 大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android 更高版本的 android 捆绑包实现 java.time 类。 对于早期的 Android (ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 和more。

【讨论】:

【参考方案3】:

使用SimpleDateFormat 类:

private Date parseDate(String date, String format) throws ParseException

    SimpleDateFormat formatter = new SimpleDateFormat(format);
    return formatter.parse(date);

用法:

Date date = parseDate("19/05/2009", "dd/MM/yyyy");

为了提高效率,您可能希望将格式化程序存储在哈希图中。 hashmap 是 util 类的静态成员。

private static Map<String, SimpleDateFormat> hashFormatters = new HashMap<String, SimpleDateFormat>();

public static Date parseDate(String date, String format) throws ParseException

    SimpleDateFormat formatter = hashFormatters.get(format);

    if (formatter == null)
    
        formatter = new SimpleDateFormat(format);
        hashFormatters.put(format, formatter);
    

    return formatter.parse(date);

【讨论】:

警告!!这个想法很好,但实施起来并不好。 DateFormat 不能静态存储,因为它们不是线程安全的!如果它们从多个线程中使用(这对于静态总是有风险的)。 FindBugs 包含一个检测器(我碰巧最初贡献了它,在我被咬后。见dschneller.blogspot.com/2007/04/… :-)) 您的博客文章读起来很有趣 :-) 如果我同步了 parseDate 方法本身会怎样?但问题是它可能会减慢代码速度...... 只要 parseDate 方法是访问地图的唯一方法,同步它就可以工作。但是,正如您所说,这会引入瓶颈。【参考方案4】:

将字符串日期转换为 java.sql.Date

String fromDate = "19/05/2009";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date dtt = df.parse(fromDate);
java.sql.Date ds = new java.sql.Date(dtt.getTime());
System.out.println(ds);//Mon Jul 05 00:00:00 IST 2010

【讨论】:

【参考方案5】:

查看 java.text.SimpleDateFormat 的 javadocs,它描述了您需要的一切。

【讨论】:

【参考方案6】:

虽然SimpleDateFormat 确实可以满足您的需求,但您可能还想查看Joda Time,这显然是Java 7 中重做日期库的基础。虽然我没有经常使用它,但我只听说过它的好消息,如果您在项目中广泛操纵日期,那可能值得研究。

【讨论】:

【参考方案7】:

假设你有一个这样的字符串:

String mDate="2019-09-17T10:56:07.827088"

现在我们要在 JavaKotlin 中更改这种 String 格式的单独日期和时间。

JAVA:

我们有一个提取日期的方法:

public String getDate() 
    try 
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mDate);
        dateFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
        return dateFormat.format(date);
     catch (ParseException e) 
        e.printStackTrace();
    
    return null;

Return 是这个:09/17/2019

我们有提取时间的方法:

public String getTime() 

    try 
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mCreatedAt);
        dateFormat = new SimpleDateFormat("h:mm a", Locale.US);
        return dateFormat.format(date);
     catch (ParseException e) 
        e.printStackTrace();
    
    return null;

Return 是这个: 上午 10:56

科特林:

我们有一个提取日期的功能:

fun getDate(): String? 

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val date = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US)
    return dateFormat.format(date!!)

Return 是:09/17/2019

我们有提取时间的方法:

fun getTime(): String 

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val time = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("h:mm a", Locale.US)
    return dateFormat.format(time!!)

Return 是这个: 上午 10:56

【讨论】:

请不要教年轻人使用早已过时且臭名昭著的麻烦SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中有很多更好的东西。 SimpleDateFormat 也无法正确解析秒(微秒)的 6 位小数。 当我运行你的第二个 sn-p 时,我没有像你说的那样得到 10:56 AM,而是得到 11:09 AM(在 Oracle jdk-11.0.3 上测试)。 @OleV.V. , 如果一个方法已经过时了,它会被弃用,并在上面用一条线​​作为标志,如果一个方法或类没有被弃用,我们可以使用它,我不是说这是最好的方法,也许我们有更好的方法但是这样简单易懂,如果一个方法或类是旧的,没有理由麻烦,使用DateTimeFormatter我们需要minsdk 26或更高,那就不好了 @OleV.V.但是感谢您的评论以及您的第二条评论,我可以说我在两个应用程序中多次检查它并返回10:56 AM @OleV.V. ,好的,但是当我没有办法或者API(库)比我的代码非常好时,我使用了一个库,因为当你添加一个库时,你会在你的项目中添加一些可能不会使用的代码,这对你来说是重载项目,这是我的方法,你的方法对我来说是可敬的。【参考方案8】:

格式化日期并转换为字符串的简单方法

    Date date= new Date();

    String dateStr=String.format("%td/%tm/%tY", date,date,date);

    System.out.println("Date with format of dd/mm/dd: "+dateStr);

输出:日期格式为 dd/mm/dd: 21/10/2015

【讨论】:

【参考方案9】:

Date 对象有无格式,它是一种表示。日期可以通过String您喜欢的格式 显示。

例如“yyyy-MM-dd”、“yy-MMM-dd”、“dd-MMM-yy”等

要实现这一点,您可以使用SimpleDateFormat

试试这个,

        String inputString = "19/05/2009"; // i.e. (dd/MM/yyyy) format

        SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy"); 
        SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

        try 
            Date dateFromUser = fromUser.parse(inputString); // Parse it to the exisitng date pattern and return Date type
            String dateMyFormat = myFormat.format(dateFromUser); // format it to the date pattern you prefer
            System.out.println(dateMyFormat); // outputs : 2009-05-19

         catch (ParseException e) 
            e.printStackTrace();
        

此输出:2009-05-19

【讨论】:

以上是关于在 Java 中以不同的格式将字符串解析为日期的主要内容,如果未能解决你的问题,请参考以下文章

Java:不可解析的日期异常

如何在 BigQuery 中以字符串格式将工作日月份转换为日期?

java 字符串转换成日期

在 SQL Server 中以日期时间格式转换日期时间字符串

java.text.ParseException:无法解析的日期:将 mm/dd/yyyy 字符串转换为日期

如何将flutter中的日期解析为与Java ZonedDateTime兼容的json字符串