diff --git a/1ano/2semestre/poo/guides/POO-2022-aula06.pdf b/1ano/2semestre/poo/guides/POO-2022-aula06.pdf new file mode 100644 index 0000000..10d65a5 Binary files /dev/null and b/1ano/2semestre/poo/guides/POO-2022-aula06.pdf differ diff --git a/1ano/2semestre/poo/src/aula05/DateYMD.java b/1ano/2semestre/poo/src/aula05/DateYMD.java index 13c7f84..74392d0 100644 --- a/1ano/2semestre/poo/src/aula05/DateYMD.java +++ b/1ano/2semestre/poo/src/aula05/DateYMD.java @@ -71,7 +71,7 @@ public class DateYMD { } public String toString() { - return String.format("%04d-%02d-%02d", year, month, day); + return String.format("%04d-%02d-%02d", this.year, this.month, this.day); } static boolean validMonth(int month) { return month >= 1 && month <= 12; diff --git a/1ano/2semestre/poo/src/aula05/README.md b/1ano/2semestre/poo/src/aula05/README.md index ad99067..ef70d71 100755 --- a/1ano/2semestre/poo/src/aula05/README.md +++ b/1ano/2semestre/poo/src/aula05/README.md @@ -1,14 +1,16 @@ # Programação Orientada a Objetos ## Aula 05 -### Tópico principal da aula: Inheritance +### Tópico principal da aula: Classes * [Guião](https://github.com/TiagoRG/uaveiro-leci/tree/master/1ano/2semestre/poo/guides/POO-2022-aula05.pdf) * [Slides](https://github.com/TiagoRG/uaveiro-leci/tree/master/1ano/2semestre/poo/slides/POO_03_Classes.pdf) ### Exercise List -| Exercise Number | File Name | -|-----------------|----------------------------------------------------------------------------------------------------------------| -| 1 | [DateYMD.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula05/DateYMD.java) | +| Exercise Number | File Name | +|-----------------|------------------------------------------------------------------------------------------------------------------------| +| 1 | [DateYMD.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula05/DateYMD.java) | +| 2 | [Calendar.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula05/Calendar.java) | +| 3 | [AuctionDemo.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula05/AuctionDemo.java) | --- *Pode conter erros, caso encontre algum, crie um* [*ticket*](https://github.com/TiagoRG/uaveiro-leci/issues/new) diff --git a/1ano/2semestre/poo/src/aula06/Bolser.java b/1ano/2semestre/poo/src/aula06/Bolser.java new file mode 100644 index 0000000..77a08e4 --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/Bolser.java @@ -0,0 +1,43 @@ +package aula06; + +import utils.DateYMD; + +public class Bolser extends Student{ + private Professor supervisor; + private double monthlyAmount; + + public Bolser(String name, int cc, DateYMD birthDate, DateYMD registrationDate, Professor supervisor, double monthlyAmount) { + super(name, cc, birthDate, registrationDate); + this.setSupervisor(supervisor); + this.setMonthlyAmount(monthlyAmount); + } + + public Bolser(String name, int cc, DateYMD birthDate, Professor supervisor, double monthlyAmount) { + this(name, cc, birthDate, null, supervisor, monthlyAmount); + } + + public Professor getSupervisor() { + return this.supervisor; + } + public void setSupervisor(Professor supervisor) { + if (supervisor == null) { + throw new IllegalArgumentException("Supervisor cannot be null"); + } + this.supervisor = supervisor; + } + + public double getMonthlyAmount() { + return this.monthlyAmount; + } + public void setMonthlyAmount(double monthlyAmount) { + if (monthlyAmount < 0) { + throw new IllegalArgumentException("Monthly amount cannot be negative"); + } + this.monthlyAmount = monthlyAmount; + } + + @Override + public String toString() { + return String.format("%s; CC: %d; Date de nascimento: %s; Data de matrícula: %s; NMec: %d; Supervisor: %s; Montante mensal: %.2f", this.getName(), this.getCc(), this.getBirthDate(), this.getRegistrationDate(), this.getNMec(), this.supervisor, this.monthlyAmount); + } +} diff --git a/1ano/2semestre/poo/src/aula06/Contact.java b/1ano/2semestre/poo/src/aula06/Contact.java new file mode 100644 index 0000000..73a711c --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/Contact.java @@ -0,0 +1,55 @@ +package aula06; + +public class Contact { + private final int id; + private Person person; + private String email; + private String phone; + + private static int currentId = 1; + + public Contact(Person person, String email, String phone) { + if (email == null || email.isEmpty() || phone == null || phone.isEmpty()) + throw new IllegalArgumentException("Either email or phone must be provided"); + this.id = Contact.currentId++; + this.setPerson(person); + this.setEmail(email); + this.setPhone(phone); + } + + public int getId() { + return id; + } + + public Person getPerson() { + return person; + } + public void setPerson(Person person) { + if (person == null) + throw new IllegalArgumentException("Person must be provided"); + this.person = person; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + if (!email.matches("^[a-zA-Z_0-9.]+@[a-zA-Z_0-9.]+\\.[a-zA-Z_0-9]+$")) + throw new IllegalArgumentException("Invalid email"); + this.email = email; + } + + public String getPhone() { + return phone; + } + public void setPhone(String phone) { + if (!phone.matches("^9[0-9]{8}$")) + throw new IllegalArgumentException("Invalid phone"); + this.phone = phone; + } + + @Override + public String toString() { + return String.format("ID: %d%nPerson: %s%nEmail: %s%nPhone: %s", this.id, this.person, this.email, this.phone); + } +} diff --git a/1ano/2semestre/poo/src/aula06/ContactList.java b/1ano/2semestre/poo/src/aula06/ContactList.java new file mode 100644 index 0000000..13f5ebb --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/ContactList.java @@ -0,0 +1,177 @@ +package aula06; + +import utils.DateYMD; + +import java.util.Scanner; + +public class ContactList { + private static final Scanner sin = new Scanner(System.in); + private static Contact[] contacts; + + public static void main(String[] args) { + + while (true) { + System.out.println("Selecione uma opção:"); + System.out.println("1. Inserir contacto"); + System.out.println("2. Alterar contacto"); + System.out.println("3. Apagar contacto"); + System.out.println("4. Procurar contacto"); + System.out.println("5. Listar contactos"); + System.out.println("0. Sair"); + System.out.print("> "); + String option = sin.nextLine(); + switch (option) { + case "0" -> { + sin.close(); + System.exit(0); + } + case "1" -> { + System.out.print("Insira o nome: "); + String name = sin.nextLine(); + System.out.print("Insira o cc: "); + String ccStr = sin.nextLine(); + int cc = Integer.parseInt(ccStr); + System.out.print("Insira a data de nascimento (formado: dd-mm-yyyy): "); + String date = sin.nextLine(); + String[] dateParts = date.split("-"); + DateYMD birthDate = new DateYMD(Integer.parseInt(dateParts[0]), Integer.parseInt(dateParts[1]), Integer.parseInt(dateParts[2])); + System.out.print("Insira o email: "); + String email = sin.nextLine(); + System.out.print("Insira o telefone: "); + String phone = sin.nextLine(); + Person person = new Person(name, cc, birthDate); + + Contact contact = new Contact(person, email, phone); + + if (contacts == null) { + contacts = new Contact[1]; + contacts[0] = contact; + } else { + if (checkIfContactExists(cc)) break; + Contact[] newContacts = new Contact[contacts.length + 1]; + System.arraycopy(contacts, 0, newContacts, 0, contacts.length); + newContacts[contacts.length] = contact; + contacts = newContacts; + } + } + case "2" -> { + System.out.print("Insira o nome, email ou telefone do contacto que pretende alterar: "); + String query = sin.nextLine(); + int[] indexes = searchContactsIndex(query); + System.out.printf("Contactos encontrados: %d%n", indexes.length); + + if (indexes.length == 0) { + System.out.println("Não foram encontrados contactos com esse nome, email ou telefone"); + } else if (indexes.length == 1) { + System.out.printf("Alterando contacto: %s%n", contacts[indexes[0]]); + System.out.print("Insira o novo telefone: "); + String phone = sin.nextLine(); + System.out.print("Insira o novo email: "); + String email = sin.nextLine(); + contacts[indexes[0]].setPhone(phone); + contacts[indexes[0]].setEmail(email); + } else { + Contact contact = selectContact(indexes); + System.out.printf("Alterando contacto: %s%n", contact); + System.out.print("Insira o novo telefone: "); + String phone = sin.nextLine(); + System.out.print("Insira o novo email: "); + String email = sin.nextLine(); + contact.setPhone(phone); + contact.setEmail(email); + } + } + case "3" -> { + System.out.print("Insira o nome, email ou telefone do contacto que pretende alterar: "); + String query = sin.nextLine(); + int[] indexes = searchContactsIndex(query); + System.out.printf("Contactos encontrados: %d%n", indexes.length); + + if (indexes.length == 0) { + System.out.println("Não foram encontrados contactos com esse nome, email ou telefone"); + } else if (indexes.length == 1) { + System.out.printf("Apagando contacto: %s%n", contacts[indexes[0]]); + Contact[] newContacts = new Contact[contacts.length - 1]; + System.arraycopy(contacts, 0, newContacts, 0, indexes[0]); + System.arraycopy(contacts, indexes[0] + 1, newContacts, indexes[0], contacts.length - indexes[0] - 1); + contacts = newContacts; + } else { + Contact contact = selectContact(indexes); + System.out.printf("Apagando contacto: %s%n", contact); + Contact[] newContacts = new Contact[contacts.length - 1]; + System.arraycopy(contacts, 0, newContacts, 0, contact.getId()); + System.arraycopy(contacts, contact.getId() + 1, newContacts, contact.getId(), contacts.length - contact.getId() - 1); + contacts = newContacts; + } + } + case "4" -> { + System.out.print("Insira o nome, email ou telefone do contacto que pretende alterar: "); + String query = sin.nextLine(); + int[] indexes = searchContactsIndex(query); + System.out.printf("Contactos encontrados: %d%n", indexes.length); + + if (indexes.length == 0) { + System.out.println("Não foram encontrados contactos com esse nome, email ou telefone"); + } else if (indexes.length == 1) { + System.out.println(contacts[indexes[0]]); + } else { + for (int index : indexes) + System.out.printf("%s%n", contacts[index]); + } + System.out.println(); + } + case "5" -> { + for (Contact contact : contacts) + System.out.printf("%s%n", contact); + System.out.println(); + } + default -> System.out.println("Opção inválida!"); + } + } + } + + private static boolean checkIfContactExists(int cc) { + for (Contact c : contacts) { + if (c.getPerson().getCc() == cc) { + System.out.print("Já existe um contacto para essa pessoa, pretende criar um novo? (s/n): "); + String answer = sin.nextLine(); + return answer.equals("s"); + } + } + return true; + } + + private static int[] searchContactsIndex(String query) { + int[] indexes = new int[contacts.length]; + int index = 0; + for (int i = 0; i < contacts.length; i++) { + if (contacts[i].getPerson().getName().contains(query) || contacts[i].getEmail().contains(query) || contacts[i].getPhone().contains(query)) { + indexes[index] = i; + index++; + } + } + return indexes; + } + + private static Contact selectContact(int[] indexes) { + System.out.println("Foram encontrados vários contactos com esse nome, email ou telefone, selecione um:"); + for (int index : indexes) + System.out.printf("%s%n", contacts[index]); + + Contact contact; + do { + System.out.print("Insira o ID do contacto que pretende alterar: "); + int index = sin.nextInt(); + contact = searchContactById(index); + } while (contact == null); + + return contact; + } + + private static Contact searchContactById(int id) { + for (Contact contact : contacts) { + if (contact.getId() == id) return contact; + } + return null; + } +} diff --git a/1ano/2semestre/poo/src/aula06/Person.java b/1ano/2semestre/poo/src/aula06/Person.java new file mode 100644 index 0000000..4744bad --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/Person.java @@ -0,0 +1,47 @@ +package aula06; + +import utils.DateYMD; + +public class Person { + private String name; + private int cc; + private DateYMD birthDate; + + public Person(String name, int cc, DateYMD birthDate) { + this.setName(name); + this.setCc(cc); + this.setBirthDate(birthDate); + } + + public String getName() { + return this.name; + } + public void setName(String name) { + if (name == null || name.isEmpty()) + throw new IllegalArgumentException("Name cannot be null or empty"); + this.name = name; + } + + public int getCc() { + return this.cc; + } + public void setCc(int cc) { + if (String.valueOf(cc).length() != 8) + throw new IllegalArgumentException("CC must have 8 digits"); + this.cc = cc; + } + + public DateYMD getBirthDate() { + return this.birthDate; + } + public void setBirthDate(DateYMD birthDate) { + if (birthDate == null) + throw new IllegalArgumentException("Birth date cannot be null"); + this.birthDate = birthDate; + } + + @Override + public String toString() { + return String.format("%s; CC: %d; Data de nascimento: %s", this.name, this.cc, this.birthDate); + } +} diff --git a/1ano/2semestre/poo/src/aula06/PersonTest.java b/1ano/2semestre/poo/src/aula06/PersonTest.java new file mode 100644 index 0000000..423cf59 --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/PersonTest.java @@ -0,0 +1,21 @@ +package aula06; + +import java.util.Scanner; +import utils.DateYMD; + +public class PersonTest { + public static void main(String[] args) { + Scanner sin = new Scanner(System.in); + + Student al = new Student ("Andreia Melo", 98556781,new DateYMD(18, 7, 1990), new DateYMD(1, 9, 2018)); + Professor p1 = new Professor("Jorge Almeida", 34672215, new DateYMD(13, 3, 1967), "Associado", "Informática"); + Bolser bls = new Bolser ("Igor Santos", 89765431, new DateYMD(11, 5, 1985), p1, 900); + bls.setMonthlyAmount(1050); + System.out.println("Student:"+ al.getName()); + System.out.println(al); + System.out.println("Bolser:"+ bls.getName() + ", NMec: " + bls.getNMec() + ", Bolsa:" + bls.getMonthlyAmount()+ ", Orientador:" + bls.getSupervisor()); + System.out.println(bls); + + sin.close(); + } +} diff --git a/1ano/2semestre/poo/src/aula06/Professor.java b/1ano/2semestre/poo/src/aula06/Professor.java new file mode 100644 index 0000000..00e59c1 --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/Professor.java @@ -0,0 +1,39 @@ +package aula06; + +import utils.DateYMD; + +public class Professor extends Person { + private String category; + private String department; + + public Professor(String name, int cc, DateYMD birthDate, String category, String department) { + super(name, cc, birthDate); + this.setCategory(category); + this.setDepartment(department); + } + + public String getCategory() { + return this.category; + } + public void setCategory(String category) { + if (category == null || category.isEmpty()) + throw new IllegalArgumentException("Category cannot be null or empty"); + if (!(category.equals("Auxiliar") || category.equals("Associado") || category.equals("Catedrático"))) + throw new IllegalArgumentException("Invalid category"); + this.category = category; + } + + public String getDepartment() { + return this.department; + } + public void setDepartment(String department) { + if (department == null || department.isEmpty()) + throw new IllegalArgumentException("Department cannot be null or empty"); + this.department = department; + } + + @Override + public String toString() { + return String.format("%s; CC: %d; Date de nascimento: %s; Categoria: %s; Departamento: %s", this.getName(), this.getCc(), this.getBirthDate(), this.category, this.department); + } +} diff --git a/1ano/2semestre/poo/src/aula06/README.md b/1ano/2semestre/poo/src/aula06/README.md new file mode 100755 index 0000000..f295632 --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/README.md @@ -0,0 +1,16 @@ +# Programação Orientada a Objetos +## Aula 06 +### Tópico principal da aula: Inheritance + +* [Guião](https://github.com/TiagoRG/uaveiro-leci/tree/master/1ano/2semestre/poo/guides/POO-2022-aula06.pdf) +* [Slides](https://github.com/TiagoRG/uaveiro-leci/tree/master/1ano/2semestre/poo/slides/POO_04_Herança.pdf) + +### Exercise List +| Exercise Number | Files Name | +|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1 | [PersonTest.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/PersonTest.java)
[Person.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/Person.java)
[Student.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/Student.java)
[Professor.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/Professor.java)
[Bolser.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/Bolser.java) | +| 2 | [Contact.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/Contact.java)
[ContactList.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/ContactList.java) | +| 3 | [Vector.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/Vector.java)
[VectorTest.java](https://github.com/TiagoRG/uaveiro-leci/blob/master/1ano/2semestre/poo/src/aula06/VectorTest.java) | + +--- +*Pode conter erros, caso encontre algum, crie um* [*ticket*](https://github.com/TiagoRG/uaveiro-leci/issues/new) diff --git a/1ano/2semestre/poo/src/aula06/Student.java b/1ano/2semestre/poo/src/aula06/Student.java new file mode 100644 index 0000000..458d990 --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/Student.java @@ -0,0 +1,40 @@ +package aula06; + +import utils.DateYMD; +import java.time.LocalDate; + +public class Student extends Person { + private DateYMD registrationDate; + private int nMec; + public static int currentNMec = 100; + + public Student(String name, int cc, DateYMD birthDate, DateYMD registrationDate) { + super(name, cc, birthDate); + this.setRegistrationDate(registrationDate); + this.setNMec(Student.currentNMec++); + } + + public Student(String name, int age, DateYMD birthDate) { + this(name, age, birthDate, null); + } + + public int getNMec() { + return this.nMec; + } + public void setNMec(int nMec) { + this.nMec = nMec; + } + + public DateYMD getRegistrationDate() { + return this.registrationDate; + } + public void setRegistrationDate(DateYMD registrationDate) { + LocalDate now = LocalDate.now(); + this.registrationDate = registrationDate == null ? new DateYMD(now.getDayOfMonth(), now.getMonthValue(), now.getYear()) : registrationDate; + } + + @Override + public String toString() { + return String.format("%s; CC: %d; Date de nascimento: %s; Data de matrícula: %s; NMec: %d", this.getName(), this.getCc(), this.getBirthDate(), this.registrationDate, this.nMec); + } +} diff --git a/1ano/2semestre/poo/src/aula06/Vector.java b/1ano/2semestre/poo/src/aula06/Vector.java new file mode 100644 index 0000000..7e151dd --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/Vector.java @@ -0,0 +1,95 @@ +package aula06; + +public class Vector { + private int[] vector; + + // Constructors and main getter + public Vector() { + this.vector = new int[0]; + } + public Vector(int size) { + this.vector = new int[size]; + } + public Vector(int[] vector) { + this.vector = vector; + } + public int[] getVector() { + return vector; + } + + // Getters + public int size() { + return this.vector.length; + } + public boolean contains(int value) { + for (int n : this.vector) + if (n == value) + return true; + return false; + } + public int count(int value) { + int count = 0; + for (int n : this.vector) + if (n == value) + count++; + return count; + } + + // Method to change values + public void insert(int value) { + if (this.contains(value)) return; + int[] aux = new int[this.size()+1]; + System.arraycopy(this.vector, 0, aux, 0, this.size()); + aux[this.size()] = value; + this.vector = aux; + } + public void remove(int value) { + int[] aux = new int[this.size()-this.count(value)]; + int i = 0; + for (int n : this.vector) { + if (n == value) + continue; + aux[i] = n; + i++; + } + this.vector = aux; + } + public void empty() { + this.vector = new int[0]; + } + + // Interact with other vectors + public Vector add(Vector secondVector) { + Vector result = new Vector(); + for (int n : this.vector) + if (!result.contains(n)) + result.insert(n); + for (int n : secondVector.vector) + if (!result.contains(n)) + result.insert(n); + return result; + } + public Vector subtract(Vector secondVector) { + Vector result = new Vector(); + for (int n : this.vector) + if (!result.contains(n) && !secondVector.contains(n)) + result.insert(n); + return result; + } + public Vector intersect(Vector secondVector) { + Vector result = new Vector(); + for (int n : this.vector) + if (!result.contains(n) && secondVector.contains(n)) + result.insert(n); + return result; + } + + // ToString + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + for (int n : this.vector) + result.append(String.format("%d ", n)); + return this.size() > 0 ? result.substring(0, result.length()-1) : result.toString(); + } +} diff --git a/1ano/2semestre/poo/src/aula06/VectorTest.java b/1ano/2semestre/poo/src/aula06/VectorTest.java new file mode 100644 index 0000000..1259028 --- /dev/null +++ b/1ano/2semestre/poo/src/aula06/VectorTest.java @@ -0,0 +1,31 @@ +package aula06; + + +public class VectorTest { + public static void main(String[] args) { + Vector c1 = new Vector(); + c1.insert(4); c1.insert(7); c1.insert(6); c1.insert(5); + + Vector c2 = new Vector(); + int[] test = { 7, 3, 2, 5, 4, 6, 7}; + for (int el : test) c2.insert(el); + c2.remove(3); c2.remove(5); c2.remove(6); + + System.out.println(c1); + System.out.println(c2); + + System.out.println("Número de elementos em c1: " + c1.size()); + System.out.println("Número de elementos em c2: " + c2.size()); + + System.out.println("c1 contém 6?: " + ((c1.contains(6) ? "sim" : "não"))); + System.out.println("c2 contém 6?: " + ((c2.contains(6) ? "sim" : "não"))); + + System.out.println("União:" + c1.add(c2)); + System.out.println("Interseção:" + c1.intersect(c2)); + System.out.println("Diferença:" + c1.subtract(c2)); + + c1.empty(); + System.out.println("c1:" + c1); + + } +} diff --git a/1ano/2semestre/poo/src/utils/DateYMD.java b/1ano/2semestre/poo/src/utils/DateYMD.java new file mode 100644 index 0000000..b4723c4 --- /dev/null +++ b/1ano/2semestre/poo/src/utils/DateYMD.java @@ -0,0 +1,94 @@ +package utils; + +public class DateYMD { + private int day; + private int month; + private int year; + + public DateYMD(int day, int month, int year) { + if (!validDate(day, month, year)) + throw new IllegalArgumentException("Invalid date"); + this.day = day; + this.month = month; + this.year = year; + } + + public void set(int day, int month, int year) { + if (!validDate(day, month, year)) + throw new IllegalArgumentException("Invalid date"); + this.day = day; + this.month = month; + this.year = year; + } + + public int[] get() { + return new int[]{this.day, this.month, this.year}; + } + + public int getDay() { + return day; + } + + public int getMonth() { + return month; + } + + public int getYear() { + return year; + } + + public void increment() { + if (this.day < monthDays(this.month, this.year)) + this.day++; + else if (this.month < 12) { + this.day = 1; + this.month++; + } else { + this.day = 1; + this.month = 1; + this.year++; + } + } + + public void addDays(int days) { + for (int i = 0; i < days; i++) + this.increment(); + } + + public void decrement() { + if (this.day > 1) + this.day--; + else if (this.month > 1) { + this.day = monthDays(this.month - 1, this.year); + this.month--; + } else { + this.day = 31; + this.month = 12; + this.year--; + } + } + + public String toString() { + return String.format("%04d-%02d-%02d", this.year, this.month, this.day); + } + static boolean validMonth(int month) { + return month >= 1 && month <= 12; + } + + static int monthDays(int month, int year) { + if (!validMonth(month)) + return -1; + int[] daysPerMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + if (month == 2 && isLeapYear(year)) + return 29; + return daysPerMonth[month - 1]; + } + + static boolean isLeapYear(int year) { + return year % 100 == 0 ? year % 400 == 0 : year % 4 == 0; + } + + public static boolean validDate(int day, int month, int year) { + return day >= 1 && day <= monthDays(month, year); + } +} \ No newline at end of file