3

I'm having an issue with the Java Calendar add() functionality. The give or take is used to provide a roundabout date for dates to depart on a travel site.

end.add(Calendar.DATE, Integer.parseInt(giveOrTake));

The code is above and the test condition I'm using is to choose 29/07/2012 as the date and 3 days give or take. According to the documentation this should come out as 01/08/2012 but it comes out at 01/07/2012.

I've checked giveOrTake when it's passed to the method and it's fine so I have no idea what is going on. I can hardcode the giveOrTake value and still get the error.

Thomas Mitchell
  • 1,071
  • 2
  • 16
  • 29
  • 5
    Please post a short but complete program demonstrating the problem. (Oh, and ideally move to Joda Time instead - it's much more sensible.) – Jon Skeet Jun 20 '12 at 16:32
  • 1
    How are you generating the output? (in a java calendar august is month 7...) – Affe Jun 20 '12 at 16:32
  • Apologies for neglecting the question. Turns out it was an issue with SimpleDateFormat using 'mm' instead of 'MM' – Thomas Mitchell Jun 22 '12 at 11:05

3 Answers3

5

Works for me:

import java.util.*;

public class Test {
    public static void main (String []args) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(2012, Calendar.JULY, 29);
        calendar.add(Calendar.DATE, 3);
        System.out.println(calendar.getTime()); // August 1st
    }
}

My guess is that you've got the month wrong before calling add - note how my call to set above uses 6 as the month, because the call uses 0-based month numbers.

Note that as per my comment on the question, you'd be much better off moving to Joda Time if you can...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • month zero based is pretty misleading imo – keuleJ Jun 20 '12 at 16:58
  • @keuleJ: Absolutely. Just one of the many reasons to use Joda. – Jon Skeet Jun 20 '12 at 16:59
  • @JonSkeet you can use the `Calendar.JUNE` etc constants to avoid the 0-based issue. – Dandre Allison Dec 28 '12 at 01:33
  • @DandreAllison: That only helps in the *very* specific situation where you have a month number that you know at compile time. It doesn't help when you've got it as an integer variable from another system, for example. – Jon Skeet Dec 28 '12 at 08:50
  • @JonSkeet I can't speak for where the number originates, but your answer has a hard coded integer "6", and in that case it's preferable to use the constant. Otherwise you are dealing with implementing an Adapter that converts between a date from another system to a `Calendar` object in Java. In which case it is wise to check the documentation to understand both systems to understand what you have to change to convert between them. It would be easier to make that Adapter if they represented them the same, but subtracting one isn't awful. – Dandre Allison Dec 28 '12 at 16:42
  • @DandreAllison: I'm fine with using a constant here, but claiming that using the constant avoids the 0-based issue is an overstatement - it's still an issue. – Jon Skeet Dec 28 '12 at 16:49
  • @DandreAllison: Note that your *suggested* edit before used the wrong constant - it was specifying Calendar.JUNE instead of Calendar.JULY. I've edited the answer with the right constant. – Jon Skeet Dec 28 '12 at 16:50
  • @JonSkeet thanks for fixing the edit, that was just a mistake in my counting, I'm not arguing that Java does dates correctly, as I don't think it does actually. But I'm also not overstating it. Instead of trying to put in/take out a month directly. If you put in months with the constants and take them out with formatting and the likes, then you shove the fact that the months are stored 0-based under the rug. However, anytime you're dealing with Adapting between objects it requires an understanding of how those objects store things. – Dandre Allison Dec 28 '12 at 17:57
  • @DandreAllison: My point is that your comment suggested that by using constants, it becomes a non-issue - and that's just not true, IMO. It's a pain all over the place. Yet another area where Joda Time wins. – Jon Skeet Dec 28 '12 at 18:30
  • @JonSkeet, I will try to end here, but if you check my comment says "avoid the 0-based issue", which means it is an issue. But if you don't use "magic numbers" in setting the month, the fact that July is `6` instead of `7`, internally, is transparent. It's a concern of API not implementation. It doesn't strictly matter if the months were internally stored 3-based (for some imaginary optimization). And clearly the `Calendar` API is flawed, because this discussion exists in the first place. Example: `set(...)` could be 1-based even if it just subtracted 1 to store the months internally. – Dandre Allison Dec 28 '12 at 18:55
  • 1
    @DandreAllison: Yes, it's an API flaw. I don't think the month numbers which *everyone dealing with Gregorian calendars in real life* associates with those months a "magic number" really. I completely agree that this is an API issue rather than implementation though. – Jon Skeet Dec 28 '12 at 19:10
0

You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.

Also, you are using a date-time object to represent a date-only value, a misfit.

Using java.time

The LocalDate class represents a date-only value without time-of-day and without time zone.

LocalDate ld = LocalDate.of( 2012 , 7 , 29 ) ;
LocalDate threeDaysLater = ld.plusDays( 3 );

ld.toString(): 2012-07-29

threeDaysLater.toString(): 2012-08-01

See code run live in IdeOne.com.


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.

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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
-1

It was an issue with the date format. It was set as yyyymmdd when it should have been 'yyyyMMdd'.

Thomas Mitchell
  • 1,071
  • 2
  • 16
  • 29
  • 3
    This is what happens when you don't give enough information in the question. There's no way anyone could have helped you based on just that information - whereas if you'd provided a program which actually demonstrated the problem, it would have been spotted really quickly. – Jon Skeet Dec 28 '12 at 16:49