Is there a way to retrieve individual information from scanner input? - java

I'm pretty new to java programming and I'm suppose to read data from a separate text file in java and calculate the age of a person however I'm having trouble trying to get the calculation of the age right
Data in the text file:
First Name
Last Name
DOB (E.g. 15 Jan 1988)
Current Year (E.g. 2020)
Below is the code I'm using the read the data from the text file as well as the code I used to calculate the age however when I try to print the DOB it reads correctly but when I try to calculate it doesn't seem to do it correctly
String lastName = input.nextLine();
int day = input.nextInt();
Month month = Month.valueOf (input.next ()); //from an enum
int year = input.nextInt();
int currentYear = input.nextInt();
hr.setFirstName (firstName);
hr.setLastName (lastName);
d.setDate (day, month, year);
hr.setCurrentYear (currentYear);
//the method to calculate age from another class
public int getAge ()
{
Date d = new Date ();
int age = currentYear - d.getYear();
return age;
}
//code to print out the date of birth
System.out.printf("Date of birth: %d %s %d \n", d.getDay(), d.getMonth(), d.getYear());

Related

Java - How do I allow users to select a date range and then check that the date range is either 7 or 14 days?

I need to preface this question by saying that I am incredibly new to Java and programming in general so there are going to be a lot of concepts I don't understand so please try to keep it as simple as possible.
Basically, in college we've been tasked with creating a really simple hotel booking program. We're not being graded on our OOP abilities so it just has to be in one class and done in the console.
A part of it we need to do is allowing the user to select a date range for their stay, which by itself would be fairly simple I think but they are specifically only allowed to stay 7 days or 14 days. So they're not allowed to stay 3 days or 10 days etc.
Now I know how to take input with the scanner class but I feel like taking user-inputted dates is a whole different beast.
So with that in mind how would I go about doing this?
If that doesn't make sense just say and I'll try to clarify further.
Thanks in advance!
LocalDate from java.time
Read the start date from the user
I suggest that you ask the user to input the date in a format defined by the default locale. Users will be happy to use a format that they recognize as common in their culture. To help the user type the correct format, first output both the format and an example date in that format. For example:
Locale userLocale = Locale.getDefault(Locale.Category.FORMAT);
String dateFormat = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, null, IsoChronology.INSTANCE, userLocale);
DateTimeFormatter dateFormatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(userLocale);
LocalDate exampleDate = LocalDate.of(2019, Month.OCTOBER, 23);
System.out.println("Enter start date in format " + dateFormat
+ ", for example " + exampleDate.format(dateFormatter));
In US locale this will print:
Enter start date in format M/d/yy, for example 10/23/19
In German locale, for example, the output is different:
Enter start date in format dd.MM.yy, for example 23.10.19
Now read the date as a string from the user and parse it using the same formatter.
LocalDate arrivalDate = null;
do {
String inputDateString = yourInputScanner.nextLine();
try {
arrivalDate = LocalDate.parse(inputDateString, dateFormatter);
} catch (DateTimeParseException dtpe) {
System.out.println(inputDateString + " is not in the correct format, please try again");
}
} while (arrivalDate == null);
If this was for a graphical user interface, one would typically use a date picker rather than textual input. There are some available, use your search engine.
Read the length of the date range from the user
Have the user input the number of weeks they want to stay, either 1 or 2. Inform them of the end date in each case.
LocalDate departureDate7 = arrivalDate.plusWeeks(1);
LocalDate departureDate14 = arrivalDate.plusWeeks(2);
System.out.println("Enter the number of weeks of the stay,"
+ " 1 for departure date " + departureDate7.format(dateFormatter)
+ ", 2 for departure date " + departureDate14.format(dateFormatter));
Example output (US locale, input 12/20/19):
Enter the number of weeks of the stay, 1 for departure date 12/27/19,
2 for departure date 1/3/20
Based on the user input select the corresponding departure date.
Avoid Date and SimpleDateFormat
The classes Date and SimpleDateFormat used in the other answers are poorly designed, the latter notoriously troublesome. They are also long outdated. Don’t use them. Instead I am using java.time, the modern Java date and time API. A LocalDate is a date without time of day, which seems to be what you need here.
Links
Oracle tutorial: Date Time explaining how to use java.time.
You may also find inspiration in my answer to a different question here.
I presume that you are going to have a simple command line interface. I think you can should use the scanner. Tell the use before hand that the dates need to be in a particular format. E.G. It could be 23rd Feb,2019 or 23/03/2019 or 03/23/2019.
private final int SevenDays = 7;
private final int FourteenDays = 14;
private void checkReservation() {
Scanner scanner = new Scanner(System.in);
System.out.println("The Dates should be in the YYYY-MM-DD Format");
System.out.println("Enter the first date");
String firstDate = scanner.nextLine();
try{
LocalDate startDate = LocalDate.parse(firstDate);
System.out.println("Enter the Second sate");
String secondDate = scanner.nextLine();
LocalDate endDate = LocalDate.parse(secondDate);
checkIfStayAllowed(getDifferenceInDays(startDate, endDate));
} catch (DateTimeParseException dateParseError){
dateParseError.printStackTrace();
}
}
private void checkIfStayAllowed(int reservation){
System.out.println(reservation);
if(reservation == SevenDays){
System.out.println("Guest is allowed to stay for 7 days");
} else if (reservation ==FourteenDays){
System.out.println("Guest is allowed to stay for 14 days");
}
// More logic can go here...
else {
System.out.println("Guest are only allowed to stay for 7 or 14 days!!!");
}
}
private int getDifferenceInDays(LocalDate startDate, LocalDate endDate){
return endDate.compareTo(startDate);
}
You could do something like this to get the date from the user:
private Date getDateFromUser(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a date in this format dd/mm/yyyy:");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse(in.next()); //could also use in.nextLine()
//which grabs the whole line instead of just up until a space like in.next() does
return date;
}
The rest can be decided however you would like. Also make sure to close the scanner object. You might also need to check to make sure what the user entered is okay before you try the creation of the Date object.

How to convert person mm/dd/yyyy D.O.B into actual age. Selenium, Java [duplicate]

This question already has answers here:
Calculating the difference between two Java date instances
(45 answers)
How do I calculate someone's age in Java?
(28 answers)
How can I calculate age in Java accurately given Date of birth
(4 answers)
Closed 4 years ago.
I want to convert date of birth into age.
This is my code.
String patientDOB = driver.findElement(id("patient_profile_widget_form_birthday")).getAttribute("value");
I'm getting date as: 03/01/1961
How could I convert this into age?
I want output like => 57 Years
Any idea? :)
using java 8
public int calculateAge(
LocalDate birthDate) {
// validate inputs ...
return Period.between(birthDate, LocalDate.now());
}
private static final DateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US);
String patientDOB = driver.findElement(id("patient_profile_widget_form_birthday")).getAttribute("value");
Date dateOfBirth = getDateFromString(patientDOB);
public Date getDateFromString(final String patientDOB) {
try {
return FORMATTER.parse(param);
} catch (ParseException e) {
throw new Exception("ParseException occurred while parsing date ", e);
}
}
public static int getAge(Date dateOfBirth) {
Calendar today = Calendar.getInstance();
Calendar birthDate = Calendar.getInstance();
birthDate.setTime(dateOfBirth);
if (birthDate.after(today)) {
throw new IllegalArgumentException("You don't exist yet");
}
int todayYear = today.get(Calendar.YEAR);
int birthDateYear = birthDate.get(Calendar.YEAR);
int todayDayOfYear = today.get(Calendar.DAY_OF_YEAR);
int birthDateDayOfYear = birthDate.get(Calendar.DAY_OF_YEAR);
int todayMonth = today.get(Calendar.MONTH);
int birthDateMonth = birthDate.get(Calendar.MONTH);
int todayDayOfMonth = today.get(Calendar.DAY_OF_MONTH);
int birthDateDayOfMonth = birthDate.get(Calendar.DAY_OF_MONTH);
int age = todayYear - birthDateYear;
// If birth date is greater than todays date (after 2 days adjustment of leap year) then decrement age one year
if ((birthDateDayOfYear - todayDayOfYear > 3) || (birthDateMonth > todayMonth)){
age--;
// If birth date and todays date are of same month and birth day of month is greater than todays day of month then decrement age
} else if ((birthDateMonth == todayMonth) && (birthDateDayOfMonth > todayDayOfMonth)){
age--;
}
return age;
}
Create a wrapper method that get you string as argument,
use:
String[] parts = string.split("/");
and select the 3rd item of the list.
then you just have to use:
int year = Calendar.getInstance().get(Calendar.YEAR);
to get your year. Then you just convert your year string into an int and substract them

Simple one class program java intro trouble [duplicate]

This question already has an answer here:
Java: how can i add a day on Date? [duplicate]
(1 answer)
Closed 5 years ago.
I've been working on this for hours, and while this is due tonight I got my wisdom teeth out today and the anesthesia is making me really easily confused.
I need is two methods within the class, "toString", which takes dd/mm/yyyy and prints that, as well as "advance" which modifies the day + 1.
When I check the modified date, I receive this:
Initial date: 88/8/8888
Modified date: 88/0/8888
int day, month, year, newDay;
String decision, dummy ;
Scanner read = new Scanner(System.in);
public static void main(String[] args) {
Date dateInstance = new Date();
dateInstance.toString();
dateInstance.advance();
}
public String toString() {
System.out.println("Enter day (mm/xx/yyyy): ");
day = read.nextInt();
System.out.println("Enter month (xx/dd/yyyy): ");
month = read.nextInt();
System.out.println("Enter year (mm/dd/xxxx): ");
year = read.nextInt();
System.out.println("Initial date: "+month+"/"+day+"/"+year);
System.out.println("Modified date: "+month+"/"+newDay+"/"+year);
return null;
/*
String decision = read.nextLine();
System.out.println("Would you like to display the date, and the modified date? (Y / N): ");
if(decision == "N") {
System.out.println("'N' Selected");
}else if(decision == "Y") {
System.out.println("Initial date: "+month+"/"+day+"/"+year);
System.out.println("Modified date: "+month+"/"+newDay+"/"+year);
}
return dummy;
*/
}
public int advance() {
newDay = day + 1;
return newDay;
}
Here is some code to get you started. I would guess that your teacher doesn't want you to rewrite the Date's toString() method but actually use it to create your own function that displays the output in another format (Hint - opposite).
Date dateInstance = new Date(System.currentTimeMillis());
Date dateForward = new Date(dateInstance.getTime() + 1000*60*60*24); //put this in a method
System.out.println(dateInstance.toString()); //use the split method to extract and rearrange the date
System.out.println(dateForward.toString());
Check out the Java 8 Docs for the Date Object
Output
2017-06-29
2017-06-30

How to find and save the day of the week in a string [duplicate]

This question already has answers here:
How to determine day of week by passing specific date?
(28 answers)
Closed 6 years ago.
I want to be able to enter a date as in the code below and as well as print the day in the following format: "Sun Jan 01 00:00:00 GMT 2017" I also want to save the day of the week in a string variable. I would be extremely grateful for anyone that could help with this. Many thanks in advance!
import java.util.*;
import java.text.*;
public class Run {
public static void main(String args[]) {
try {
Scanner kb = new Scanner (System.in);
System.out.println("Please enter day of deadline: ");
String day = kb.nextLine();
System.out.println("Please enter month of deadline: ");
String month = kb.nextLine();
System.out.println("Please enter year of deadline: ");
String year = kb.nextLine();
String complete = (""+day+month+year);
Date date = new SimpleDateFormat ("ddMMyyyy" ).parse(complete);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Your code won't work. What if user enters 1, 1, 2017? Then you get 112017 and that won't parse correctly.
Best way is to use the Java 8 LocalDate:
LocalDate date = LocalDate.of(Integer.parseInt(year),
Integer.parseInt(month),
Integer.parseInt(day));
String dayOfWeek = date.getDayOfWeek()
.getDisplayName(TextStyle.SHORT_STANDALONE,
Locale.getDefault());
System.out.println(dayOfWeek); // prints "Sun" for 1/1/2017 (English locale)
You could use the java.time API, which has superseded java.util.Date and related classes since Java 8 and added lots of functionality for date and time processing, including formatting. In your case:
Scanner kb = new Scanner(System.in);
System.out.println("Please enter day of deadline: ");
String day = kb.nextLine();
System.out.println("Please enter month of deadline: ");
String month = kb.nextLine();
System.out.println("Please enter year of deadline: ");
String year = kb.nextLine();
LocalDate date = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
ZonedDateTime datetime = ZonedDateTime.of(date, LocalTime.of(0, 0, 0), ZoneId.of("GMT"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd HH:mm:ss z yyyy");
System.out.println(formatter.format(datetime));
To elaborate a bit on the classes used: In java.time there exist several classes to represent dates, distinguishing between date, date with time, and whether time zone information is included. In the above example, first of all, a java.time.LocalDate object is created from the day, month and year string. This object is then converted to a java.time.ZonedDateTime, adding time and time zone information (in this case 00:00:00 and GMT).
The date-time patterns used by java.time.format.DateTimeFormatter are documented in https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html. For an introduction to the java.time API and why it has been created to replace java.util.Date, see e.g. https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

java: Convert a string which represents a two digit year to four digits

This question has been asked many times but I have an issue which I feel makes it a unique question.
Here it goes.
I have a string which represents a two digit year i.e. to write 2016 I input 16
I have a requirement to convert a two digit year to four digit year i.e. 16 becomes 2016.
After going through some questions and answers I made the following findings
Solution 1
DateFormat sdfp = new SimpleDateFormat("dd.mm.yy");
Date d = sdfp.parse(input);
DateFormat sdff = new SimpleDateFormat("yyyy-MM-dd");
String date = sdff.format(d);
This would be great but I do not have a month or day in my case just a year and I could not find a way to create a date object with just the year.
Solution 2
The above could be solved with a Calendar object but it does not allow the input an of a two digit year for its year field.
Edit
Forgot to mention I cannot use Joda-Time because I'm working on the Android platform and it would increase the size of my project for just this small use
Why not just remove the part of month and day from the format?
DateFormat sdfp = new SimpleDateFormat("yy");
Date d = sdfp.parse(input);
DateFormat sdff = new SimpleDateFormat("yyyy");
String date = sdff.format(d);
LIVE
Here is the rule about how SimpleDateFormat interpret the abbreviated year. (bold by me)
For parsing with the abbreviated year pattern ("y" or "yy"), SimpleDateFormat must interpret the abbreviated year relative to some century. It does this by adjusting dates to be within 80 years before and 20 years after the time the SimpleDateFormat instance is created. For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat instance created on Jan 1, 1997, the string "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" would be interpreted as May 4, 1964.
I think this is much simpler:
String year = "20" + input;
But if you want to make the user's life easy, and assume that he's entering a valid card, this problem is easy: if he types in 2 digits, then add (thisYear/100). If this seems to be in the past in the past, then if it's more than 90 years in the past, then add another 100 (this will only be the case in the last decade of any century)
Date now = new Date();
int expYear = (int)(now.getYear()/100) + parseInt(input);
if (expYear < now.getYear() && expYear+90<now.getYear()) {
expYear += 100;
}
public static int adjustOneOrTwoDigitYearInput(int year) {
return adjustOneOrTwoDigitYearInput(year, Year.now().getValue());
}
public static int adjustOneOrTwoDigitYearInput(int inputYear, int referenceYear) {
if(inputYear > 99) {
return inputYear;
}
int currentCentury = referenceYear / 100 * 100;
int currentCenturyYear = currentCentury + inputYear;
int upperLimit = referenceYear + 20;
int lowerLimit = referenceYear - 79;
// initially place it in current century
int adjusted = currentCenturyYear;
if(adjusted> upperLimit) {
// shift a century down
adjusted -= 100;
}
else if(adjusted < lowerLimit) {
// shift a century up
adjusted += 100;
}
return adjusted;
}
Some Testing:
#Test
public void test_adjustOneOrTwoDigitYearInput()
{
assertEquals(2017, adjustOneOrTwoDigitYearInput(17, 2017));
assertEquals(2037, adjustOneOrTwoDigitYearInput(37, 2017)); // +20
assertEquals(1938, adjustOneOrTwoDigitYearInput(38, 2017)); // +21
assertEquals(2000, adjustOneOrTwoDigitYearInput(0, 2017)); // 0
assertEquals(1999, adjustOneOrTwoDigitYearInput(99, 2017)); // 99
assertEquals(2078, adjustOneOrTwoDigitYearInput(78, 2078));
assertEquals(2098, adjustOneOrTwoDigitYearInput(98, 2078)); // + 20
assertEquals(1999, adjustOneOrTwoDigitYearInput(99, 2078)); // + 21 / 99
assertEquals(2000, adjustOneOrTwoDigitYearInput(0, 2078)); // 0
assertEquals(1990, adjustOneOrTwoDigitYearInput(90, 1990));
assertEquals(1999, adjustOneOrTwoDigitYearInput(99, 1990)); // 99
assertEquals(2000, adjustOneOrTwoDigitYearInput(0, 1990)); // 0
assertEquals(2010, adjustOneOrTwoDigitYearInput(10, 1990)); // +20
assertEquals(1911, adjustOneOrTwoDigitYearInput(11, 1990)); // +21
}
You could use Year from java.time if you are using java 8:
Year year = Year.parse("18", DateTimeFormatter.ofPattern("yy"));
year.toString(); //This returns 2018
You can also try something like this:
String input = "16";
String str = String.valueOf(Calendar.getInstance().get(Calendar.YEAR)).substring(0, 2)+input;
System.out.println("str = " + str);
And the result:
str = 2016
A rather simple one. Courtesy Gavriel
String year = "20" + input;
if(input>99)
{
String year= "2"+input;
}

Categories