Friends,
我正在提供我的生产代码的修改摘录。
运行以下代码时,我得到"测试日期问题:getYear 方法的问题",尽管我通过传递 auditdate1 来执行getDateEndOfDay
。
我无法真正解决这个问题,因为日期正确,我可以在生产代码的 catch 块的记录器中看到这一点。我非常需要你的帮助。
此getDateEndOfDay
方法从许多公共方法调用,并且多个线程可能同时调用这些静态方法。
package test;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
public class TestDateProblem {
public static void main(String args[]) {
/*
* This is the date format that is mostly used. Logger shows this kind
* of date during Exception.
*/
String auditdate1 = "2011-12-27";
// Rarely sent this way.
String auditdate2 = "27-12-2011";
/*
* We don't send this way but I'm sure the problem occurs if the date goes this
* way. As far as the inputs are concerned, it doesn't go like this.
*/
String auditdate3 = "27-2011-12";
try {
System.out.println("Result1:" + getDateEndOfDay(auditdate1));
System.out.println("Result2:" + getDateEndOfDay(auditdate2));
// simulating problem?
System.out.println("Result3:" + getDateEndOfDay(auditdate3));
} catch (Exception e) {
System.out.println("auditdate1:" + auditdate1);
}
}
/*
* This getDateEndOfDay(.) method is called from many public methods and it
* may be possible that multiple threads are calling these static methods at
* the same time.
*/
public static Date getDateEndOfDay(String dateparam) throws Exception {
String separator = "/";
dateparam = dateparam.replace("-", separator);
String[] strP = dateparam.split(separator);
Integer year = getYear(strP);
Integer month = getMonth(strP);
Integer day = getDay(strP);
GregorianCalendar cal = new GregorianCalendar(year, month - 1, day, 23,
59, 00);
return cal.getTime();
}
private static Integer getYear(String[] dateComponents) throws Exception {
if (dateComponents.length != 3) {
return 1900;
}
System.out
.println("dateComponents::" + Arrays.toString(dateComponents));
Integer val1 = Integer
.valueOf(dateComponents[0].startsWith("0") ? dateComponents[0]
.substring(1) : dateComponents[0]);
Integer val2 = Integer
.valueOf(dateComponents[2].startsWith("0") ? dateComponents[2]
.substring(1) : dateComponents[2]);
if (val1 > 1900) {
return val1;
} else if (val2 > 1900) {
return val2;
} else {
// Original code throws exception instead of printing to console.
System.out.println("TestDateProblem: Problem with getYear method.");
throw new Exception();
}
}
private static Integer getDay(String[] dateComponents) {
if (dateComponents.length != 3) {
return -1;
}
Integer val1 = Integer
.valueOf(dateComponents[0].startsWith("0") ? dateComponents[1]
.substring(1) : dateComponents[0]);
Integer val2 = Integer
.valueOf(dateComponents[2].startsWith("0") ? dateComponents[1]
.substring(1) : dateComponents[2]);
if (val1 <= 31) {
return val1;
} else if (val2 <= 31) {
return val2;
} else {
System.out.println("TestDateProblem: Problem with getDay method.");
return 0;
}
}
private static Integer getMonth(String[] dateComponents) {
if (dateComponents.length != 3) {
return 0;
}
Integer val1 = Integer
.valueOf(dateComponents[1].startsWith("0") ? dateComponents[1]
.substring(1) : dateComponents[1]);
if (val1 <= 12 && val1 >= 1) {
return val1;
} else {
System.out
.println("TestDateProblem:: Problem with getMonth method");
return 0;
}
}
}
虽然代码不必要地冗长,但它也相当清晰。 您遇到的问题是它试图确定日期是 yyyy/mm/dd 格式还是 dd/mm/yyyy 格式,但是如果你有时像 yy/mm/dd 格式一样给出它,它无法弄清楚它是什么并给出你看到的错误。
使用调试器单步执行代码将确认这一点。
我会再次阅读此评论,因为它解释了问题
* We don't send this way but the problem occurs if the date goes this
* way.
您给它一个无效的格式化日期,它正确地拒绝它,因为它不知道如何处理它。
没有理由相信此代码中存在任何线程安全问题。 它没有静态变量或其他操作非局部变量的方法。 调用甚至可能是非线程安全代码的唯一地方是当您创建一个新的 GregorianCalendar 对象时,但该文档中没有任何内容表明它不是线程安全的,所以我认为这不太可能。
另外,Java 中不是已经有日期解析的东西了吗? 为什么不直接使用 java.text.SimpleDateFormat 的解析方法呢? 这难道不是比这一切容易得多吗?
您在 auditdate3 方面有问题,而不是 auditdate1。您传递 27-2011-12 作为日期并尝试提取一年。您在日期的第一个和最后一个组成部分检查年份,但 27 和 12 不是有效的年份。这就是为什么你有一个例外。应在调试器中运行代码。