Полное раскрытие информации, это домашнее задание, но только очень небольшая часть задания, и я не могу понять, почему она не работает. Вот текст задания:

Создайте класс CollegeStudent. Этот класс будет содержать поля данных, которые содержат имя, фамилию, дату зачисления и предполагаемую дату окончания студента с использованием класса GregorianCalendar для каждой даты. Предоставьте методы get () и set () для каждого поля. Также предоставьте конструктор, который требует имени и фамилии и даты зачисления, и устанавливает дату окончания проекта ровно через четыре года после зачисления. Сохраните класс как CollegeStudent.java.

Создайте интерактивное приложение, которое запрашивает у пользователя данные для двух объектов CollegeStudent. Запросите у пользователя имя, фамилию, месяц зачисления, день зачисления и год зачисления для каждого CollegeStudent, а затем создайте экземпляры объектов. Отобразите все значения, включая предполагаемые даты выпуска. Сохраните приложение как TestCollegeStudent.java

Я смог сделать все, что он просил, за исключением того, что когда я пытался вычислить дату окончания, это также добавляет 4 года к значению даты зачисления. Вот мой класс CollegeStudent:

import java.util.GregorianCalendar;

public class CollegeStudent {

    String firstName;
    String lastName;
    GregorianCalendar enrollmentDate;
    GregorianCalendar graduationDate;
    
    
    // Constructor requiring first name, last name, and enrollment date
    public CollegeStudent(String first, String last, GregorianCalendar enrollment) {
        firstName = first;
        lastName = last;
        enrollmentDate = enrollment;
        
        // Set graduationDate to enrollmentDate, then add 4 years
        graduationDate = enrollment;
        graduationDate.add(GregorianCalendar.YEAR, 4);
    }
    // Get and Set firstName
    public void setFirstName(String first) {
        firstName = first;
    }
    public String getFirstName() {
        return firstName;
    }
    
    // Get and Set lastName
    public void setLastName(String last) {
        lastName = last;
    }
    public String getLastName() {
        return lastName;
    }
    
    // Get and Set enrollmentDate
    public void setEnrollmentDate(GregorianCalendar enrollment) {
        enrollmentDate = enrollment;
    }
    public GregorianCalendar getEnrollmentDate(){
        return enrollmentDate;
    }
    
    // Get and Set graduationDate
    public void setGraduationDate(GregorianCalendar graduation) {
        graduationDate = graduation;
    }
    public GregorianCalendar getGraduationDate() {
        return graduationDate;
    }

}

Мой TestCollegeStudent.java отображает как enrollmentDate, так и GraduationDate, и они оба показывают одну и ту же дату через 4 года после начальной enrollmentDate, введенной пользователем. Если я удалю строку, в которой я добавил 4 года к градации, они обе будут отображаться как начальная дата регистрации. Мне кажется, что мне не хватает очень простой синтаксической проблемы, но я не смог понять, что это такое.

1
Wes Hampton 16 Янв 2021 в 18:06

3 ответа

В этой теме уже есть хороший ответ. Я добавляю свой вклад. Основной источник проблемы - это строка, где окончание даты относится к зачислению.

graduationDate = enrollment

Вы также можете попробовать это:

// Set graduationDate to enrollmentDate, then add 4 years
graduationDate = new GregorianCalendar(); // New object
graduationDate.setTime(enrollmentDate.getTime()); // Update time
graduationDate.add(GregorianCalendar.YEAR, 4); // add years
1
silentsudo 16 Янв 2021 в 15:51

Проблема в том, что когда вы делаете это, graduationDate = enrollment GraduationDate теперь указывает на объект регистрации, и каждое изменение, которое вы вносите в любой из этих объектов, будет отражаться на другом, поскольку они являются одним и тем же объектом.

На самом деле вы хотите создать новый календарь на основе другого календаря, который должен быть graduationDate = (GregorianCalendar)enrollment.clone();

1
Bruno Neves 16 Янв 2021 в 17:19

Java.time

Для вашего задания это, вероятно, не пойдет, но всем остальным следует использовать java.time, современный API даты и времени Java, для работы с датами. И! С java.time практически невозможно допустить ошибку, о которой вы спрашиваете.

    LocalDate enrollmentDate = LocalDate.of(2021, Month.JANUARY, 4);
    LocalDate graduationDate = enrollmentDate.plusYears(4);
    
    System.out.format("Enrolled: %s. Projected graduation: %s.%n", enrollmentDate, graduationDate);

Выход:

Поступил: 04.01.2021. Планируемый выпуск: 04.01.2025.

Выход на границу требований

Если вы хотите научить своего учителя, как это должно быть сделано, но при этом сохраняете требование, чтобы поля имели тип GregorianCalendar… (1) я не могу сказать, рекомендуется ли это в вашей школе. (2) Это будет компромисс, то есть не идеальное решение, с преимуществами java.time и недостатком смешанных API и ненужных преобразований. Поехали:

public class CollegeStudent {

    String firstName;
    String lastName;
    GregorianCalendar enrollmentDate;
    GregorianCalendar graduationDate;
    
    // Constructor requiring first name, last name, and enrollment date
    public CollegeStudent(String first, String last,
            int enrollmentYear, int enrollmentMonth, int enrollmentDay) {
        firstName = first;
        lastName = last;
        ZonedDateTime enrollmentZdt
                = LocalDate.of(enrollmentYear, enrollmentMonth, enrollmentDay)
                        .atStartOfDay(ZoneId.systemDefault());
        enrollmentDate = GregorianCalendar.from(enrollmentZdt);
        
        // Set graduationDate to enrollmentDate, then add 4 years
        ZonedDateTime graduationZdt = enrollmentZdt.plusYears(4);
        graduationDate = GregorianCalendar.from(graduationZdt);
    }
    
    // Getters and setters …
}

Чтобы попробовать:

    CollegeStudent student = new CollegeStudent("Wes", "Hampton", 2021, 1, 16);
    System.out.println("Enrolled:      " + student.getEnrollmentDate().toZonedDateTime());
    System.out.println("Will graduate: " + student.getGraduationDate().toZonedDateTime());

Вывод в моем часовом поясе:

Enrolled:      2021-01-16T00:00+01:00[Europe/Copenhagen]
Will graduate: 2025-01-16T00:00+01:00[Europe/Copenhagen]

Ссылка на сайт

Это будет хорошим чтением для вашего учителя.

Обучающее руководство по Oracle: дата и время, объясняющее, как использовать java.time.

0
Ole V.V. 16 Янв 2021 в 17:03
65751080