代码之家  ›  专栏  ›  技术社区  ›  Shervin Asgari

如何在不知道格式的情况下将字符串转换为日期?

  •  39
  • Shervin Asgari  · 技术社区  · 14 年前

    我有问题。我试图将一些字符串转换为日期,但我不知道日期到达的格式。

    可能是 yyyy.mm.dd hh:mm:ss MM.dd.yy hh:mm:ss 等等。

    如何将这些字符串转换为日期? 我试过这个:

    DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    Date d = (Date)formatter.parse(someDate);
    

    但当我打印出来的时候,它是这样打印出来的:2010-08-05 12:42:48.638 CEST,意思是 年-月-日hh:mm:ss 但是,当我运行上述代码时,日期对象现在变为 Sat Jan 31 00:42:48 CET 11 说起来也很奇怪。

    我有什么办法可以正确设置字符串的日期格式吗?

    9 回复  |  直到 7 年前
        1
  •  43
  •   Justin    14 年前

    你不能!

    如果你有约会的话 2010-08-05 那么它可以是2010年8月5日,也可以是2010年5月8日-你 需要 要知道日期格式(或者至少将一种格式优先于另一种格式),就要区分它们。

        2
  •  10
  •   Eyal Schneider    10 年前

    我同意Kragen的观点,在一般情况下,没有正确的解决方案。但是,如果满足以下条件,则可以使用以下解决方案:

    1. 你有一套所有可能的格式

    2. 两种格式之间没有歧义;两种格式都无法成功分析日期表达式。

    考虑以下迭代可能格式列表的解决方案。此解决方案利用 ThreadLocal ,以便在多线程环境中高效地进行数据分析(请记住 SimpleDateFormat 不是线程安全的):

    public class FlexibleDateParser {
        private List<ThreadLocal<SimpleDateFormat>> threadLocals = new  ArrayList<ThreadLocal<SimpleDateFormat>>();
    
        public FlexibleDateParser(List<String> formats, final TimeZone tz){
            threadLocals.clear();
            for (final String format : formats) {
                ThreadLocal<SimpleDateFormat> dateFormatTL = new ThreadLocal<SimpleDateFormat>() {
                    protected SimpleDateFormat initialValue() {
                        SimpleDateFormat sdf = new SimpleDateFormat(format);
                        sdf.setTimeZone(tz); 
                        sdf.setLenient(false);
                        return sdf;
                    }
                };
                threadLocals.add(dateFormatTL);
            }       
        }
    
        public Date parseDate(String dateStr) throws ParseException {
            for (ThreadLocal<SimpleDateFormat> tl : threadLocals) {
                SimpleDateFormat sdf = tl.get();
                try {
                    return sdf.parse(dateStr);
                } catch (ParseException e) {
                    // Ignore and try next date parser
                }
            }
            // All parsers failed
            return null;
        }       
    }
    
        3
  •  7
  •   oksayt    14 年前

    如前所述,您至少需要有一个有序的模式候选列表。一旦你有了它, Apache DateUtils 有一个 parseDate(String dateString, String[] patterns) 方法,使您可以轻松地尝试日期字符串上的模式列表,并按第一个匹配的模式进行分析:

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

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

    解析将依次尝试每个解析模式。只有当解析整个输入字符串时,才认为解析成功。如果没有匹配的分析模式,则会引发ParseException。

    解析器将对解析的日期宽大处理。

        4
  •  5
  •   bjoern    11 年前

    这里有一个基于美国日期格式的快速而肮脏的解决方案。

    public Date parseDate(String strDate) throws Exception
    {
        if (strDate != null && !strDate.isEmpty())
        {
            SimpleDateFormat[] formats =
                    new SimpleDateFormat[] {new SimpleDateFormat("MM-dd-yyyy"), new SimpleDateFormat("yyyyMMdd"),
                            new SimpleDateFormat("MM/dd/yyyy")};
    
            Date parsedDate = null;
    
            for (int i = 0; i < formats.length; i++)
            {
                try
                {
                    parsedDate = formats[i].parse(strDate);
                    return parsedDate;
                }
                catch (ParseException e)
                {
                    continue;
                }
            }
        }
        throw new Exception("Unknown date format: '" + strDate + "'");
    }
    
        5
  •  4
  •   Paweł Dyda    14 年前

    你的问题与国际化有关。正如Kragen所回答的,你不能仅仅以未知的格式解析日期。尽管您可以扫描所有可能的区域设置并分析 某物 但你不知道它是否被正确解析。

    只是一点I18N背景:

    问:你能告诉我这个日期是指什么年月日吗?

    2010年11月9日?

    答:不知道当地的情况,你就不能。可能是什么。9月11日在美国,11月9日在英国。等等。

        6
  •  1
  •   KarlP    14 年前

    如果它是一个协议,定义格式-也许ISO会激怒除了我们瑞典以外的所有人…

    如果它是从用户输入的,让他们设置他们的区域设置。如果可以,请以完整格式显示解析的日期,以便用户可以对其进行验证,如2009年11月10日。

        7
  •  0
  •   Alexander Malakhov Rahul R Dhobi    14 年前

    我唯一的猜测是,你应该先收集一些统计数据来确定格式。

    如果你幸运的话,你会有像“2010/08/13”这样的日期,可以明确地解析。

        8
  •  -1
  •   Maheshwar Ligade    9 年前

    这是一个简单的解决方案,对我很有用。 这是解析日期、将字符串作为参数传递的简单方法,并且可以按照您希望的任何格式解析它。

    String dateToConvert(String date) {
            String strDate = "";
            try {
                //create SimpleDateFormat object with source string date format
                DateFormat sdfSource = new SimpleDateFormat("yyyy-MM-dd");
    
                //parse the string into Date object
                Date d = sdfSource.parse(date);
                LocalLog.e(LOG_TAG, d.toString());
                //create SimpleDateFormat object with desired date format
                SimpleDateFormat sdfDestination = new SimpleDateFormat(AppConstants.UNIVERSAL_DATE_FORMAT);
    
                //parse the date into another format
                strDate = sdfDestination.format(d);
    
                LocalLog.e(LOG_TAG, strDate);
    
            } catch (ParseException pe) {
                System.out.println("Parse Exception : " + pe);
            }
            return strDate;
        }
    
        9
  •  -2
  •   Vignesh Anand    12 年前
    public  String compareDate( PaymentTxnRequest request ) throws ParseException { 
            Date debitDate= request.getPaymentTxn().getCrValDt();
            Date now = new Date();
            String response="";
            SimpleDateFormat sdfDate = new SimpleDateFormat("dd/MM/yyyy");
            String strCurrDate = sdfDate.format(now);
            String strDebitDate = sdfDate.format(debitDate);
            System.out.println("Current Date: " + strCurrDate);
            Date currentDate =  new SimpleDateFormat("dd/MM/yyyy").parse(strCurrDate);
            Date txnDate =  new SimpleDateFormat("dd/MM/yyyy").parse(strDebitDate);
            System.out.println("C -> "+currentDate);
            System.out.println("C -> "+txnDate); 
             if (txnDate!=null){
             if (currentDate.equals(txnDate))
             {
                 System.out.println("Valid Txn");
                 response="valid";
             }
             if (currentDate.after(txnDate))
             {
                System.out.println("--> Not  Valid TXN Past");   
                response="notValid";
             }
            if (currentDateenter code here.before(txnDate)){
                System.out.println("Future Valid TXn");
                 response="future";
            }
         }
            return response;
        }
    
    推荐文章