Java DateTime extension class

Java class to extend java.util.Date class to add some methods given in c# like addSeconds, addMinutes, addDays, addYears etc. This are really helpful.

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

// TODO: Auto-generated Javadoc
/**
 * The Class DateTime.
 */
public class DateTime extends Date{

        /** The Constant serialVersionUID. */
        private static final long serialVersionUID = 5298959255088340222L;
        
        /** The calendar. */
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
         /** The Constant DaysToMonth365. */
        private static final int[] DaysToMonth365 = {
         0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
     
     /** The Constant DaysToMonth366. */
     private static final int[] DaysToMonth366 = {
         0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};

        
    /** The Constant MillisPerSecond. */
        private static final int MillisPerSecond = 1000;
    
    /** The Constant MillisPerMinute. */
    private static final int MillisPerMinute = MillisPerSecond * 60;
    
    /** The Constant MillisPerHour. */
    private static final int MillisPerHour = MillisPerMinute * 60;
    
    /** The Constant MillisPerDay. */
    private static final int MillisPerDay = MillisPerHour * 24;

   
    /** The Constant DaysPerYear. */
    private static final int DaysPerYear = 365;
  
    /** The Constant DaysPer4Years. */
    private static final int DaysPer4Years = DaysPerYear * 4 + 1;
   
    /** The Constant DaysPer100Years. */
    private static final int DaysPer100Years = DaysPer4Years * 25 - 1;
   
    /** The Constant DaysPer400Years. */
    private static final int DaysPer400Years = DaysPer100Years * 4 + 1;
  
    /** The Constant DaysTo10000. */
    private static final int DaysTo10000 = DaysPer400Years * 25 - 366;
    
    /** The Constant MaxMillis. */
    private  static final long MaxMillis = (long)DaysTo10000 * MillisPerDay;
    
    /** The Constant DatePartYear. */
    private static final int DatePartYear = 0;
    
    /** The Constant DatePartDayOfYear. */
    private static final int DatePartDayOfYear = 1;
    
    /** The Constant DatePartMonth. */
    private static final int DatePartMonth = 2;
    
    /** The Constant DatePartDay. */
    private static final int DatePartDay = 3;
        
        /**
     * Date to milli.
     *
     * @param year the year
     * @param month the month
     * @param day the day
     * @return the long
     * @throws Exception the exception
     */
    private static long DateToMilli(int year, int month, int day) throws Exception {
        if (year >= 1 && year <= 9999 && month >= 1 && month <= 12) {
            int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
            if (day >= 1 && day <= days[month] - days[month - 1]) {
                int y = year - 1;
                int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
                return n * MillisPerDay;
            }
        }
        throw new Exception("invalid argument");
    }
        
        /**
     * Days in month.
     *
     * @param year the year
     * @param month the month
     * @return the int
     * @throws Exception the exception
     */
    public static int DaysInMonth(int year, int month) throws Exception {
        if (month < 1 || month > 12) throw new Exception("invalid argument");
        // IsLeapYear checks the year argument
        int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
        return days[month] - days[month - 1];
    }

    

        /**
     * Checks if is leap year.
     *
     * @param year the year
     * @return true, if successful
     * @throws Exception the exception
     */
    public static boolean IsLeapYear(int year) throws Exception {
        if (year < 1 || year > 9999) {
                throw new Exception("invalid argument");
        }
        return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
    }


    /**
         * Instantiates a new date time.
         */
        public DateTime() {
                super();
                // TODO Auto-generated constructor stub
        }
    
    /**
         * Instantiates a new date time.
         *
         * @param time the time
         */
        public DateTime(long time) {
                super(time);
        }

    /**
         * Adds the days.
         *
         * @param value the value
         * @return the date time
         * @throws Exception the exception
         */
        public DateTime addDays(double value) throws Exception{
                return new DateTime(this.getTime()+getMilliSec(value, MillisPerDay));
    }

    /**
     * Adds the hours.
     *
     * @param value the value
     * @return the date time
     * @throws Exception the exception
     */
    public DateTime addHours(double value) throws Exception{
        return new DateTime(this.getTime()+getMilliSec(value, MillisPerHour));
    }

    /**
     * Adds the milliseconds.
     *
     * @param value the value
     * @return the date time
     */
    public DateTime addMilliseconds(double value){
        return new DateTime(this.getTime()+(long)value);
    }

    /**
     * Adds the minutes.
     *
     * @param value the value
     * @return the date time
     * @throws Exception the exception
     */
    public DateTime addMinutes(double value) throws Exception{
        return new DateTime(this.getTime()+getMilliSec(value, MillisPerMinute));
    }


    /**
     * Adds the months.
     *
     * @param months the months
     * @return the date time
     * @throws Exception the exception
     */
    public DateTime addMonths(int months) throws Exception{
         if (months < -120000 || months > 120000) throw new Exception("Invalid Argument");
         int y = getDatePart(DatePartYear);
         int m = getDatePart(DatePartMonth);
         int d = getDatePart(DatePartDay);
         int i = m - 1 + months;
         if (i >= 0) {
             m = i % 12 + 1;
             y = y + i / 12;
         }
         else {
             m = 12 + (i + 1) % 12;
             y = y + (i - 11) / 12;
         }
         if (y < 1 || y > 9999) {
                 throw new Exception("Invalid Argument");
         }
             int days = DaysInMonth(y, m);
             if (d > days) d = days;
             return new DateTime((long)(DateToMilli(y, m, d) + this.getTime() % MillisPerDay) );
    }
    
 /**
     * Adds the seconds.
     *
     * @param value the value
     * @return the date time
     * @throws Exception the exception
     */
    public DateTime addSeconds(double value) throws Exception{
        return new DateTime(this.getTime()+getMilliSec(value, MillisPerSecond));
    }
    
    /**
     * Adds the years.
     *
     * @param value the value
     * @return the date time
     * @throws Exception the exception
     */
    public DateTime addYears(int value) throws Exception{
        return addMonths(value * 12);
    }
    
    // Returns a given date part of this DateTime. This method is used
    // to compute the year, day-of-year, month, or day part.
    /**
  * Gets the date part.
  *
  * @param part the part
  * @return the int
  */
 private int getDatePart(int part) {
        
        // n = number of days since 1/1/0001
        int n = (int)(this.getTime() / MillisPerDay);
        // y400 = number of whole 400-year periods since 1/1/0001
        int y400 = n / DaysPer400Years;
        // n = day number within 400-year period
        n -= y400 * DaysPer400Years;
        // y100 = number of whole 100-year periods within 400-year period
        int y100 = n / DaysPer100Years;
        // Last 100-year period has an extra day, so decrement result if 4
        if (y100 == 4) y100 = 3;
        // n = day number within 100-year period
        n -= y100 * DaysPer100Years;
        // y4 = number of whole 4-year periods within 100-year period
        int y4 = n / DaysPer4Years;
        // n = day number within 4-year period
        n -= y4 * DaysPer4Years;
        // y1 = number of whole years within 4-year period
        int y1 = n / DaysPerYear;
        // Last year has an extra day, so decrement result if 4
        if (y1 == 4) y1 = 3;
        // If year was requested, compute and return it
        if (part == DatePartYear) {
            return y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1;
        }
        // n = day number within year
        n -= y1 * DaysPerYear;
        // If day-of-year was requested, return it
        if (part == DatePartDayOfYear) return n + 1;
        // Leap year calculation looks different from IsLeapYear since y1, y4,
        // and y100 are relative to year 1, not year 0
        boolean leapYear = y1 == 3 && (y4 != 24 || y100 == 3);
        int[] days = leapYear? DaysToMonth366: DaysToMonth365;
        // All months have less than 32 days, so n >> 5 is a good conservative
        // estimate for the month
        int m = n >> 5 + 1;
        // m = 1-based month number
        while (n >= days[m]) m++;
        // If month was requested, return it
        if (part == DatePartMonth) return m;
        // Return 1-based day-of-month
        return n - days[m - 1] + 1;
    }
    
    /**
     * Gets the milli sec.
     *
     * @param value the value
     * @param scale the scale
     * @return the milli sec
     * @throws Exception the exception
     */
    private long getMilliSec(double value, int scale) throws Exception {
        long millis = (long)(value * scale + (value >= 0? 0.5: -0.5));
        if (millis <= -MaxMillis || millis >= MaxMillis)
            throw new Exception("Invalid argument");
        return millis;
    }

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args){
        DateTime dt = new DateTime();
        try {
                System.out.println(dt);
                System.out.println(dt.addSeconds(3));
                System.out.println(dt.addMinutes(50));
                System.out.println(dt.addHours(3));
                        System.out.println(dt.addDays(3.0));
                        System.out.println(dt.addMonths(2));
                        System.out.println(dt.addYears(4));
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
    }
   
}