如何使用java检测给定的日期格式

问题描述 投票:0回答:9

我有一个方法可以获取字符串并将其更改为特定的日期格式,但问题是日期可以是任何格式 例如

16 July 2012

March 20 2012

2012 March 20

所以我需要检测字符串是哪种文件格式。

我使用下面的代码来测试它,但如果文件格式发生变化,我会得到异常。

private String getUpdatedDate(String updated) {
        Date date;
        String formatedDate = null;
        try {
            date = new SimpleDateFormat("d MMMM yyyy", Locale.ENGLISH)
                    .parse(updated);
            formatedDate = getDateFormat().format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return formatedDate;
    }
java localdate
9个回答
9
投票

也许最简单的解决方案是构建一组您可以合理预期的日期格式,然后依次尝试针对每个格式的输入。

您可能想要标记不明确的输入,例如2012年5月6日是6月5日还是5月6日?


5
投票

BalusC 编写了一个简单的

DateUtil
,适用于许多情况。您可能需要扩展它以满足您的要求。

这是链接:https://balusc.omnifaces.org/2007/09/dateutil.html

以及您需要寻找的方法

determineDateFormat()


3
投票

如果你正在使用 Joda Time (顺便说一句,很棒的库),你可以很容易地做到这一点:

DateTimeParser[] dateParsers = { 
        DateTimeFormat.forPattern("yyyy-MM-dd HH").getParser(),
        DateTimeFormat.forPattern("yyyy-MM-dd").getParser() };
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, dateParsers).toFormatter();

DateTime date1 = formatter.parseDateTime("2012-07-03");
DateTime date2 = formatter.parseDateTime("2012-07-03 01");

2
投票

Apache commons 有一个实用方法来解决这个问题。 org.apache.commons.lang.time.DateUtils 类有一个方法 parseDateStrictly

   public static Date parseDateStrictly(String str,
                                         String[] parsePatterns)
                                  throws ParseException

 Parameters:
        str - the date to parse, not null
        parsePatterns - the date format patterns to use, see SimpleDateFormat, not null

通过尝试各种不同的解析器来解析表示日期的字符串。

解析将依次尝试每种解析模式。仅当解析整个输入字符串时,解析才被视为成功。如果没有解析模式匹配,则会抛出 ParseException。

解析器严格解析 - 它不允许诸如“1996 年 942 年 2 月”之类的日期。


1
投票

我的图书馆 FTA (https://github.com/tsegall/fta) 旨在解决这个问题(以及其他问题)。这是一个例子:


import java.util.Locale;

import com.cobber.fta.dates.DateTimeParser;
import com.cobber.fta.dates.DateTimeParser.DateResolutionMode;

public abstract class DetermineDateFormat {

    public static void main(final String[] args) {
        final DateTimeParser dtp = new DateTimeParser(DateResolutionMode.MonthFirst, Locale.ENGLISH);

        System.err.println(dtp.determineFormatString("26 July 2012"));
        System.err.println(dtp.determineFormatString("March 9 2012"));
        // Note: Detected as MM/dd/yyyy despite being ambiguous as we indicated MonthFirst above when insufficient data
        System.err.println(dtp.determineFormatString("07/04/2012"));
        System.err.println(dtp.determineFormatString("2012 March 20"));
        System.err.println(dtp.determineFormatString("2012/04/09 18:24:12"));
    }

这将给出以下输出:

MMMM d yyyy
MM/dd/yyyy
yyyy MMMM dd
yyyy/MM/dd HH:mm:ss

0
投票

确定需要哪种格式,并尝试用每种格式依次解析日期。一旦其中一种格式毫无例外地解析日期,就停止。


0
投票

Click to see the result

使用正则表达式解析字符串中的日期。该正则表达式可以检测任何类型的日期格式。这里的示例代码还不包括时间。您可以更改代码以添加日期的更多部分,例如时间和时区...月份名称取决于系统的默认语言区域设置。

import java.io.IOException;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateUtils {

    static String MONTH="";
    static String dateRegEx="";
    static Pattern DatePattern; 
    static HashMap<String, Integer> monthMap = new HashMap<String, Integer>();
    static {
        initializeMonthName();
        dateRegEx="(?i)(\\d{1,4}|"+MONTH+")[-|/|.|\\s+]?(\\d{1,2}|"+MONTH+")[-|/|.|,]?[\\s+]?(\\d{1,4}|"+MONTH+")[\\s+|\\t|T]?(\\d{0,2}):?(\\d{0,2}):?(\\d{0,2})[.|,]?[\\s]?(\\d{0,3})?([+|-])?(\\d{0,2})[:]?(\\d{0,2})[\\s+]?([A|P]M)?";
        DatePattern = Pattern.compile(dateRegEx);
    }

    private static void initializeMonthName() {
        String[] monthName=getMonthString(true);
        for(int i=0;i<12;i++){
            monthMap.put(monthName[i].toLowerCase(), Integer.valueOf(i+1));
        }

        monthName=getMonthString(false);
        for(int i=0;i<12;i++){
            monthMap.put(monthName[i].toLowerCase(), Integer.valueOf(i+1));
        }

        Iterator<String> it = monthMap.keySet().iterator();
        while(it.hasNext()){
            String month=it.next();
            if(MONTH.isEmpty()){
                MONTH=month;
            }else{
                MONTH=MONTH + "|" + month;
            }
        }
    }

    public static boolean isInteger(Object object) {
        if(object instanceof Integer) {
            return true;
        } else {
            try{
                Integer.parseInt(object.toString());
            }catch(Exception e) {
                return false;
            }           
        } 
        return true;
    }

    public static String[] getMonthString(boolean isShort) {
        DateFormatSymbols dfs = new DateFormatSymbols();
        if (isShort) {
         return dfs.getShortMonths();
        } else {
            return dfs.getMonths();
        }
    }

    public static int getMonthMap(String value) {

        if(monthMap.get(value)==null){
            return 0;
        }
        return monthMap.get(value).intValue();      
    }

    public static long parseDate(String value){

        Matcher matcher = DatePattern.matcher(value);
        int Year=0, Month=0, Day=0; 
        boolean isYearFound=false;
        boolean isMonthFound=false;
        boolean isDayFound=false;
        if(matcher.find()) {            
            for(int i=1;i<matcher.groupCount();i++){
                String data=matcher.group(i)==null?"":matcher.group(i); 
                if(data.equalsIgnoreCase("null")){
                    data="";
                }
                //System.out.println(String.valueOf(i) + ": " + data);
                switch(i){
                case 1:
                    if(!data.isEmpty()){
                        if(isInteger(data)){
                            Integer YMD = Integer.valueOf(data);
                            if(YMD==0){
                                return 0;
                            }
                            if(YMD>31){
                                Year = YMD.intValue();
                                isYearFound = true;
                            }else if(YMD>12){
                                Day = YMD.intValue();
                                isDayFound = true;
                            }else {
                                Month=YMD.intValue();
                                isMonthFound=true;
                            }
                        }else {
                            Month = getMonthMap(data.toLowerCase());
                            if(Month==0){
                                return 0;
                            }
                            isMonthFound=true;
                        }
                    }else {
                        return 0;
                    }
                    break;
                case 2:
                    if(!data.isEmpty()){
                        if(isInteger(data)){                            
                            Integer YMD = Integer.valueOf(data);
                            if(YMD==0){
                                return 0;
                            }

                            if(YMD>31){
                                if(isYearFound) {
                                    return 0;
                                }
                                Year = YMD.intValue();
                                isYearFound = true;
                            }else if(YMD>12){
                                if(isDayFound) {                                    
                                    return 0;
                                }
                                Day = YMD.intValue();
                                isDayFound = true;
                            }else {                             
                                if(isMonthFound){
                                    Day=YMD.intValue();
                                    isDayFound=true;
                                }else{
                                    Month=YMD.intValue();
                                    isMonthFound=true;
                                }
                            }
                        }else {
                            if(isMonthFound){
                                Day=Month;
                                isDayFound=true;
                            }
                            Month = getMonthMap(data.toLowerCase());
                            if(Month==0){
                                return 0;
                            }

                            isMonthFound=true;
                        }
                    }else {
                        return 0;
                    }
                    break;
                case 3:
                    if(!data.isEmpty()){
                        if(isInteger(data)){

                            Integer YMD = Integer.valueOf(data);
                            if(YMD==0){
                                return 0;
                            }
                            if(YMD>31){
                                if(isYearFound) {
                                    return 0;
                                }
                                Year = YMD.intValue();
                                isYearFound = true;
                            }else if(YMD>12){
                                if(isDayFound) {
                                    return 0;
                                }
                                Day = YMD.intValue();
                                isDayFound = true;
                            }else {
                                if(isMonthFound){
                                    Day=YMD.intValue();
                                    isDayFound=true;                                    
                                }else {
                                    Month = YMD.intValue();
                                    isMonthFound=true;
                                }

                            }
                        }else {
                            if(isMonthFound){
                                Day=Month;
                                isDayFound=true;
                            }
                            Month = getMonthMap(data.toLowerCase());
                            if(Month==0){
                                return 0;
                            }
                            isMonthFound=true;
                        }
                    }else {
                        return 0;
                    }
                    break;
                case 4:
                //hour
                    break;
                case 5:
                //minutes
                    break;
                case 6:
                //second
                    break;
                case 7:
                //millisecond
                    break;
                case 8:
                //time zone +/-
                    break;
                case 9:
                //time zone hour
                    break;
                case 10:
                // time zone minute
                    break;
                case 11:
                //AM/PM
                    break;
                }

            }           
        }

        Calendar c = Calendar.getInstance();
        c.set(Year, Month-1, Day, 0, 0); 
        return c.getTime().getTime();
    }


    public static void main(String[] argv) throws IOException {

        long d= DateUtils.parseDate("16 July 2012");
        Date dt = new Date(d);
        SimpleDateFormat df2 = new SimpleDateFormat("d MMMM yyyy");
        String dateText = df2.format(dt);
        System.out.println(dateText);

        d= DateUtils.parseDate("March 20 2012");
        dt = new Date(d);
        dateText = df2.format(dt);
        System.out.println(dateText);        

        d= DateUtils.parseDate("2012 March 20");
        dt = new Date(d);
        dateText = df2.format(dt);
        System.out.println(dateText);  
    }

}

0
投票
 public static String detectDateFormat(Context context, String inputDate, String requiredFormat) {
    String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
    String dateFormat = "";

    if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
        dateFormat = "MMddyyyy";
    } else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
        dateFormat = "ddMMyyyy";
    } else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
        dateFormat = "yyyyMMdd";
    } else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
        dateFormat = "yyyyddMM";
    } else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
        dateFormat = "ddMMMyyyy";
    } else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
        dateFormat = "MMMddyyyy";
    } else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
        dateFormat = "yyyyMMMdd";
    } else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
        dateFormat = "yyyyddMMM";
    } else {

    }
    try {
        String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));
        Toast.makeText(context, formattedDate, Toast.LENGTH_SHORT).show();
        return formattedDate;
    } catch (Exception e) {
        Toast.makeText(context, "Please check the date format", Toast.LENGTH_SHORT).show();
        return "";
    }

}

0
投票

我也遇到了这个问题,在某些地方:

  1. 我做了同样的事情,收集了符合我需要的格式。
  2. 更新了我的 sql 查询,使其以我可以轻松解析的格式返回日期,例如在我的查询 TO_CHAR (o.CREATE_TS, 'MM-DD-YYYY') 中使用了它 & 在以我的其他所需格式转换时,使用 java 中的“MM-dd-yyyy”来解析并更改为所需格式。

希望#2 至少在少数情况下能帮助您。

© www.soinside.com 2019 - 2024. All rights reserved.