статические методы, которые манипулируют датой.проблема многопоточности - PullRequest
2 голосов
/ 27 декабря 2011

Друзья

Я даю модифицированный фрагмент моего производственного кода.

При выполнении следующего кода я получаю «TestDateProblem: проблема с методом getYear», хотя я выполняю getDateEndOfDay, передавая auditdate1.

Я не мог действительно решить эту проблему, поскольку дата идет правильно, и я мог видеть это в регистраторе в блоке 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;
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 27 декабря 2011

Нет оснований полагать, что в этом коде есть проблемы с безопасностью потоков. Он не имеет статических переменных или других средств, которыми манипулируют нелокальные переменные. Единственное место, где может вызываться код, который может быть даже не потокобезопасным, - это когда вы создаете новый объект GregorianCalendar, но ничто в этой документации не предполагает, что он не будет потокобезопасным, поэтому я думаю, что это крайне маловероятно.

Кроме того, разве в Java уже ничего не разбирается? Почему бы просто не использовать метод разбора java.text.SimpleDateFormat? Разве это не будет намного проще, чем все это?

2 голосов
/ 27 декабря 2011

Несмотря на то, что код излишне многословен, он также достаточно понятен. Проблема, с которой вы столкнулись, заключается в том, что она пытается выяснить, является ли дата в формате гггг / мм / дд или в формате дд / мм / гггг, однако, если вы дадите ей что-то в формате гг / мм / дд, она не сможет определить это и дает ошибку, которую вы видите.

Выполнение кода с помощью отладчика подтвердит это.

Я бы прочитал этот комментарий еще раз, поскольку он объясняет проблему

* We don't send this way but the problem occurs if the date goes this
* way.

Вы даете ей неверную отформатированную дату, и она по праву отклоняет ее, потому что не знает, как с ней обращаться.

1 голос
/ 27 декабря 2011

У вас проблема с AuditDate3, а не с AuditDate1. Вы передаете 27-2011-12 в качестве даты и пытаетесь извлечь год. Сначала вы проверяете год и последние компоненты даты, но 27 и 12 не являются действительным годом. Вот почему у вас есть исключение. Вы должны запустить свой код в отладчике.

...