如何在不知道格式的情况下将字符串转换为日期?
我有一个问题。我正在尝试将一些字符串转换为日期,但我不知道日期到达的格式。
它可能为 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);
但是当我打印出 someDate 时,它打印出来是这样的: 2010-08-05 12:42:48.638 CEST 这意味着 yyyy.mm.dd hh:mm:ss ,但是当我运行上面的代码,日期对象现在变成了 Sat Jan 31 00:42:48 CET 11
至少可以说很奇怪。
到目前为止,我有什么想法可以正确格式化字符串吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如前所述,您至少需要有一个候选模式的有序列表。一旦你有了这个, Apache DateUtils 有一个
parseDate(String dateString, String[]patterns)
方法,可让您轻松尝试日期字符串上的模式列表,并按第一个匹配的模式对其进行解析:As noted before, you need to at least have an ordered list of pattern candidates. Once you have that, Apache DateUtils has a
parseDate(String dateString, String[] patterns)
method that lets you easily try out a list of patterns on your date string, and parse it by the first one that matches:这是一个基于美国日期格式的快速而肮脏的解决方案。
Here is a quick and dirty solution based on american date formats.
您的问题与国际化有关。正如克拉根回答的那样,你不能只解析未知格式的日期。虽然您可以扫描所有可能的语言环境并解析某些内容,但您不知道它是否已正确解析。
简单介绍一下 i18n 背景:
问:您能告诉我这个日期指的是哪一年、哪一天吗:
09/11/10?
答:如果不知道区域设置,你就不能。它可以是任何东西。 9 月 11 日在美国。 11 月 9 日,英国。等等。
Your problem is related to Internationalization. As Kragen answered, you can't just parse date in unknown format. Although you can scan all possible locales and parse something, but you wouldn't know if it was parsed correctly.
Just a little i18n background:
Q: Can you tell me what day month and year this date is referring to:
09/11/10?
A: Without knowing the locale, you can't. It could be anything. September, 11th in USA. November, 9th in Great Britain. And so on.
我曾经有一个任务要编写一个代码,该代码可以将字符串解析为日期,其中日期格式事先未知。即我必须解析任何有效的日期格式。我写了一个项目,然后写了一篇文章来描述我的实现背后的想法。以下是文章的链接: Java 8 java.time 包:解析迄今为止的任何字符串。一般想法是将您希望支持的所有模式写入外部属性文件中并从那里读取它们,并尝试按这些格式一一解析您的字符串,直到成功或用完格式为止。请注意,顺序也很重要,因为某些字符串可能对多种格式有效(美国/欧洲的差异)。优点是您可以不断向文件添加/删除格式,而无需更改代码。所以这样的项目也可以为不同的客户定制
I once had a task to write a code that would parse a String to date where date format was not known in advance. I.e. I had to parse any valid date format. I wrote a project and after that I wrote an article that described the idea behind my implementation. Here is the link to the article: Java 8 java.time package: parsing any string to date. General Idea is to write all the patterns that you wish to support into external properties file and read them from there and try to parse your String by those formats one by one until you succeed or run out of formats. Note that the order also would be important as some Strings may be valid for several formats (US/European differences). Advantage is that you can keep adding/removing formats to the file without changing your code. So such project could also be customized for different customers
如果它是一个协议;定义格式 - 也许 ISO 会激怒除我们瑞典以外的所有人......
如果它是由用户输入的;让他们设置他们的区域设置。如果可以的话,以完整格式显示解析后的日期,以便用户可以验证它,例如 2009 年 11 月 10 日。
If its a protocol; define the format - perhaps ISO that will irritate everyone except us in sweden...
If it input from users; Let them set their locale. If you can do it, show the parsed date in full format so the user can verify it, like November 10, 2009.
我唯一的猜测是,您应该首先收集一些统计数据来找出格式。
如果幸运的话,您将拥有像“2010/08/13”这样的日期,可以明确地解析它
My only guess, is that you should gather some statistics first to figure out the format.
If you're lucky, you will have date like "2010/08/13" which can be parsed unambiguously
我创建了一个实用程序来尝试解析一些常见的日期格式。
它会尝试检查哪个数字大于 12,否则如果两者都小于 12,它会优先选择用户定义的布尔值 PreferredMonthFirst,并根据该值在
MM/dd/yyyy
或dd/ 之间进行选择MM/yyyy
它还接受prefer24HourTime 布尔值来解析时间。
我没有使用列表并迭代它并尝试解析它并尝试捕获异常,因为异常的成本更高。因此,根据分隔符和长度,我尝试找到日期格式。
您可以在测试用例中找到用法。
https://github.com/rajat-g/DateParser
I created a utility that tries to parse some common date formats.
It tries to check which digit is greater than 12 or else if both are less than 12 it prefers user-defined boolean preferMonthFirst based on which it will choose between
MM/dd/yyyy
ordd/MM/yyyy
It also accepts prefer24HourTime boolean for parsing time.
I did not use the list and iterate over it and try to parse it and tried to catch exception because Exceptions are costlier. So based on separator and length I tried to find the date format.
You can find usages in the test cases.
https://github.com/rajat-g/DateParser
这是简单的解决方案,对我有用。
这是解析日期的简单方法,将字符串作为参数传递&以您想要的任何格式解析它。
Here is the simple solution, which is worked for me.
This is the simple method to parse the date, pass the String as argument & parse it in any format those you want.
你不能!
如果您的日期为
2010-08-05
,那么它可以是 2010 年 8 月 5 日或 2010 年 5 月 8 日 - 您需要知道日期格式(或者至少优先考虑一种格式)来区分它们。You cant!
If you have the date
2010-08-05
then it can be either 5th August 2010, or 8th May 2010 - you need to know the date format (or at least prioritise one format over the over) to tell them apart.我同意克拉根的观点,在一般情况下没有正确的解决方案。但是,如果满足以下条件,您可以使用以下解决方案:
您有一组所有可能的格式
格式之间没有歧义;其中两个都无法成功解析任何日期表达式。
考虑以下解决方案,该解决方案迭代可能的格式列表。此解决方案利用
ThreadLocal
,为了在多线程环境中提高日期解析效率(请记住SimpleDateFormat
不是线程安全的):I agree with Kragen that in the general case there is no correct solution. However, if the following conditions hold, you may use the solution below:
You have a set of all possible formats
There is no ambiguity between the formats; no date expression can be successfully parsed by two of them.
Consider the following solution which iterates over a list of possible formats. This solution makes use of
ThreadLocal
, in order to make date parsing efficient in a multi-threaded environment (remember thatSimpleDateFormat
isn't thread safe):