ArtsAutosBooksBusinessEducationEntertainmentFamilyFashionFoodGamesGenderHealthHolidaysHomeHubPagesPersonal FinancePetsPoliticsReligionSportsTechnologyTravel
  • »
  • Technology»
  • Computers & Software

[Part 8] Create your own Calendar (Date/Time) library from scratch using Java

Updated on April 7, 2015

Part 8 - Naming a day and adding days, months, or years to a given date

In Part 7, we created the methods to count the days, months, or years between two dates. We also created the methods to display them but what if we want to know if a given date falls on a Sunday or any other day of the week? What if we want to give a specific date and add the number of days, months, or years we want instead of giving a second date?

In this part, we will do just that. The methods that we are about to create are in the table below.

Method
Purpose
nameOfDay()
Checks which day of the week the date falls on.
addDays()
Adds days to a given date.
addMonths()
Adds months to a given date.
addYears()
Adds years to a given date.
Methods and their purpose.

Name of day

How do we find out if it's Monday, Wednesday, Saturday, or any other name of day? A better question is how do we instruct the computer how to find it out? We already know that we feed the code to the computer in the form of an algorithm or a set of instructions. This could be easy if every date has a corresponding name of day, for example, January 1 is forever on a Sunday regardless of what year it is but it's not.

To solve the problem, let's take a look on uncertainties or things that may change for whatever reason.


BMO is excited! I like BMO.
BMO is excited! I like BMO. | Source

Uncertain things


1. Changes every year.
We can't just assign for example, "Thursday" for March 26 because that is only true for March 26, 2015 and other dates. Last year, March 26 is "Wednesday".

2. Leap years.
Just when you thought that this follows a simple pattern of March 26, 2014 -> "Wednesday" --> March 26, 2015 -> "Thursday" and you made a confident guess that March 26, 2016 will fall on a "Friday", you were wrong because it falls on a "Saturday", ha! Since 2016 is a leap year, the extra day (February 29) pushed the day further.

3. Number of days.
The number of days each month are not all the same, there's 30, 31, 28, and 29. The total number of days for each year is also not always 365. On a leap year, it's 366.

Certain things

In order to formulate an algorithm, we must find a spot in the calendar that's permanent or never changes. It has always and will always be the way it is.


1. There are 7 days in a week, always.
While the number of days in a month and the total number of days in a year may change, the number of days in a week are always only just 7.

2. The are 7 name of days in a week, always.
Different dates may only fall on these seven names, there are no other names. These names are Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, and Saturday.


    public String nameOfDay(String date){
        String init01012015 = "Th";
        String nameOfDay = "";
        int daysBetween = countDaysBetween("01-JAN-2015", date);
        int mod = daysBetween % 7;

        switch (mod){
            case 0:
                nameOfDay = "Th";
                break;
            case 1:
                nameOfDay = "Fr";
                break;
            case 2:
                nameOfDay = "Sa";
                break;
            case 3:
                nameOfDay = "Su";
                break;
            case 4:
                nameOfDay = "Mo";
                break;
            case 5:
                nameOfDay = "Tu";
                break;
            case 6:
                nameOfDay = "We";
                break;
            default: //do nothing
                break;
        }

        return nameOfDay;
    }

Name of day

Now that we have identified the permanent spots in the calendar, we can now write our method. First we find an initial point or a date that we will start from. The later, the better but for this example, I will use the date January 1, 2015. This can be replaced as long as the value is changed depending on what day it falls on.

Line 2
We initialize the string variable "init01012015" with the value "Th". We declare the variable "nameOfDay", this will contain the value that will be returned by the nameOfDay() method later. We initialize the int variable "daysBetween" with the number of days between January 1, 2015 and the "date" that our method will receive.

Line 5
This is the part that gives a number between 0 to 6. The % operator or modulus is used to get the remainder of a division. The value of "daysBetween" or the number of days between January 1, 2015 and a given date is divided by 7 (the number of days in a week). The remainder is stored to the int variable "mod".

Line 7
The value of "mod" is used for the switch statement. In every cases, it checks if "mod" contains any value between 0 to 6 and uses that to decide what value will be assigned to the variable "nameOfDay".


How the nameOfDay() switch block works.
How the nameOfDay() switch block works.

Case 0

The name of day resets after 7 days. If it's Sunday today, after 7 days it will be Sunday again. Since we started with January 1, 2015 on this method and we declared that it falls on a Thursday, if the number of days between that and the given date is divisible by 7 or has no remainder, that date is declared to fall on Thursday as well.

Other cases

Consider the remainder as the distance from the initial position. Since Thursday is the initial position, any Thursday is of 0 distance from the initial position. If the distance is 1 (case 1) then it's one day after Thursday (Friday). If two (case 2), it's two days after Thursday (Saturday).

See the sample table below.

 
 
 
 
 
 
 
 
Distance (case)
0
1
2
3
4
5
6
Day
Thursday
Friday
Saturday
Sunday
Monday
Tuesday
Wednesday
Cases and their corresponding days.

You can now test the method by using the sample code below.

        System.out.println("January 1, 2015 falls on a " + myCalendar.nameOfDay("01-JAN-2015"));
        System.out.println("April 13, 2015 falls on a " + myCalendar.nameOfDay("13-APR-2015"));
        System.out.println("December 30, 2015 falls on a " + myCalendar.nameOfDay("30-DEC-2015"));

Take a look at the result below and try to compare it to your calendar.

Result for nameOfDay().
Result for nameOfDay().

Adding days to a given date

The addDays() method has two parameters; the date and the number of days that will be added to that date. We use the value of the "days" variable to specify how many times we will run the code inside the while loop. In the while loop, the value of the variable "date" is constantly replaced with the next date until the loop ends.

    public String addDays(String date, int days){
        while(days > 0){
            date = nextDate(date);
            days --;
        }

        return date;
    }

You can use the code below to test the addDays() method.

        System.out.println("90 days after October 27, 2013: " + myCalendar.addDays("27-OCT-2013", 90));
        System.out.println("365 days after February 26, 2015: " + myCalendar.addDays("26-FEB-2015", 365));
        System.out.println("365 days after February 26, 2016: " + myCalendar.addDays("26-FEB-2016", 365));

Why nextDate() instead of nextDay()?

You should get a result similar to the screenshot below. Notice the difference between adding 365 days to February 26, 2015 and February 26, 2016. Since we used nextDate() instead of nextDay(), it checked if the year is a leap year and based the computation on that. The same with the switching of months and years for October 27, 2013.

Result for addDays().
Result for addDays().

Adding months to a given date

Inside the while loop, we have an "if-else" statement. In both statements, we assign a new value to the variable "date" but only with a slight difference. If we reach the last month of the year (December) and the next month is January, we use nextYear(date) to set the "year" part of the date. The condition can be changed to check if the current month is December but I prefer checking if the next month is January since it gives me more awareness that the year should be replaced. If the next month is not January then we leave the year as it is.

    public String addMonths(String date, int months){
        while(months > 0){
            if (nextMonth(date).equals("JAN"))
                date = getDay(date) + "-" + nextMonth(date) + "-" + nextYear(date);
            else
                date = getDay(date) + "-" + nextMonth(date) + "-" + getYear(date);
            months --;
        }

        if (numOfDays(date) < getDay(date))
            date = date.replace(String.valueOf(getDay(date)), String.valueOf(numOfDays(date)));

        return date;
    }

Last day of the month

On line 10, we have another "if" statement. Since we cannot predict what the user will input or add months into, this checks if the total number of days of the month we got as a result is less than the day of the original date before we added the month(s).

Example

The initial month is "31-JAN-2015" and we want to add 1 month to that. Without the conditional statement on line 10, we will have the result "31-FEB-2015" and that would be invalid because there is no such thing. Since we have this conditional statement, the "day" part of the data adjusts to the maximum number of days the resulting month has, in this case 28 because 2015 is not a leap year. We get "28-FEB-2015" instead and that's a valid result.

The third line in the sample code below represents this case.

        System.out.println("4 months after October 27, 2013: " + myCalendar.addMonths("27-OCT-2013", 4));
        System.out.println("9 months after February 26, 2015: " + myCalendar.addMonths("26-FEB-2015", 9));
        System.out.println("2 months after December 31, 2016: " + myCalendar.addMonths("31-DEC-2016", 2));
Result for addMonths().
Result for addMonths().

Adding years to a given date

In terms of method definition, the addYears() method has very little difference with the addDays() method but since only the year needs to change, nextYear() is used instead of nextDate(). The value of the "years" variable is used to specify how many times the code inside the while loop will be executed. The code gets the next year and assign that value to the "year" variable. When the loop stops, the final value of the "year" variable is converted to string and concatenated to form a new value for "date".

    public String addYears(String date, int years){
        while(years > 0){
            date = getDay(date) + "-" + getMonth(date) + "-" + String.valueOf(nextYear(date));
            years --;
        }

        return date;
    }

After running the code below, you should get a result similar to the one in the image after the sample code.

        System.out.println("2 years after October 27, 2013: " + myCalendar.addMonths("27-OCT-2013", 2));
        System.out.println("1 year after February 26, 2015: " + myCalendar.addMonths("26-FEB-2015", 1));
        System.out.println("10 years after December 5, 2016: " + myCalendar.addMonths("5-DEC-2016", 10));
Result for addYears().
Result for addYears().

End of Part 8

We can now identify on which day of the week a specific date falls. We are no longer limited to counting or displaying the number of days between two dates, instead we can give only one date and add the number of days, months, and years we want.

Now that we can do all these, we can create and display an actual calendar now. Remember the calendar display on Part 6? That's what we're gonna do on the next part. I am not a fan of swing and thought it would be interesting and "old school" to do all these using text.

Fancy calendar out of mere boredom.
Fancy calendar out of mere boredom. | Source

Most of the codes can already be found in the repository on GitHub before they are discussed here.

Read Part 9

© 2015 Joann Mistica

Comments

    0 of 8192 characters used
    Post Comment

    No comments yet.