Logic Problem - Java
I have a family tree app which allows you to build nodes. I am stuck on a problem which requires editing a members date of birth. The date of birth is just a string in the following format dd-mm-yyyy. My problem arises when checking if the date of birth is valid (i.e. any parent cannot be younger than a child). So if the node has both parents and children and user selects to edit it's date of birth, the function must continuously check to see whether an age between the two dates has been added. The problem I am having is getting this continual check to occur using the methods I have defined. I'm hoping someone understands the isue and can help. Note checkDOb also sets the dob too. its bad naming on my part.
here is the code:
private void dateCheck(FamilyMember node) {
String dob = enterDateOfBirth();
if (node.hasChildren()) {
node.setDob(dob);
checkDob(node, node.getOldestChild(), 0);
}
FamilyMember parent = null;
if (node.hasMother() && node.hasFather()) {
if (node.getMother().getAge() > node.getFather().getAge()) {
parent = node.getFather();
} else {
parent = node.getMother();
}
checkDob(parent, node, 1);
} else {
//single parent
if (node.hasMother()) {
parent = node.getMother();
checkDob(parent, node, 1);
}
if (node.hasFather()) {
parent = node.getFather();
checkDob(parent, node, 1);
}
}
}
private void checkDob(FamilyMember parent, FamilyMember child, int member) {
out.println(parent.getYear());
out.println(child.getYear());
while (parent.getYear() > child.getYear()) {
out.println("Invalid Date - The Oldest Child of " + parent.getFullName()
+ "(" + child.getFullName() + ")\n cannot older than his/her parents. Try Again.");
out.println();
if (member == 0) {
parent.setDob(enterDateOfBirth());
开发者_Python百科 }
if (member == 1) {
child.setDob(enterDateOfBirth());
}
}
}
private String enterDateOfBirth() {
out.print("Enter Year Of Birth (0 - 2011): ");
String y = in.nextLine();
out.print("Enter Month Of Birth (1-12): ");
String m = in.nextLine();
if (m.trim().equals("")) {
m = "0";
}
if (m.length() == 1) {
m = "0" + m;
}
m += "-";
out.print("Enter Date of Birth (1-31): ");
String d = in.nextLine();
if (d.trim().equals("")) {
d = "0";
}
if (d.length() == 1) {
d = "0" + d;
}
d += "-";
String dob = d + m + y;
while (!DateValidator.isValid(dob)) {
out.println("Invalid date. Try again.");
dob = enterDateOfBirth();
}
return (dob);
}
Thanks in advance.
Well the standard way to parse Dates is using SimpleDateFormat
. But I don't think that will help in your case you so I won't go there.
But you should use Date objects (or, as others will say: use JodaTime's DateTime object) when you are talking about Dates, it makes things easier.
make Date
the type of dob
and exchange this code:
String dob = d + m + y;
for this:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(y));
cal.set(Calendar.MONTH, Integer.parseInt(m)-1);
cal.set(Calendar.DATE, Integer.parseInt(d));
Date dob = cal.getTime();
(you should lose all the if (m.length() == 1)
stuff, because Strings with leading zeroes will be parsed as octal values)
Now you can just validate that parentBirthDate.compareTo(childBirthDate)>0
Also, to be more precise you should truncate all the fields that are smaller than day:
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Also: don't use System.out.println()
, use a logging framework like Log4J or SLF4J.
Oh, BTW, validating that the child is younger than the parent won't be enough. You will probably have to validate that the difference is 12 years or more :-)
It can be smt like
//return true if one of arguments is true!
private boolean bornBefore(FamilyMember first, FamilyMember second){
if(first == null || second == null){
return true;
}
return /*your magic date comaparator*/;
}
private boolean validDate(FamilyMember node, MagicDate date) {
return bornBefore(node, node.getOldestChild())
&& bornBefore(node.getFather(), node)
&& bornBefore(node.getMother(), node);
}
}
You should decouple your validation and data entry. To start of you have your tree model with the current values and a new string that you want to enter in to change a value.
bool checkDOB(String date, FamilyMember node) {
//return true if date is more recent than any parents of node and
//older than any children of node
}
Now that you have a stand alone validation method, you should call it anytime you are about to add a new node or edit one. Do not change any values in the actual data model until it has been validated This means your tree will always be in a valid state and an edit is just a local operation.
精彩评论