我有问题。我试图将一些字符串转换为日期,我不知道日期到达的格式。
它可能会显示为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
,但是当我运行上面的代码时,日期对象现在变为{{1至少可以说是奇怪的。
任何想法如何才能正确格式化字符串到目前为止?
答案 0 :(得分:45)
你不能!
如果您的日期为2010-08-05
,则可能是2010年8月5日或2010年5月8日 - 您需要了解日期格式(或至少优先考虑一种格式告诉他们分开。
答案 1 :(得分:11)
我同意Kragen的说法,在一般情况下没有正确的解决方案。但是,如果满足以下条件,您可以使用以下解决方案:
您有一套所有可能的格式
格式之间没有歧义;没有日期表达式可以被其中两个成功解析。
考虑以下解决方案,它迭代可能的格式列表。此解决方案使用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;
}
}
答案 2 :(得分:7)
如前所述,您至少需要一个有序的模式候选列表。完成后,Apache DateUtils有一个parseDate(String dateString, String[] patterns)
方法,可让您轻松尝试日期字符串上的模式列表,并通过匹配的第一个模式对其进行解析:
public static Date parseDate(String str,
String[] parsePatterns)
throws ParseException
通过尝试各种不同的解析器来解析表示日期的字符串。
解析将依次尝试每个解析模式。如果解析整个输入字符串,则认为解析成功。如果没有解析模式匹配,则抛出ParseException。
解析器将对解析日期宽容。
答案 3 :(得分:5)
这是一个基于美国日期格式的快速而肮脏的解决方案。
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 + "'");
}
答案 4 :(得分:4)
您的问题与国际化有关。正如Kragen回答的那样,你不能只以未知格式解析日期。虽然您可以扫描所有可能的区域设置并解析某些内容,但您不知道它是否已正确解析。
只是一点点i18n背景:
问:你能告诉我这个日期指的是哪个月份和年份:09/11/10?
答:不知道区域设置,你不能。它可能是任何东西。 9月11日在美国。 11月9日在英国。等等。
答案 5 :(得分:1)
如果是协议;定义格式 - 也许ISO会激怒瑞典以外的所有人......
如果是用户输入的话;让他们设置他们的语言环境。如果可以,请以完整格式显示已解析的日期,以便用户可以对其进行验证,如2009年11月10日。
答案 6 :(得分:0)
我唯一的猜测是,你应该首先收集一些统计数据来确定格式。
如果你很幸运,你会有像“2010/08/13”这样的日期,可以毫不含糊地解析
答案 7 :(得分:0)
此答案是我对另一个问题的答案的副本,该问题被标记为与该问题重复
我曾经有一个任务要编写一个代码,该代码可以将String解析为迄今尚未事先知道日期格式的日期。即我必须解析任何有效的日期格式。我写了一个项目,然后写了一篇文章,描述了实现背后的想法。这是文章的链接:Java 8 java.time package: parsing any string to date。 General Idea是将希望支持的所有模式写入外部属性文件,然后从那里读取它们,并尝试按一种格式逐一解析String,直到成功或用尽格式为止。请注意,顺序也很重要,因为某些字符串可能对几种格式有效(美国/欧洲差异)。优点是您可以在不更改代码的情况下继续向文件中添加/删除格式。这样的项目也可以针对不同的客户进行定制
答案 8 :(得分:-1)
这是一个简单的解决方案,对我有用。 这是解析日期的简单方法,将String作为参数传递。以任何你想要的格式解析它。
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)
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;
}