2015-12-25 24 views
6

如果输入是01-01-2015它应该更改为2015-01-01
如果输入是2015-01-01它应该更改为01-01-2015
我用SimpleDateFormat但没有得到正确的输出:日期格式改变

//Class to change date dd-MM-yyyy to yyyy-MM-dd and vice versa 
public class ChangeDate { 
    static SimpleDateFormat formatY = new SimpleDateFormat("yyyy-MM-dd"); 
    static SimpleDateFormat formatD = new SimpleDateFormat("dd-MM-yyyy"); 

    //This function change dd-MM-yyyy to yyyy-MM-dd 
    public static String changeDtoY(String date) { 
    try { 
     return formatY.format(formatD.parse(date)); 
    } 
    catch(Exception e) { 
     return null; 
    } 
    } 

    //This function change yyyy-MM-dd to dd-MM-yyyy 
    public static String changeYtoD(String date) { 
    try { 
     return formatD.format(formatY.parse(date)); 
    } 
    catch(Exception e) { 
     return null; 
    } 
    } 
} 

我需要一些条件,可以自动检测日期的模式,改变为另一种格式。

+0

第一个连字符的位置可能是?根据所选择的功能 – Henry

+1

获得第一个连字符的发生... – Sreemat

回答

2

正则表达式是矫枉过正

对于日期时间的工作,没必要和regex打扰。

只需尝试使用一种格式进行解析,即可捕获预期的异常。如果确实抛出异常,请尝试使用其他格式进行解析。如果抛出异常,那么您知道输入意外地不是这两种格式。

java.time

您正在使用现在内置到Java 8和后来的java.time框架取代了老麻烦的日期时间类。新课程的灵感来自非常成功的Joda-Time框架,作为其后继者,概念相似但重新设计。由JSR 310定义。扩展ThreeTen-Extra项目。请参阅Oracle Tutorial

LocalDate

新类包括一个,LocalDate,日期只值,而不时的一天。正是你需要的。

格式化程序

你的第一格式可以是标准ISO 8601格式,YYYY-MM-DD。这种格式在java.time中默认使用。

如果由于输入与ISO 8601格式不匹配导致此第一次解析尝试失败,则会引发DateTimeParseException

LocalDate localDate = null; 
try { 
    localDate = LocalDate.parse(input); // ISO 8601 formatter used implicitly. 
} catch (DateTimeParseException e) { 
    // Exception means the input is not in ISO 8601 format. 
} 

其他格式必须由一个编码模式指定,类似于您使用SimpleDateFormat进行的操作。因此,如果我们从第一次尝试中捕捉到异常,请进行第二次解析尝试。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy"); 
LocalDate localDate = null; 
try { 
    localDate = LocalDate.parse(input); 
} catch (DateTimeParseException e) { 
    // Exception means the input is not in ISO 8601 format. 
    // Try the other expected format. 
    try { 
     localDate = LocalDate.parse(input , formatter); 
    } catch (DateTimeParseException e) { 
     // FIXME: Unexpected input fit neither of our expected patterns. 
    } 
} 
+1

使用异常处理非例外行为(/用于流量控制)是非常糟糕的做法。 -1。 – XenoRo

+1

此处的异常处理是必需的,因为所称的核心Java方法声明异常。如果try/catch被省略,代码将不能成功编译。这个例子是捕捉由解析方法而不是纯异常或抛出的Throwable具体DateTimeParseException,所以本实施例中示出了简洁和正确的代码。 –

+0

@JasonPlurad嗯,'DateTimeParseException'是'RuntimeException'所以编译器不需要明确的异常处理(抛出或捕获)。或者你谈论别的什么?无论如何,'LocalDate.parse(...)'会在没有try/catch代码的情况下编译。但是,如果这个解决方案是优雅的话,那么另一个问题是。 –

0

阅读了有关PatternMatcher,并正则表达式

Java代码(基于OP):

if (date.matches("\\d{2}-\\d{2}-\\d{4}")){ 
    //convert D format to Y format... 
} else if(date.matches("\\d{4}-\\d{2}-\\d{2}")){ 
    //convert Y to D... 
} else { 
    throw new IllegalArgumentException("Received date format is not recognized."); 
} 

注:本场比赛,图案可与capture groups得到改善。
例如:"\\d{4}(-\\d{2}){2}""(-?\\d{2}){2}\\d{4}"

+2

Downvoter是欢迎说明理由 – XenoRo

7

有2个选项:

  1. 尝试检查与正则表达式做某事。像:

    if (dateString.matches("\\d{4}-\\d{2}-\\d{2}")) { 
        ... 
    } 
    
  2. 尝试转换到第一图案,如果抛出异常,试图转换为另一种模式(但它是不好的做法,这样做)

+0

我会尝试的第一个选项我已经尝试了第二个选项,但它转换,给了不合适date.Thank你 – Sreemat

+0

使用异常应该限于实际的例外情况,而不是处理预期的行为。 -1。 – XenoRo

+0

它不会抛出异常@AlmightyR – Sreemat

-2

只是比较的位置日期字符串中的第一个' - '字符。

+1

假定读者知道或了解“如何做”,在这一点上,他们很可能不会问/阅读这个答案。 -1。 – XenoRo

+0

您的欢迎和感谢全能的 –

+0

@SantoshVishwakarma现在,这个答案应该已发布为评论。请添加更多解释和示例代码,以成为一个完整的答案。 –

0

参见:https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/datetime/iso/examples/StringConverter.java

非ISO日期转换 https://docs.oracle.com/javase/tutorial/datetime/iso/nonIso.html

添加标识ISO日期两种方式是相互兼容(防断裂)的新年表装置输入的日期数据和存储它在正确的结构中(其他函数可以轻松地对数据进行操作)。参见:https://docs.oracle.com/javase/8/docs/api/java/time/chrono/Chronology.html

'正则表达式方法'可以被错误的输入打破,并且不会返回任何输入的标准错误(以获得标准的相同结果)。

查看由用户提供的答案“Tardate”在这个主题:How to sanity check a date in java

您想要防弹输入并将其存储在正确识别的结构中,以便用其他功能轻松操作。