Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve date parsing #167

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/hallpointer/address/model/member/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
public class Room {

public static final String MESSAGE_CONSTRAINTS = "Room should be in the format block-floor-room number.\n"
public static final String MESSAGE_CONSTRAINTS = "Room must be in the format block-floor-room number.\n"
+ "Example: 10-3-100\n"
+ "Unfortunately, non-numeric block or room numbers are currently unsupported.";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public boolean equals(Object other) {
}

Telegram otherTelegram = (Telegram) other;
System.out.println(value.equals(otherTelegram.value));
return value.equals(otherTelegram.value);
}

Expand Down
44 changes: 39 additions & 5 deletions src/main/java/hallpointer/address/model/session/SessionDate.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Represents a SessionDate.
Expand All @@ -14,11 +16,14 @@
public class SessionDate {

public static final String MESSAGE_CONSTRAINTS =
"Dates should be in the format dd MMM yyyy.\n"
"Dates must be in the format dd MMM yyyy,\n"
+ "although it is case-insensitive and does not need zero-padding.\n"
+ "Example: 24 Sep 2024";

// Desired date format
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd MMM yyyy");
// Whitespace processing already done earlier
public static final Pattern parsingPattern = Pattern.compile("^([0-9]{1,2}) ([a-zA-Z]{3}) ([0-9]{4})$");

public final LocalDate fullDate;

Expand All @@ -30,16 +35,45 @@ public class SessionDate {
public SessionDate(String date) {
requireNonNull(date);
checkArgument(isValidDate(date), MESSAGE_CONSTRAINTS);
fullDate = LocalDate.parse(date, DATE_FORMATTER);
fullDate = LocalDate.parse(manualFormatDate(date), DATE_FORMATTER);
}

/**
* Parses minor errors in date formatting and fixes them.
* Minor errors in this case referring to zero-padding and month case.
*
* @param date the input date in question
* @return the correctly formatted date
*/
private static String manualFormatDate(String date) {
requireNonNull(date);
Matcher matcher = parsingPattern.matcher(date);
if (!matcher.find()) {
return ""; // no amount of formatting can save this given the input constraints
}
// matcher.group(0) returns the whole string
String day = matcher.group(1);
String month = matcher.group(2);
String year = matcher.group(3);

// Fix zero-padding requirement
if (day.length() == 1) {
day = "0" + day;
}
// Fix month case issue
month = month.substring(0, 1).toUpperCase() + month.substring(1).toLowerCase();
// Nothing can be done about year errors due to ambiguity

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does year error mean

return day + " " + month + " " + year;
}

/**
* Returns true if a given string is a valid date and has the expected format.
*/
public static boolean isValidDate(String test) {
public static boolean isValidDate(String date) {
try {
LocalDate parsedDate = LocalDate.parse(test, DATE_FORMATTER);
return parsedDate.format(DATE_FORMATTER).equals(test);
String formattedDate = manualFormatDate(date);
LocalDate parsedDate = LocalDate.parse(formattedDate, DATE_FORMATTER);
return parsedDate.format(DATE_FORMATTER).equals(formattedDate); // throws error if it doesn't work
} catch (DateTimeParseException e) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/hallpointer/address/model/tag/Tag.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
public class Tag {

public static final String MESSAGE_CONSTRAINTS = "Tag names should be alphanumeric and without spaces.";
public static final String MESSAGE_CONSTRAINTS = "Tag names must be alphanumeric and without spaces.";
public static final String VALIDATION_REGEX = "\\p{Alnum}+";

public final String tagName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,33 @@ public void isValidDate() {
assertFalse(SessionDate.isValidDate("24 September 2024")); // wrong format
assertFalse(SessionDate.isValidDate("Oct 24 2024")); // wrong format
assertFalse(SessionDate.isValidDate("2024 24 Sep")); // wrong format
assertFalse(SessionDate.isValidDate("333 Mar 2024")); // invalid day
assertFalse(SessionDate.isValidDate("30 m 2024")); // invalid month
assertFalse(SessionDate.isValidDate("30 Mar 024")); // invalid year
assertFalse(SessionDate.isValidDate(" Mar 2024")); // missing day
assertFalse(SessionDate.isValidDate("29 2024")); // missing month
assertFalse(SessionDate.isValidDate("30 Mar ")); // missing year

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be test cass for invalid dates such as 40 sep 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm i saw the prev test

// valid dates
assertTrue(SessionDate.isValidDate("24 Sep 2024")); // valid date
assertTrue(SessionDate.isValidDate("01 Jan 2000")); // valid date
assertTrue(SessionDate.isValidDate("15 Aug 2023")); // valid date
assertTrue(SessionDate.isValidDate("24 Sep 2024"));
assertTrue(SessionDate.isValidDate("01 Jan 2000"));
assertTrue(SessionDate.isValidDate("15 Aug 2023"));
assertTrue(SessionDate.isValidDate("1 Jan 2000")); // no zero-padding
assertTrue(SessionDate.isValidDate("15 aUg 2023")); // wrong case
assertTrue(SessionDate.isValidDate("4 fEB 1989")); //both
}

@Test
public void equals() {
SessionDate sessionDate = new SessionDate("24 Sep 2024");
SessionDate sessionDate = new SessionDate("4 Sep 2024");

// same values -> returns true
assertTrue(sessionDate.equals(new SessionDate("24 Sep 2024")));
assertTrue(sessionDate.equals(new SessionDate("4 Sep 2024")));

// same after formatting -> returns true
assertTrue(sessionDate.equals(new SessionDate("04 Sep 2024")));
assertTrue(sessionDate.equals(new SessionDate("4 sep 2024")));
assertTrue(sessionDate.equals(new SessionDate("4 SeP 2024")));

// same object -> returns true
assertTrue(sessionDate.equals(sessionDate));
Expand Down