views:

71

answers:

3

I have a simple task. There are two classes : Ticket and Date. Ticket contains event, event place and event date which is a Date object. I also need to provide a move() method for Date object, so I used Calendar and Calendar's add(). Everything looks fine apart of the output. I constantly get the same date for all Event objects. The code :

Ticket class :

public class Ticket {

private String what;
private String where;
private Date when;

public Ticket(String s1, String s2, Data d){
    this.what = s1;
    this.where = s2;
    this.when = d;
}

public Date giveDate(){
    System.out.println("when in giveDate() "+this.when);
    return this.when;
}

public String toString(){
    return "what: "+this.what+"\n"+"where: "+this.where+"\n"+"when: "+this.when;
}

}

Date class:

import java.util.Calendar;
import java.util.GregorianCalendar;

public class Date {

public int day;
public int month;
public int year;

public Date(int x, int y, int z){
    this.day = x;
    this.month = y;
    this.year = z;
}

public Date move(int p){

    Calendar gc = new GregorianCalendar(this.year, this.month, this.day);
    gc.add(Calendar.DAY_OF_YEAR, p);

    this.year = gc.get(Calendar.YEAR);
    this.day = gc.get(Calendar.DAY_OF_MONTH);
    this.month = gc.get(Calendar.MONTH);

    return this;
}

@Override
public String toString(){
    return this.day+","+this.month+","+this.year;
}

}

Main for testing :

 Date date1=new Date(30,4,2002);
 Ticket event1=new Ticket("Peter Gabriel's gig",
                      "London",date1
                     );
 System.out.println(event1);

 Ticket event2=new Ticket("Diana Kroll's concert",
                      "Glasgow",date1
                     );
 System.out.println(event2);

 Date date2=event2.giveDate();

 date2.move(30);
 Ticket event3=new Ticket("X's B-day",
                      "some place",date2
                     );
 System.out.println(event3);

 System.out.println(event1);
 System.out.println(event2);
 System.out.println(event3);

And here's my output. After creating Events they have proper date, but at the end thy all get the same date dunno why :/

what: Peter Gabriel's gig
where: London
when: 30,4,2002
what: Diana Krall's concert
where: Glasgow
when: 6,12,2004
what: X's B-day
where: some place
when: 5,1,2005
what: Peter Gabriel's gig
where: London
when: 5,1,2005
what: Diana Krall's concert
where: Glasgow
when: 5,1,2005
what: X's B-day
where: some place
when: 5,1,2005
+4  A: 

the YEAR, DAY_OF_MONTH, etc. constants of Calendar are integer values for internal use in the Calendar. They denote the field in the calendar, not the value.

You obtain the value this way:

gc.get(Calendar.YEAR); (or gc.get(gc.YEAR), but better access it statically)

As per your update, first get rid of the Date(int, int, int) constructor. It has been deprecated:

Date(int year, int month, int date)
Deprecated. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date) or GregorianCalendar(year + 1900, month, date).

Bozho
I somehow missed that, thanks !
owca
+4  A: 

Bozho has given the correct answer as to why you're seeing that particular behaviour. However, this is symptomatic of a bigger problem: using java.util.Calendar in the first place. I have two suggestions to make:

  • Don't write a class called Date when readers may well assume you mean java.util.Date
  • Don't use java.util.{Date,Calendar} - use Joda Time instead. It's a much better API which makes it harder to make this sort of mistake. Dates and times are hard enough without having to fight against a rubbish API.
Jon Skeet
I'll check that out
owca
while I agree that `Date` and `Calendar` are not designed well, and that JodaTime is preferable, I haven't had any problems with `Calendar` _once I got used to it_ ;)
Bozho
A: 

Okay so solution was the following :

in Date

public Date( Date d){
    this.day = d.day;
    this.month = d.month;
    this.year = d.year;
}

and in Ticket:

public Ticket(String s1, String s2, Data d){
    this.what = s1;
    this.where = s2;
    this.when = new Date(d);
}
owca