操作日期的静态方法.多线程问题



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 不是有效的年份。这就是为什么你有一个例外。应在调试器中运行代码。

最新更新