Matthew Cassar
Matthew Cassar

Reputation: 223

Java Calendar Not Changing Values

I am writing an application to receive past stock data in java. I am using a Calendar to chose the to and from dates when calculating a six day average however this is not working due to the to calendar being the same as the from despite subtracting days in the latter...

    private BigDecimal calcMovingAvg(int days, Calendar start){

    Calendar to = start;

    int temp = Functions.weekdays(start.getTime(), days);
    temp = temp - (2 * temp);

    start.add(start.DAY_OF_MONTH, temp);

    BigDecimal d = new BigDecimal(String.valueOf(days));

    List<HistoricalQuote> histQuotes = null;
    try {
        //Calling a method to get stock history between start and to date
        histQuotes = stk.getHistory(start, to, Interval.DAILY);
        System.out.println(histQuotes);
    } catch (IOException e) {
        e.printStackTrace();
    }

Start is already defined and working

I save to = start so as to have an end date when taking the previous 6 days for averaging

Functions.weekdays calculates how many of those 6 days were actually weekdays (business days) and adjusts the number accordingly (temp is the number of days needed to get 6 business days).

When comparing, I am getting start == to, why is start not changing?

Upvotes: 0

Views: 266

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 339342

java.time

This work is easier with the java.time framework built into Java 8 and later. Avoid using the old date-time classes such as java.util.Calendar as they haven proven to be poorly designed and troublesome.

Immutable Objects

The java.time classes use immutable objects, generating new objects based on the old ones’ values rather than changing (”mutating“) the original. This approach prevents the problem encountered in the Question.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime later = now.plusWeeks( 1 );  // Generates a second object without modifying the first.

Convert

Best to avoid the old classes entirely, including java.util.Date and java.util.Calendar. But if you must, you can convert.

New methods have been added to the old classes to facilitate conversion.

Call GregorianCalendar::toZonedDateTime to generate an equivalent ZonedDateTime object. I your Calendar object is indeed a GregorianCalendar, downcast.

if( cal instanceof GregorianCalendar ) {
    GregorianCalendar gCal = ( GregorianCalendar ) cal;  // Cast. Down-casting from interface to concrete class.
    ZonedDateTime zdt = gCal.toZonedDateTime();
}

Call the static method GregorianCalendar.from( ZonedDateTime) to get a GregorianCalendar object (which implements the Calendar interface) from a ZonedDateTime.

java.util.Calendar cal = java.util.GregorianCalendar.from( later );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Upvotes: 1

Matthew Cassar
Matthew Cassar

Reputation: 223

    Calendar to = (Calendar) start.clone();

    int temp = Functions.weekdays(start.getTime(), days);
    temp = temp - (2 * temp);

    start.add(start.DAY_OF_MONTH, temp);

The calendar was using the same instance. Cloning the calendar solved the issue as it created two separate entities.

Upvotes: 1

Related Questions