将所有可能的字符串日期转换为日期对象

时间:2013-07-16 13:41:53

标签: java string date

我需要能够将日期的所有可能的字符串表示转换为Date对象。我知道这不是一项微不足道的任务,我主要是寻求指导,因为我认为没有“单线”解决方案。

仅有一个可能的输入类的当前示例:return new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).parse(input);

为了澄清我的问题,这里有一些可能的字符串输入:

  • 30-08-2011
  • 2011年6月25日
  • 2011年6月15日
  • 11年1月7日
  • 19-9-2011

数据是由第三方移交的,所以我对此无能为力。我有一些关于检查分隔符是什么的想法,并根据它选择正确的格式。

感谢任何帮助。

问候。

编辑:我可以访问用户的区域设置,这样我就可以实际区分日期和月份部分。或者换句话说,我可以访问日期的区域设置。

3 个答案:

答案 0 :(得分:1)

第一个想法可能是检测非数字和非字母字符。这些字符分隔日期中的月,日和年。在你的例子中,这些是' - ',''和'。'。

接下来,根据检测到的分隔符分割字符串。

这会在第一种情况下给你:[“30”,“08”,“2011”。

然后我们可以检查年份是第一个还是最后一个。这可以通过检查位数来完成。如果numDigits == 4那么你就知道哪一年是年份。否则你可以检查范围,是不是[1,31]然后又是一年。如果他们都在[1,31],那么我认为没有明确的决定方式。 (也许你更了解一年的可能性?)

最后是中间的字符串。在那里,您只需检查它是否包含字母字符或数字。

答案 1 :(得分:1)

Uglier代码比我想象的还要多。所以我会给它。 拆分令牌,填充3个日期组件。 人们仍然需要找到给定语言环境的那些组件的顺序:Mdy,dMy。

public class DateIn {

    public static void main(String[] args) {
        String[] dates = {
            "30-08-2011",
            "25.06.2011",
            "15 Juni 2011",
            "01-07-11",
            "19-9-2011",
        };
        DateIn in = new DateIn();
        Locale locale = Locale.US;
        for (String date : dates) {
            try {
                Date d = in.read(date, locale);
                System.out.printf("%s -> %s%n", date,
                    new SimpleDateFormat("yyyy-MM-dd").format(d));
            } catch (IllegalArgumentException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    private Date read(String date, Locale locale)
            throws IllegalArgumentException {
        final String[] ymdFormatters = { "y", "M", "d" };
        final int[] ymdGetters = { Calendar.YEAR, Calendar.MONTH,
            Calendar.DAY_OF_MONTH };
        String[] tokens = date.split("\\W+");
        final int Y = 0;
        final int M = 1;
        final int D = 2;
        int[] ymdValues = new int[3];
        for (String token : tokens) {
            if (token.matches("\\d+\\pL+")) { // 1st, 2nd, 3rd, 4th, 1e, ...
                token = token.replaceAll("\\pL+", "");
                ymdValues[D] = Integer.parseInt(token);
            } else if (token.matches("\\d+")) {
                int n = Integer.parseInt(token);
                if (n > 31) {
                    ymdValues[Y] = n;
                } else if (n > 12) {
                    ymdValues[D] = n;
                } else {
                    // Locale dependent order.
                    if (ymdValues[M] == 0) {
                        ymdValues[M] = n;
                    } else if (ymdValues[D] == 0) {
                        ymdValues[D] = n;
                    } else if (ymdValues[Y] == 0) {
                        ymdValues[Y] = n;
                    }
                }
            } else if (!token.isEmpty()) {
                for (int md = M; md <= D; ++md) {
                    String fmt = "";
                    for (int i = 0; i < 4; ++i) {
                        fmt += ymdFormatters[md];
                        SimpleDateFormat sdf = new SimpleDateFormat(fmt);
                        sdf.setLenient(true);
                        try {
                            Date dt = sdf.parse(token);
                            Calendar cal = Calendar.getInstance(locale);
                            cal.setTime(dt);
                            int n = cal.get(ymdGetters[md]);
                            if (md == M) {
                                ++n; // To 1-based
                            }
                            ymdValues[md] = n;
                            break;
                        } catch (ParseException e) {
                            //continue;
                        }
                    }
                }
            }
        }
        Calendar calendar = Calendar.getInstance(locale);
        for (int md = Y; md <= D; ++md) {
            int n = ymdValues[md];
            if (n == 0) {
                throw new IllegalArgumentException("Missing "
                    + ymdFormatters[md] + " part in " + date);
            }
            if (md == Y) {
                if (n < 100)
                    n += (calendar.get(Calendar.YEAR) / 100) * 100;
            } else if (md == M) {
                --n; // Calendar's month is 0-based.
            }
            calendar.set(ymdGetters[md], n);
        }
        return calendar.getTime();
    }
}

答案 2 :(得分:0)

您可以尝试将字符串拆分为其组成部分(天,月,年)并单独解析它们。

例如:

String input = 30-08-2011;
if (input.indexOf("-") == -1)
return;
else    
   String day = index.substring(0, selected.indexOf("-"));
那天,可以单独解析。然后重复该过程的月份和年份。然后,您不必担心日期组件之间的格式。