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

Posted

技术标签:

【中文标题】如何使用java检测给定的日期格式【英文标题】:How to detect the given date format using java 【发布时间】:2012-07-03 20:02:19 【问题描述】:

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

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;
    

【问题讨论】:

***.com/questions/3389348/parse-any-date-in-java “任何格式”的范围相当大。这是否包括像03/04/05 这样的模棱两可的日期,这可能是取决于语言环境的任何顺序?这是否包括月份名称的本地化版本? sdfonlinetester.info 【参考方案1】:

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

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

【讨论】:

我赞成这个,因为我的想法是正确的,但为什么没有图书馆呢?这就是我正在寻找的。​​span> 【参考方案2】:

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

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

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

【讨论】:

但是它不考虑像 1990 年 8 月 19 日这样的日期 @user2822178:您可以在DATE_FORMAT_REGEXPS 中再添加一个reg ex,例如^[a-z]3\\s\\d1,2[,]\\s\\d4$", "MMM dd, yyyy" 链接目前已断开 @BernhardWebstudio 修复了链接。谢谢。【参考方案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");

【讨论】:

【参考方案4】:

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 年 2 月 942 日”之类的日期。

【讨论】:

1996 年 2 月 942 日是一个日期? 942 代表什么??【参考方案5】:

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

【讨论】:

【参考方案6】:

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)(\\d1,4|"+MONTH+")[-|/|.|\\s+]?(\\d1,2|"+MONTH+")[-|/|.|,]?[\\s+]?(\\d1,4|"+MONTH+")[\\s+|\\t|T]?(\\d0,2):?(\\d0,2):?(\\d0,2)[.|,]?[\\s]?(\\d0,3)?([+|-])?(\\d0,2)[:]?(\\d0,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);  
    


【讨论】:

【参考方案7】:
 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 "";
    


【讨论】:

【参考方案8】:

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

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

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

【讨论】:

以上是关于如何使用java检测给定的日期格式的主要内容,如果未能解决你的问题,请参考以下文章

如何从给定日期获得一个月的整数并打印为月份名称格式(“MMM”)

如何检测浏览器的输入格式[type=date]

java日期问题 如何将给定的俩时间 之间的月份列出来

如何找出给定日期和开始和结束时间可用的所有持续时间:java

java - 如何从Java中存储日期的给定字符串字段中减去X天? [复制]

如何以给定格式从 dijit.form.DateTextBox 获取日期?