1
votes

I am looking to display the date by using the calendar object.

public abstract class Employee implements EmployeeInfo {

protected String firstName;
protected String lastName;
protected String idNumber;
Calendar birthday = Calendar.getInstance();
protected char gender;

public Employee()
{
    firstName = "";
    lastName = "";
    idNumber = "";
    gender = ' ';
    birthday.set(Calendar.MONTH, 0);
    birthday.set(Calendar.DAY_OF_MONTH, 00);
    birthday.set(Calendar.YEAR, 0000);
}

public Employee(String first, String last, String id, char gen, int month, int day, int year)
{
    firstName = first;
    lastName = last;
    idNumber = id;
    gender = gen;
    birthday.set(Calendar.MONTH, month);
    birthday.set(Calendar.DAY_OF_MONTH, day);
    birthday.set(Calendar.YEAR, year);
}

public Calendar getBirthday() {

    return birthday;
}

public void setBirthday(int month, int day, int year, Calendar birthday) throws ParseException {
    birthday = Calendar.getInstance();
    birthday.set(Calendar.MONTH, month);
    birthday.set(Calendar.DAY_OF_MONTH, day);
    birthday.set(Calendar.YEAR, year);
    SimpleDateFormat formatted = new SimpleDateFormat("MM/dd/yyyy");
    String date = month + "/" + day + "/" + year;
    Date birth = formatted.parse(date);
    birthday.setTime(birth);
    this.birthday = birthday;
}

public String toSring()
{
    return "ID Employee Number: " + idNumber + "\n" + "Employee name: " + firstName + " "
            + lastName + "\n" + "Birth date: " + birthday + "\n";
}

public abstract double getMonthlyEarning();

public class Staff extends Employee {
protected double hourlyRate;

public Staff()
{
    super();
    hourlyRate = 0.0;
}

public Staff(String first, String last, String ID, char gen1, int month, int day, int year, double rate)
{
    super(first, last, ID, gen1, month, day, year);
    hourlyRate = rate;
}

}

…and…

public class Test {

public static void main(String[] args) {

    Employee[] employees = new Employee[2];
    employees[0] = new Staff("Minh", "Vu", "123", 'M', 3,06,1997, 50.00);
    employees[1] = new Staff("Mike", "Nguyen", "456", 'M', 5,18,1977, 65.00);

    for(Employee member : employees)
    {
        System.out.println(member);
        System.out.println("------------------------------------------");
    }
}
}

The problem I am facing is why the birth date in the following output gives me an unknown, ridiculously long line:

ID Employee Number: 123

Employee name: Minh Vu

Birth date: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=1997,MONTH=3,WEEK_OF_YEAR=6,WEEK_OF_MONTH=2,DAY_OF_MONTH=6,DAY_OF_YEAR=37,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=2,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-28800000,DST_OFFSET=0]

Full Time

Monthly Salary: $8000.0


ID Employee Number: 456

Employee name: Mike Nguyen

Birth date: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=1977,MONTH=5,WEEK_OF_YEAR=6,WEEK_OF_MONTH=2,DAY_OF_MONTH=18,DAY_OF_YEAR=37,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=2,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-28800000,DST_OFFSET=0]

Full Time

Monthly Salary: $10400.0


Based on my analysis, I believe that I have to use create an object from the SimpleDateFormat class and put "MM/dd/yyyy" into the parameter. However, I have to parse the SimpleDateFormat object by creating a Date object. I would like to use the Calendar class to create my date object.

When I was debugging, I noticed that the display of the birth date was wrong; it printed everything within my birthday object. I'm not sure what to do. The help would be greatly appreciated. :)

3

3 Answers

2
votes

First of all you should use java.time not Calendar.

Second thing is you don't have to create your date twice (you are doing it in your setter).

And last but not least, you have to format date before you print it (in toString() method)

This is how your setter should look like:

public void setBirthday(int month, int day, int year) {
    this.birthday.set(Calendar.MONTH, month);
    this.birthday.set(Calendar.DAY_OF_MONTH, day);
    this.birthday.set(Calendar.YEAR, year);
}

or even better :

public void setBirthday(Calendar birthday) {
    this.birthday = birthday;
}

And this is how your toString() method should look like:

public String toString(){
    return "ID Employee Number: " + idNumber + "\n" + "Employee name: " + firstName + " "
            + lastName + "\n" + "Birth date: " + formatter.format(birthday) + "\n";
}

So you need to also add this to your code:

private final static SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
1
votes

tl;dr

LocalDate birthdate;
…
this.birthdate = LocalDate.of( 1955 , 3 , 17 ); // March 17, 1955. 

Details

The Answer by qwerty1423 is correct, and should be accepted. You are seeing the results of the toString method. If you insist on using Calendar, learn to generate a string in your desired format.

java.time

But you should not be using Calendar. It is one of the troublesome old date-time classes, now legacy, supplanted by the java.time classes. The legacy classes are an awful mess; avoid them. Also, the java.time classes use immutable objects and are therefore thread-safe.

The LocalDate class represents a date-only value without time-of-day and without time zone.

public abstract class Employee implements EmployeeInfo {

    protected String firstName;
    protected String lastName;
    protected String idNumber;
    LocalDate birthday;

    // Constructor
    public Employee() {
        this.firstName = "";
        this.lastName = "";
        this.idNumber = "";
        this.birthday = LocalDate.MIN ;  // Or some other arbitrary default value.
    }

    // Constructor
    public Employee( String first, String last, String id, int month, int day, int year )
    {
        this.firstName = first;
        this.lastName = last;
        this.idNumber = id;
        this.birthdate = LocalDate.of( year , month , day ) ;
    }

Call LocalDate::toString to generate a string in standard ISO 8601 format: YYYY-MM-DD. For other formats, search Stack Overflow for java.time.format.DateTimeFormatter class.

To localize, specify:

  • FormatStyle to determine how long or abbreviated should the string be.
  • Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

Example:

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = this.birthdate.format( f );

See this code run live at IdeOne.com.

birthdate.toString(): 1955-03-17

output: jeudi 17 mars 1955

Tips:

  • Always use decreasing order of significance when ordering your date-time parts: year, month, day, hour, minute, second. This is logical, easy to follow, and follows the style of the ISO 8601 standard for date-time values. So instead of passing int month, int day, int year as arguments, pass int year , int month , int dayOfMonth.

  • Better yet, just pass a LocalDate object rather than mere integer numbers. Doing so makes your code more self-documenting, ensures valid values, and provides for type safety.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.

Where to obtain the java.time classes?

Table of which java.time library to use with which version of Java or Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

0
votes

Because you are printing out the Calendar Object the variable birthday is.

You might want to implement your own class based on Calendar but with a toString method that actually does what you expect.