8

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

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;
    }
4

9 回答 9

6

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

您可能想要标记模棱两可的输入,例如 2012/5/6 是 6 月 5 日还是 5 月 6 日?

于 2012-07-03T11:37:53.163 回答
5

BalusC 编写了一个DateUtil适用于许多情况的简单程序。您可能需要扩展它以满足您的要求。

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

以及您需要寻找的方法determineDateFormat()

于 2012-07-03T11:43:36.810 回答
3

如果您使用的是Joda Time(btw 很棒的库),您可以很容易地做到这一点:

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");
于 2012-07-03T13:55:49.743 回答
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。

解析器会严格解析——它不允许诸如“February 942, 1996”之类的日期。

于 2015-07-16T15:40:50.797 回答
0

确定预期的格式,并尝试使用每种格式解析日期,一个接一个。一旦其中一种格式无一例外地解析日期,就立即停止。

于 2012-07-03T11:38:09.567 回答
0

点击查看结果

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

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);  
    }

}
于 2018-04-17T15:59:36.180 回答
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 "";
    }

}
于 2019-07-04T12:42:04.620 回答
0

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

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

希望#2 至少在少数情况下对您有所帮助。

于 2020-10-13T19:39:03.977 回答
0

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
于 2022-03-04T22:07:20.557 回答