views:

1294

answers:

5

I want a nice way to get the current unix timestamp from a java Date object, this is my solution:

public class Date extends java.util.Date {

    public int getUnixTimeStamp() {
        int unixtimestamp = (int) (this.getTime() * .001);
        return unixtimestamp;
    }
}

That works fine, but the problem is when I try to cast a java Date object to my custom date class, i.e:

Calendar foo = Calendar.getInstance();
foo.set(0, 0, 0, 12, 30);
myapp.Date foo2 = (myapp.Date)foo.getTime();

This generates: Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to myapp.Date

I understand why this exception is made but is there any way to cast a superclass to a subclass? If not, how would you implement the unixtimestamp method? I use it quite often in my application.

+3  A: 

You can't cast a superclass in a subclass because the subclass may have a bigger interface than the superclass means the subclass can have functions like getUnixTimeStamp() that the superclass doesn't have. In your example that would mean you trying to call getUnixTimeStamp on a java.util.Date.

You can use a Delegate or Composition instead of inheritance here.

That means you have a Class

public class Date {

    private java.util.date date;

    public Date(java.util.Date date) {
        this.date = date
    }

    public int getUnixTimeStamp() {
        int unixtimestamp = (int) ((this.date.getTime()) * .001);
        return unixtimestamp;
    }

}

In this way you don't cast the date into your date you create a class arround the java.util.date.

If you use only this function it could be an easier solution to just create a static util function getUnixTime(Date date) that returns the changed date.

Janusz
A: 

Why do you need to make this class extend java.util.Date at all? Make a static function that takes a Date and returns the unix timestamp of that date.

patros
+2  A: 

If you're keen on having your subclass, implement a constructor in your Date class taking a java.util.Date foo and in it call super with foo.getTime(); then instead of casting you just call Date(foo) to instantiate your subclass.

Alex Martelli
A: 

As already mentioned you could implement it by letting the constructor of the class take the time as an input. Something like this:

public class Date {

long unixtimestamp;

public Date(long time) {
    unixtimestamp = (long) (time * .001);
}

public long getUnixTimeStamp() {
    return unixtimestamp;
}

}

Another option is just to create a static method which converts it. It depends on whether you are planning on adding other similar features to the class or not. If not then a static-method is probably better.

Yrlec
A: 

No, you can't cast a type to a more derived type if the reference doesn't point to an instance of the derived type.

The Date being returned by Calendar.getTime() isn't one of your Date objects, and it doesn't have the additional attributes and behaviours those objects do.

You could modify your Date class to use composition instead of inheritance, e.g.

class Date {

    private java.util.Date date;

    public Date( java.util.Date date ) {
        this.date = date;
    }

    public int getUnixTimestamp() {
        return (int)( date.getTime() * .001 );
    }

}
Rob