在Java中将日期字符串转换为特定的日期格式"dd-MM-yyyy"

3
我有多个联系人的出生日期,并且所有联系人都与移动设备同步。现在问题是所有联系人的生日格式都不同,我想以特定格式(如“dd-MM-yyyy”)显示所有生日日期。
例如,一个同步的联系人的生日可能是“1990-02-07”或“1988-06-15T22:00:00.000Z”或“12-02-1990”等等...然后所有这些日期都应该以特定格式“dd-MM-yyyy”显示。
那么我该怎么解决这个问题呢?
欢迎提出任何建议。

4
尝试搜索Java日期格式,这方面已经有数百个类似的问题了... - Jasper
可能是Java中不同格式的字符串转日期的重复问题。 - Matthieu
3个回答

19

简单地使用SimpleDateFormat类即可。例如:

Date d = Calendar.getInstance().getTime(); // Current time
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // Set your date format
String currentData = sdf.format(d); // Get Date String according to date format

在这里,您可以查看详细信息和所有支持的格式:

http://developer.android.com/reference/java/text/SimpleDateFormat.html


如果我知道原始日期字符串的格式,我可以将给定的字符串转换为以下特定格式的日期。但是如果我不知道原始字符串的格式,我该怎么做呢? - Rushabh Patel
如果您指定了一个字符串格式,SimpleDateFormat类应该会用'零'来完整缺失的日期部分。看一下证明。 - kinghomer
请注意,旧的日期时间类(如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat)现在已经成为遗留系统,被内置于Java 8和Java 9中的java.time类所取代。请参阅Oracle的教程 - Basil Bourque

3
我理解您的问题。您可以尝试一种冗长的方法,通过将字符串使用“-”进行分割并将其存储在数组中,然后检查数组中的每个字符串,将其解析为整数,然后执行条件语句。
假设您给出的格式如下: "1990-02-07" 年-月-日 "1988-06-15T22:00:00.000Z" 年-月-日T时间Z "12-02-1990" 月-日-年
您可以尝试像这样的方法。
    public String convert(String s){
        SimpleDateFormat newformat = new SimpleDateFormat("dd-MM-yyyy");
        try{
            if(s.contains("T")){
                String datestring = s.split("T")[0];
                SimpleDateFormat oldformat = new SimpleDateFormat("yyyy-MM-dd");
                String reformattedStr = newformat.format(oldformat.parse(datestring));
                return reformattedStr;
            }
            else{
                if(Integer.parseInt(s.split("-")[0])>13){
                    SimpleDateFormat oldformat = new SimpleDateFormat("yyyy-MM-dd");
                    String reformattedStr = newformat.format(oldformat.parse(s));
                    return reformattedStr;
                }
                else{
                    SimpleDateFormat oldformat = new SimpleDateFormat("MM-dd-yyyy");
                    String reformattedStr = newformat.format(oldformat.parse(s));
                    return reformattedStr;
                }

            }
        }
        catch (Exception e){
            return null;
        }
    }

如果我知道原始日期字符串的格式,我可以将给定的字符串转换为以下特定格式的日期。但是如果我不知道原始字符串的格式,我该怎么做呢? - Rushabh Patel
好的,我想你必须知道正在同步的格式。看看这个链接https://dev59.com/omDVa4cB1Zd3GeqPdXPf 我相信月份始终在日期之前。你有三种最终格式:月-日-年,年-月-日和年-月-日T时间Z。 - Leonid
在之前的评论中,我说月份总是在日期之前。这适用于任何来自Java的内容。另外,我已经编辑了我的答案。你可以试试那个... - Leonid

1

ISO 8601

现在的问题是所有联系人都有不同的生日格式。

这才是真正的问题:以各种格式存储日期时间值。

在将日期时间值序列化为文本时,始终使用标准的ISO 8601格式。这些格式明智而实用,避免歧义,易于机器解析,也易于跨文化人类阅读。

java.time类在解析/生成字符串时默认使用这些标准格式。

java.time

现代方法使用java.time类替代了麻烦的旧日期时间类。避免使用旧的DateCalendarSimpleDateFormat和相关类。

例如,一个同步联系人的生日可能是"1990-02-07"或"1988-06-15T22:00:00.000Z"或"12-02-1990"等...

由于歧义,解析任何可能的日期时间格式都是不可能的。例如,01-02-1990表示1月2日还是2月1日?
您可以进行猜测,但这可能是不明智的,具体取决于准确性对您的业务问题有多重要。
使用DateTimeFormatter定义一堆格式化模式。尝试每个模式。当抛出DateTimeParseException时,继续下一个模式,直到找到一个可用的。
你可以使用string length来帮助指导猜测。
List < DateTimeFormatter > dateFormatters = new ArrayList <>( 2 );
dateFormatters.add( DateTimeFormatter.ofPattern( "uuuu-MM-dd" ) );  // BEWARE of ambiguity in these formatters regarding month-versus-day.
dateFormatters.add( DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) );

String input = "1990-02-07";
// String input = "12-02-1990" ;

if ( null == input )
{
    throw new IllegalArgumentException( "Passed null argument where a date-time string is expected. Message # c7a4fe0e-9500-45d5-a041-74d457381008." );
} else if ( input.length() <= 10 )
{
    LocalDate ld = null;
    for ( DateTimeFormatter f : dateFormatters )
    {
        try
        {
            ld = LocalDate.parse( input , f );
            System.out.println( ld );
        } catch ( Exception e )
        {
            // No code here.
            // We purposely ignore this exception, moving on to try the next formatter in our list.
        }
    }
} else if ( ( input.length() > 10 ) && input.substring( input.length() - 1 ).equalsIgnoreCase( "Z" ) ) // If over 10 in length AND ends in a Z.
{
    Instant ld = null;
    try
    {
        ld = Instant.parse( input );  // Uses `DateTimeFormatter.ISO_INSTANT` formatter.
    } catch ( Exception e )
    {
        throw new IllegalArgumentException( "Unable to parse date-time string argument. Message # 0d10425f-42f3-4e58-9baa-84ff949e9574." );
    }
} else if ( input.length() > 10 )
{
    // TODO: Define another list of formatters to try here.
} else if ( input.length() == 0 )
{
    throw new IllegalArgumentException( "Passed empty string where a date-time string is expected. Message # 0ffbd9b6-8905-4e28-a732-0f402d4673df." );
} else  // Impossible-to-reach, for defensive programming.
{
    throw new RuntimeException( "ERROR - Unexpectedly reached IF-ELSE when checking input argument. Message # 6228d9e0-047a-4b83-8916-bc526e0fd22d." );
}
System.out.println("Done running.");

1990年02月07日 完成运行。

关于java.time

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

Joda-Time项目现在处于维护模式,建议迁移到java.time类。

想要了解更多,请查看Oracle教程。并且在Stack Overflow上搜索许多示例和解释。规范为JSR 310

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

如何获取java.time类?

ThreeTen-Extra项目通过增加类来扩展java.time。该项目是java.time可能未来添加的一些内容的试验场。您可能会在这里找到一些有用的类,例如Interval, YearWeek, YearQuarter更多


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