Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 6 of 6

Thread: Building your own Date class.

  1. #1
    Member
    Join Date
    Dec 2009
    Location
    UK
    Posts
    58
    My Mood
    Sleepy
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Thumbs up Building your own Date class.

    As this is the most interesting and useful piece of Java code I've written during my two-years of study, I thought I'd post the code. There are some anomolies in the class, for instance, because it only asks for dates in DD/MM/YY format, there isn't a way of determining the year prefix. Also, it'll only work with dates after 01/03/1900 as it works out the day from the numeric date entered. Therefore, these anomolies will need fixing *if* you are using it for dates before this, but not before 01/01/1900. If you need it to return dates before this, you'll need to build your own look-up table for the days of week from 01/01/1800 - 31/12/1899. For the purposes of the assignment, I was using it for a student record system (simplified database), so it's extermely unlikely that I'd be entering students that were over 110 years old.

    Note: If you know what you're doing, you can change it to read and set dates as MM/DD/YY or even YY/MM/DD, whatever you like.

    Anyway, here's the Java code including comments:

    import java.lang.Math;
    public class Date
    {
    /* Let's do this thing properly and set up a look-up table
     * which will be used in to return month as string bit at
     * the end. We'll store the months in an array of type
     * String and as computers count from zero, our first entry
     * will be monthToString[0], returning January. */
    public static String [] monthToString=
      {
        "Jan", "Feb", "Mar", "Apr", "May",
        "Jun", "Jul", "Aug", "Sep", "Oct",
        "Nov", "Dec"
      };
      /* I'm going to use a look-up table for the number of days
       * in each month as follows: */
    public static int [] noOfDays=
      {
        31,28,31,30,31,30,31,31,30,31,30,31
      };
      /* I'm going to attempt to calculate the day entered based
       * on the numeric date entered (oh no! Maths :-( !!!) so, I
       * need a look-up table for that... Extra day added for
       * leap-years (ie, anything after a legal leap-year has an
       * off-set), this first table is for the 20th Century, ie,
       * a 19 perfix on the year: */
    public static String [] daysOfWeek20th=
      {
        "Mon","Tue","Wed","Thu",
        "Fri","Sat","Sun","Mon"
      };
    /* And this is the corrosponding look-up table for the 21st
     * century boy! */
    public static String [] daysOfWeek21st=
      {
        "Sun","Mon","Tue","Wed","Thu",
        "Fri","Sat","Sun"
      };
    /* Here are the month codes! */
    public static int [] monthCodes=
      {
        6,2,2,5,0,3,5,1,4,6,2,4
      };
    /* And we need to declare some variables for working out the day: */
    public static float a, x, y, z;
    public static int v, c;
    /* Here is a variable of type char that'll force a line-feed
     * when using System.out.print ("text"+ln+"more text"); */
    public static char ln=13;
    /* The following variable of type String is also used in
     * the sub-routine that returns the month as string */
    public static String mon="";
    /* Okay, here's some variables of type integer (whole numbers)
     * which will be used in the constructor thingy */
    private int day, month, year;
     
    /* Error catching for type date in DD/MM/YY format to
     * check for legal dates, assuming a 19xx or 20xx prefix*/
    public Date (int dd, int mm, int yy)
      {
        day=dd; month=mm; year=yy;
        if (month<1 || month>12)
        {
          System.out.println("?Month not valid error"+ln+"Reset to default value.");
          month=01;
        }
        if (day<1 || day>31)
        {
          System.out.println("?Day not valid error"+ln+"Reset to default value.");
          day=01;
        }
        /* As there is no easy way to store a leap-year in a look-up table
         * I'm going to check for the 29th February first and validate it
         * later. Of course, this is advanced programming, isn't it? */
        if (day>29 && month==2)
        {
          System.out.println("?Day not valid error"+ln+"Except for leap-years, Feburary has only 28 days.");
          day=01;
        }
        /* Now, let's check to see if a legal leap-year has been entered
         * by the user, shall we? Oh, we need to do some maths. */
        if (day==29 && month==2 && ((year-2000)%4!=0))
        {
          System.out.println("?Date not valid error"+ln+"Not a leap-year.");
          day=28;
        }
        /* So, we've tested for a valid leap-year, the only thing that could
         * trip up our array above for the numbers of days in each month. */
        if (day<1 || day>noOfDays[month-1] && month!=2)
        {
          System.out.println("?Date not valid error"+ln+"Not a legal date.");
          day=01;
        }
        /* That's a whole lot more efficient and advanced than having a
         * 'switch case' or a load of 'if' statements checking for each
         * condition, isn't it? Okay, I'd use a switch case if I thought
         * that the person maintaining the Java code wasn't very good and needed
         * it to be readable, but if you use comments correctly then you
         * don't necessarily need code to be more readable, should you? */
      }
     
      /* This will initialise the date and then we'll do some stuff wid it */
      public Date()
      {
      /* Because I've gone slightly over-board on the error checking,
       * I need to initialise the date to 1,1,0 (Day, Month, Year) otherwise
       * ?Day not valid error and ?Month not valid error is thrown back at
       * the user, at least on the command line interface (ie, DOS).
       * Still, you can't be too diligent! */
        this(1,1,0);
      }
      /* This takes a copy of the date. */
      public Date (Date other)
      {
        this (other.day, other.month, other.year);
      }
     
      /* This method will return the monthAsString, as suggested by its' name */
      public String monthAsString()
      {
      /* This is very efficient because it has in-built error checking
       * actually without testing for loads of conditions */
      if (month>0 && month<13)
      {
        mon=monthToString[month-1];
        return mon;
      }
      /* Just in case any errors have sneaked into validating the month,
       * It will return a Month not set message */
        else
          return "Month not set";
      }
      /* This compares one date to another to find out if it's earlier than or
       * not, if so, returning true. */
      public boolean earlierThan(Date other)
      {
        if(year<other.year)
        {
          return true;
        }
        else
          if (year==other.year && month<other.month)
          {
            return true;
          }
          else
            if (month==other.month && day<other.day)
            {
              return true;
            }
            else
               return false;
      }
      /* This compares dates, if equal then true, if not then false. */
     
      public boolean equals (Date other)
      {
        if (day==other.day && month==other.month && year==other.year)
        {
          return true;
        }
        else
          return false;
      }
     
      public String suffix()
      {
      /* Here is where a switch case is useful, in terms of returning a
       * date: because most days as numbers have a th suffix (ie, 4th),
       * we'll use a switch case for the exceptions to that rule. */
      switch(day)
      {
        case 1: return "st";
        case 2: return "nd";
        case 3: return "rd";
        case 21: return "st";
        case 22: return "nd";
        case 23: return "rd";
        case 31: return "st";
        default: return "th";
      }
    }
     
    public String dayFromDate()
    {
    /** This method will return the day of week based on a numeric
     * date entered after 1st March 1900, because 1900 isn't a
     * leap-year, whereas 2000 is (ie, leap-years ending 00 only
     * happen every 400 years). It's highly unlikely that a student
     * will be born before this date, so for our purposes, it works
     * fine.
     * The basic maths are to take the year and add a 25% to it ignoring
     * any decimal points (ie, 25% of 01 = 0.25, so we ignore the .25)
     * then we have the following month codes: Jan=6, Feb=2, Mar=2,
     * Apr=5, May=0, Jun=3, Jul=5, Aug=1, Sep=4, Oct=6, Nov=2, Dec=4
     * which is stored in a look-up table. We take the numberic day
     * and add it to our sum, (so, month+(abs(month/4))+monthCode+day)
     * We then need the absolute value of that and pass that to a
     * type int, and then take the remainder of that number when
     * devided by 7. If the answer is negative, we add 7 until it's
     * positive, then we check for leap-years, and minus 1 off the
     * answer if the month is January or February and return the
     * dayOfWeek according to the look-up table. Simple! */
    a=year+(Math.abs(year/4));
      // This takes the year and should add 25% to it.
    x=monthCodes[month-1];
      // This will pass the 'month code' to x for our mathematics
    y=day;
      // We need to know the date to do calculations with it.
    z=a+x+y;
      // This is used to work out the day
    a=Math.abs(z);
    c=Math.round(a);
    v=c%7;
    while(v<1)
    {
      v=v+7;
    }
    if ((year-2000)%4!=0)
    {
      return daysOfWeek20th[v];
    }
      else
        if ((year-2000)%4==0 && (month>0 && month<3))
        {
           return daysOfWeek20th[v-1];
        }
        else
          if ((year-2000)%4==0 && (month>2))
          {
            return daysOfWeek20th[v];
          }
          else
            return "Day unknown";
    }
     
    public String toString()
    {
    /* This is another attempt at error trapping, just in case
     * anything above has failled. */
    if(month!=0 || day!=0)
    {
      if(year<10)
      {
      /* A nested if statement to do some padding on years less than xx10 */
        return dayFromDate()+" "+day+suffix()+" of "+monthAsString()+" 0"+year;
      }
      else
        return dayFromDate()+" "+day+suffix()+" of "+monthAsString()+" "+year;
      }
      else
        return "Date not set";
    }
     
      public void copy(Date other)
      /* This is where the date is copied to, I think. */
      {
        day=other.day; month=other.month; year=other.year;
      }
    }

    Well, there is it... consider it a framework and make it better :-)

    Enjoy!

    Shaun.

  2. The Following 2 Users Say Thank You to ShaunB For This Useful Post:

    Emperor_Xyn (December 7th, 2011), JavaPF (October 23rd, 2011)


  3. #2
    Member
    Join Date
    Dec 2009
    Location
    UK
    Posts
    58
    My Mood
    Sleepy
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Building your own Date class.

    I forgot to say, here's simple date-test class. Change the numbers in the FOR/NEXT loop with the yr variable in it to work out dates from other years. I think it's set to 1900, but I'm sure you are all clever enough to work the code out to make it to years in the 2000s, eh?
    //import java.util.Scanner;
    public class DateTester
    {
           public static int dy=0, mn=1, yr=0, mnMax=0;
          // public static int birthDay=0, birthMonth=0, birthYear=0;
          public static Date firstDate=new Date ();
          public static Date lastDay=new Date ();
          public static int [] Days=
          {
            31,28,31,30,31,30,31,31,30,31,30,31
          };
          public static void main(String args[])
          {
          // Here's a loop to demonstrate the date class in action :-)
          for (yr=77;yr<79;yr++)
          {
            dy=1;
            for(mn=1;mn<13;mn++)
            {
            // This takes the maximum number of days and puts it
            // into a variable of type integer
            mnMax=Days[mn-1];
            // Let's make the first day and print it out
            Date firstDate=new Date (dy, mn, yr);
            System.out.println(testDate);
            // And let's do the same for the last day
            Date lastDay=new Date (mnMax, mn, yr);
            System.out.println(lastDay);
          }
        }
      }
    }

  4. #3
    Member
    Join Date
    Oct 2011
    Posts
    114
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Building your own Date class.

    Im trying to run this, just to check should the (testDate) in the first println statement be (firstDate)

    Im referring to the tester main class

  5. #4
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,318
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Building your own Date class.

    Its always nice to complete projects like this, so thanks for sharing that accomplishment along with the code! If you're looking for improvements, let me offer a few small suggestions regarding design, more general recommendations to learn from. For the first constructor, you might want to consider throwing an IllegalArgumentException rather than a warning via System.out - not always are System.out directly available, and throwing an exception overcomes this. Another suggestion would be to follow standard javadoc commenting (see How to Write Doc Comments for the Javadoc Tool ) which will allow you to have an API for the class (or library), facilitating use by others. Next, be careful when defining equals methods - the equals in your code does not override the Object.equals method, which can lead to confusion. Lastly, you might consider implementing a few interfaces - Comparable comes to mind to allow one to sort instance of the class - to even further enable use of the class.

    Edit: just realized this post is several months old, but better late than never I guess .

  6. The Following User Says Thank You to copeg For This Useful Post:

    JavaPF (October 23rd, 2011)

  7. #5
    Member
    Join Date
    Dec 2009
    Location
    UK
    Posts
    58
    My Mood
    Sleepy
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Smile Re: Building your own Date class.

    Quote Originally Posted by djl1990 View Post
    Im trying to run this, just to check should the (testDate) in the first println statement be (firstDate)

    Im referring to the tester main class
    Hi,

    I've moved onto the rather scary world of Visual C++ since changing educational institutions, amongst other languages, but I've just realised very recently that some of this might be depreciated (probably not in this case?). This is due to the College using a rather old JDK and run-time environment as well as old IDEs. Not much of my old Java code in the newest Netbeans seems to work very well, but something like JCreator Pro might like it.

    The example parameters may be changed as you wish, but yes I think the main has a typo. Change it for firstDate and see what happens.

    Regarding the printing the errors, these were simply for internal use only to tell me that there has been an illegal date. I doubt using exceptions would be useful in this context as it was for my eyes only. But yes, there are lots of improvements relevant to the code that should be considered. I deliberately left some anomolies in so that the solution wasn't perfect (see the comments). I'm not sure what is meant by the Object.equals method as that's how the University did it (that code isn't mine) in the framework, but thanks for pointing it out. Just to clarify, the course module was 'Advanced Programming', and I'm honestly only now realising how much of it was advanced since changing institutions (ie, not very much). Well, it worked and I passed, and that's all that matters.

    Many thanks for the replies.

    Shaun.
    Last edited by ShaunB; October 25th, 2011 at 07:43 AM.

  8. #6
    Member
    Join Date
    Dec 2009
    Location
    UK
    Posts
    58
    My Mood
    Sleepy
    Thanks
    2
    Thanked 3 Times in 2 Posts

    Default Re: Building your own Date class.

    Just a note for anyone who might be studying under a UK-based higher-educational institution in Manchester that isn't the University of Manchester. If you're studying the 'Advanced Programming' module that I did - unless the criteria for the assignment has changed - you might get more marks if you use switch case statements instead of the look-up tables that I've used. This makes the code easier to read and therefore more obvious that you have no errors.

    Here is what I mean:
    switch(month)
      {
        case 1: return "January";
        case 2: return "February";
        case 3: return "March";
        // Continue here until...
        case 12: return "December";
        default: return "Month not set";
      }
    Obviously, delete the monthToString array at the beginning, and look at the others, mixing the data in with each method. I'm not 100% sure about Java, but in ANSI C (??), I think it's advised to use the break statement after each case.

    Good luck :-)

    Shaun.

Similar Threads

  1. Date Of Birth Revision , Class please help
    By youssef22 in forum Object Oriented Programming
    Replies: 2
    Last Post: November 6th, 2010, 02:41 AM
  2. help building up GUI for poker game
    By Pencil in forum AWT / Java Swing
    Replies: 5
    Last Post: October 26th, 2010, 02:53 PM
  3. I'm having trouble with date and calendar class
    By kiph in forum What's Wrong With My Code?
    Replies: 1
    Last Post: April 7th, 2010, 02:56 AM
  4. Building a Menu List
    By websey in forum AWT / Java Swing
    Replies: 1
    Last Post: November 15th, 2009, 10:34 AM
  5. Replies: 3
    Last Post: May 8th, 2009, 01:27 PM