matlapudi
matlapudi

Reputation: 21

static methods that manipulates Date. multi threading issue

Friends,

I'm giving modified extract of my production code.

When running the following code, I'm getting "TestDateProblem: Problem with getYear method" though I'm executing the getDateEndOfDay by passing auditdate1.

I couldn't really solve this issue as the date is going correctly and I could see this in the logger in the catch block of my production code. I badly need your help.

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.

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;
        }
    }
}

Upvotes: 2

Views: 469

Answers (3)

dbf
dbf

Reputation: 6499

You have a problem with auditdate3, not with auditdate1. You pass 27-2011-12 as a date and try to extract a year. You check for a year at first and the last components of the date, but 27 and 12 are not a valid year. That's why you have an Exception. You should run your code in debugger.

Upvotes: 1

Keith Irwin
Keith Irwin

Reputation: 5668

There's no reason to believe that there are any thread-safety problems in this code. It has no static variables or other means by which non-local variable are manipulated. The only place where code which could even possibly be non-threadsafe is called is when you create a new GregorianCalendar object, but nothing in that documentation suggests that it wouldn't be threadsafe, so I think that's highly unlikely.

Also, isn't there already date-parsing stuff in Java? Why not just use java.text.SimpleDateFormat's parse method? Wouldn't that be much easier than all this?

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533660

While the code is needlessly verbose, it is also reasonably clear. The problem you have is that its trying to work out whether the date is in yyyy/mm/dd format or dd/mm/yyyy format, however if you give it sometime like yy/mm/dd format it can't work out what it is and gives the error you see.

Stepping through the code with a debugger would confirm this.

I would read this comment again as it explains the problem

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

You are giving it an invalid formatted date and it is rightly rejecting it because it doesn't know how to handle it.

Upvotes: 2

Related Questions