So I'm trying to write a program that tells a user what bus they can take to get to their class. I have one issue at the moment: I want to have the user pass an int to compare with an ArrayList of int values to tell them if they can catch that bus.
However, I'd like to convert the output to a 12-hour type string but I can't figure out an effective way to do it! Here's my code so far.
package bus;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class busSchedule {
public static void main(String[]args){
int classTime = 0;
Scanner scnr = new Scanner(System.in);
System.out.print("What time do you have to be in class?: ");
classTime = scnr.nextInt();
for(int i = 0; i < AB.toCampus.size() - 1; ++i){
if(classTime > AB.toCampus.get(i)){
String timeString = Integer.toString(AB.toCampus.get(i));
DateFormat f2 = new SimpleDateFormat("h:mm aa");
String newTime = f2.format(timeString).toLowerCase();
System.out.println("You can take the " + AB.line + " line at " + newTime + " to get to class.");
}
}
}
}
I also have the class AB which is the name of the line. It follows:
package bus;
import java.util.ArrayList;
import java.util.Arrays;
public class AB {
static String line = "A-B";
static ArrayList<Integer> toCampus = new ArrayList<Integer>(
Arrays.asList(623, 1234, 1734, 2100)
);
}
The way it is, the output only prints 4:00 pm over and over.
Any help is appreciated!
You could simply parse the military time to a time class and then format it to your desired output, for example...
ArrayList<Integer> toCampus = new ArrayList<>(
Arrays.asList(623, 1234, 1734, 2100)
);
for (int time : toCampus) {
String value = String.format("%04d", time);
LocalTime lt = LocalTime.parse(value, DateTimeFormatter.ofPattern("HHmm"));
System.out.println(DateTimeFormatter.ofPattern("hh:mm a").format(lt));
}
Which outputs
06:23 AM
12:34 PM
05:34 PM
09:00 PM
Now, because your data is actually sorted, you can use Collections.binarySearch to find matches, for example...
ArrayList<Integer> toCampus = new ArrayList<>(
Arrays.asList(623, 1234, 1734, 2100)
);
Scanner scnr = new Scanner(System.in);
System.out.print("What time do you have to be in class?: ");
int classTime = scnr.nextInt();
int index = Collections.binarySearch(toCampus, classTime);
System.out.println(index);
if (index < 0) {
index = Math.abs(index) - 1;
}
if (index > 0 && index <= toCampus.size()) {
int time = toCampus.get(index - 1);
String value = String.format("%04d", time);
LocalTime lt = LocalTime.parse(value, DateTimeFormatter.ofPattern("HHmm"));
System.out.println(DateTimeFormatter.ofPattern("hh:mm a").format(lt));
} else {
System.out.println("Go back to bed");
}
When Collections.binarySearch can't find a match, it will return "-(insertion point) - 1", this tells us where out item would have appeared, had it been in the List.
This allows us to make some decisions about which value in the list is most appropriate.
For example, if we enter 630, the binarySearch will return -2, add 1 for the offset, which gives us -1, convert it to a positive number and that would 1. Now, obviously the element at 1 is 1234, but if we take the previous one, it returns 623!
Related
I am very new to coding and I have a simple question. I want to input day, month and year inside a for loop and after inputting it I want to display all the inputted values on the same time. how to do it.kindly help me.
i have attached the code below.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int i=0;i<n;i++) {
int day = in.nextInt();
String month = in.next();
int year = in.nextInt();
}}
//need to display the entire content from the for loop
//suppose if the n value is 3
//i will be giving 3 inputs
//10 jan 1998
//11 nov 2000
//12 dec 1995
//i want to print all at the same time
Kindly help me with it.
If I understood your question correctly and you just want to print your inputs, just add the following to the loop:
System.out.println(String.format("%d %s %d", day, month, year));
or otherwise, but not as pretty (at least in my opinion):
System.out.println(day + " " + day + " " + month + " " + year);
EDIT
As indicated, you want to print them all at the same time. To do so, you can just save them all in a list or an array for example like the following:
Before the loop:
String[] dates = new String[n];
In the loop:
dates[i] = String.format("%d %s %d", day, month, year);
And then go ahead and insert another loop to print the content of the array:
for(String date: dates){
System.out.println(dates[i]);
}
From what I have gathered, you are looking to set a number on how many dates you'd like the user to enter, take in that number of dates and then print out the dates after the user input.
Here is some basic code that will do that for you
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int numOfInputs = 3; //How many separate dates you would like to enter
int day[] = new int[numOfInputs]; //declaring an integer array day and setting the array size to the value of numOfInputs
String month[] = new String[numOfInputs]; //declaring a string array month and setting the array size to the value of numOfInputs
int year[] = new int[numOfInputs]; //declaring an integer array year and setting the array size to the value of numOfInputs
//get inputs
for(int i=0;i<numOfInputs;i++) {
System.out.println("Please enter a day");
day[i] = sc.nextInt();
System.out.println("Please enter a month");
month[i] = sc.next();
System.out.println("Please enter a year");
year[i] = sc.nextInt();
}
//print content
for(int i=0;i<numOfInputs;i++) {
System.out.println(day[i] + " " + month[i] + " " + year[i]);
}
//close scanner
sc.close();
}
Let me know if this doesn't answer your question or if you need any clarification.
So I'm trying to find the latest date from a list of dates, but I keep getting a NumberFormatException. Is there any way of resolving this?
import java.util.*;
public class Date
{
private String date;
private int day;
private int month;
private int year;
public Date(String date)
{
String [] newDate = date.split(" ");
this.day = Integer.parseInt(newDate[0]);
this.month = Integer.parseInt(newDate[1]);
this.year = Integer.parseInt(newDate[2]);
}
public boolean isOnOrAfter(Date other)
{
if(this.day < other.day)
{
return true;
}
else if(this.day == other.day && this.month < other.month)
{
return true;
}
else if(this.day == other.day && this.month == other.month && this.year < other.year)
{
return true;
}
return false;
}
public String toString()
{
return day + "/" + month + "/" + year;
}
public static void main(String [] args)
{
Scanner in = new Scanner(System.in);
System.out.print("How many dates: ");
int num = in.nextInt();
System.out.println("Enter " + num + " dates: ");
String [] dates = new String[num];
for(int i = 0; i < dates.length; i++)
{
dates[i] = in.nextLine();
}
Date latest = new Date(dates[0]);
for(int i = 0; i < dates.length; i++)
{
Date newDates = new Date(dates[i]);
if(latest.isOnOrAfter(newDates))
{
latest = newDates;
}
}
System.out.println(latest);
}
}
I think its just a tiny problem, but I can't seem to find it. Thanks in advance.
I have a method that checking for the latest date, the logic of the code seems fine to me, if you see any problems in the logic, let me know.
The dates will be input one line at a time, for example:
1 1 1890
1 1 2000
2 1 2000
30 12 1999
The output should be 2/1/2000.
There are two reasons for the NumberFormatException here:
1.You have multiple spaces in your input between the day, month and the year.
2. Scanner's nextInt does not consume the newline. Hence you need to include a dummy nextLine after it. You can read more about this here.
int num = in.nextInt();
in.nextLine(); //To consume the new line after entering the number of dates
System.out.println("Enter " + num + " dates: ");
String [] dates = new String[num];
...
NumberFormatException is caused by Integer.parseInt() trying to parse string that is not an integer.
Your example input contains consecutive spaces and if you split input by space and there are multiple consecutive spaces in the input the resulting array will contain empty strings. Integer.parseInt() is trying to parse one of these empty Strings and that is causing the exception.
instead of
String [] newDate = date.split(" ");
use
String [] newDate = date.split(" +");
This will consider multiple spaces as a split token and return only the non space characters.
I am writing an appointment program in Java and am coming across an error which is
Exception in thread "main" java.lang.NumberFormatException: For input string : ""
for the following lines :
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:470)
at java.lang.Integer.parseInt(Integer.java:499)
at AppointmentNew.main(AppointmentNew.java:24)
The program is going through once, but once it gets to the end of its first run it gives me those errors.... For instance when I run the program as follows : I make the choice of "1" to make a new appointment, I then enter the date of my new appointment "mm/dd/yyyy", then I add an appointment description, and lastly I enter the type "Once, Daily, or Monthly". After that finishes it should start back over with the very first line of "Make Choice (1: New, 2: Print Range, 3: Print All, quit):" But instead it gives me the errors I described above...
Here is my code I have.
import java.util.*;
public class AppointmentNew
{
public static void main (String[] args)
{
ArrayList<String> list = new ArrayList<String>();
Scanner stdin = new Scanner(System.in);
String choice = "";
int choiceNum = 0;
String date = "";
String descrip = "";
int type = 0;
String typeChose = "";
System.out.println("Welcome to Appointment App!\n");
System.out.println("\t============================\n");
do
{
System.out.print("\tMake Choice ( 1: New, 2: Print Range, 3: Print All, quit): ");
choice = stdin.nextLine();
choiceNum = Integer.parseInt(choice);
if (choiceNum == 1)
{
System.out.print("\n\n\tEnter New Appointment Date in mm/dd/yyyy format: ");
date = stdin.nextLine();
System.out.print("\n\n\tEnter New Appointment Description: ");
descrip = stdin.nextLine();
System.out.print("\n\n\tEnter Type (1 = Once, 2 = Daily, 3 = Monthly): ");
type = stdin.nextInt();
if (type == 1)
{
Once once = new Once(date, descrip);
typeChose = "One-Time";
}
else if (type == 2)
{
Daily daily = new Daily(date, descrip);
typeChose = "Daily";
}
else
{
Monthly monthly = new Monthly(date, descrip);
typeChose = "Monthly";
}
String stringToAdd = "";
stringToAdd = ("\n\n\tNew " + typeChose + " Appointment Added for " + date + "\n");
list.add(stringToAdd);
System.out.println(stringToAdd);
System.out.println("\t============================\n");
}
if (choiceNum == 2)
{
System.out.print("\n\n\tEnter START Date in mm/dd/yyyy format: ");
String lowDate = stdin.nextLine();
System.out.print("\n\n\tEnter END Date in mm/dd/yyyy format: ");
String highDate = stdin.nextLine();
for(int i = 0; i < list.size(); i++)
{
int dateSpot = list.get(i).indexOf(" ");
if (list.get(i).compareTo(lowDate) <= 0 && list.get(i).compareTo(highDate) >= 0)
{
System.out.println(list.get(i));
}}
}
if (choiceNum == 3)
{
for(int i = 0; i < list.size(); i++)
{
System.out.println(list.get(i));
}
}
}while (choice != "quit");
}
}
Any help would be great!
You need to add another call to nextLine() after this statement here:
type = stdin.nextInt();
// ED: stdin.nextLine();
This is because, when you grab an int from the Scanner, it doesn't consume the '\n' character that gets put on the input stream when the user hits enter.
Thus, when stdin.nextLine() is called again, the String "" is returned (everything not yet processed up to the next '\n' character), and Integer.parseInt doesn't know how to handle that, so you get an error.
Surround the code with an if statement to check if the value is not quit before trying to Parse it.
I am writing an appointment program in Java and am coming across an error which is as follows :
AppointmentNew.java:68: unreported exception java.text.ParseException; must be caught or declared to be thrown
Date lowDate = sdf.parse(stdin.nextLine());
^
AppointmentNew.java:70: unreported exception java.text.ParseException; must be caught or declared to be thrown
Date highDate = sdf.parse(stdin.nextLine());
^
AppointmentNew.java:77: unreported exception java.text.ParseException; must be caught or declared to be thrown
Date newCurrentDate = sdf.parse(currentDate);
This program is suppose to allow the user to make new appointments, when they do that they are then able to input a date and description (they can do this as many times as they want), after that they can then pick a range of dates for the program to print out (it is suppose to print out the appointments in the date range they provided". This is where my error occurs...
Here is the code I have :
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class AppointmentNew
{
public static void main (String[] args)
{
ArrayList<String> list = new ArrayList<String>();
Scanner stdin = new Scanner(System.in);
String choice = "";
int choiceNum = 0;
String date = "";
String descrip = "";
int type = 0;
String typeChose = "";
System.out.println("Welcome to Appointment App!\n");
System.out.println("\t============================");
do
{
System.out.print("\n\tMake Choice (1: New, 2: Print Range, 3: Print All, 4: Quit) ");
choice = stdin.nextLine();
choiceNum = Integer.parseInt(choice);
if (choiceNum == 1)
{
System.out.print("\n\n\tEnter New Appointment Date in mm/dd/yyyy format: ");
date = stdin.nextLine();
System.out.print("\n\n\tEnter New Appointment Description: ");
descrip = stdin.nextLine();
System.out.print("\n\n\tEnter Type (1 = Once, 2 = Daily, 3 = Monthly): ");
type = stdin.nextInt();
stdin.nextLine();
if (type == 1)
{
Once once = new Once(date, descrip);
typeChose = "One-Time";
}
else if (type == 2)
{
Daily daily = new Daily(date, descrip);
typeChose = "Daily";
}
else
{
Monthly monthly = new Monthly(date, descrip);
typeChose = "Monthly";
}
String stringToAdd = "";
stringToAdd = (date + " : \"" + descrip + "\", " + typeChose);
list.add(stringToAdd);
System.out.println("\n\n\tNew " + typeChose + " Appointment Added for " + date + "\n");
System.out.println("\t============================\n");
}
if (choiceNum == 2)
{
System.out.print("\n\n\tEnter START Date in mm/dd/yyyy format: ");
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date lowDate = sdf.parse(stdin.nextLine());
System.out.print("\n\n\tEnter END Date in mm/dd/yyyy format: ");
Date highDate = sdf.parse(stdin.nextLine());
for(int i = 0; i < list.size(); i++)
{
int dateSpot = list.get(i).indexOf(" ");
String currentDate = list.get(i);
currentDate.substring(0, dateSpot);
Date newCurrentDate = sdf.parse(currentDate);
if (newCurrentDate.compareTo(lowDate) >= 0 && newCurrentDate.compareTo(highDate) <= 0)
{
System.out.println("\n\t" + list.get(i));
}
}
}
if (choiceNum == 3)
{
for(int i = 0; i < list.size(); i++)
{
System.out.println("\n\t" + list.get(i));
}
}
}while (choiceNum != 4);
}
}
The problem is that you're trying to compare a string to a date. What does that even mean?
You should convert the String to a Date (e.g. with SimpleDateFormat) - or ideally, use Joda Time - and then compare the values when you've got them both as the same type.
EDIT: As noted in comments, this isn't what you want either:
SimpleDateFormat sdf = new SimpleDateFormat("mm/dd/yyyy");
mm means minutes in SimpleDateFormat, not months. You want MM/dd/yyyy instead. See the SimpleDateFormat documentation for more details.
currentDate.compareTo(lowDate)
currentDate is String and lowDate is Date. You are trying compareTo on two different things.
Convert currentDate to Date object and then call compareTo();
It is normal, you compare a object of Type Date with a String. Convert your String to a Date with your SimpleDateFormat (or with another format) and you will able to compare both objects.
Date correctCurrentDate = sdf.parse(currentDate);
To avoid to add try/catch in test program, I generally wrote the main method like :
public static void main (String[] args) throws Exception
Of course, for program that run in production, you should use try/catch where you can handle the exception. But it is annoying for a test program.
I have a java programming assignment where you have to input a date on a single line and it gives you a numerology (horoscope-like) report based on the date. It is assumed that the user will enter a formatted date, separated with spaces.
I can retrieve the month, day, and year of the input by using in.nextInt(). However, I also have to check that the user used a correct separating character for each part of the date, which means I just have to check whether the user used forward slashes.
When looking at my code below, I currently use charAt() to find the separating characters. The problem is that the date won't always be 14 characters long. So a date in the form of 10 / 17 / 2004 is 14 characters long, but a date of 4 / 7 / 1992 is only 12 characters long, meaning that "slash1" won't always be in.charAt(3), in the latter situation it would be in.charAt(2).
Does java have a method that allows something like in.nextChar()? I know that it doesn't, but how could I just find a next character in the date?
EDIT: I forgot to reflect this originally, but my professor said that we are NOT allowed to use the String.split() method, for some reason. The thing is, I get the month, day, and year perfectly fine. I just need to check that the person used a forward slash to separate the date. If a dash is entered, the date is invalid.
public void getDate()
{
char slash1, slash2;
do
{
System.out.print("Please enter your birth date (mm / dd / yyyy): ");
Scanner in = new Scanner(System.in);
String date = in.nextLine();
month = in.nextInt();
day = in.nextInt();
year = in.nextInt();
slash1 = date.charAt(3);
slash2 = date.charAt(8);
} while (validDate(slash1, slash2) == false);
calcNum();
}
you could consider to split the input date string with " / ", then you get a String array. the next step is converting each string in that array to int.
I would use Scanner just to get a line. Then split() the line on whitespace and check the fields:
import java.util.Scanner;
import java.util.regex.Pattern;
public class GetDate {
int month, day, year;
public static void main(String[] args)
{
GetDate theApp = new GetDate();
theApp.getDate();
}
public void getDate()
{
String date;
do
{
System.out.print("Please enter your birth date (mm / dd / yyyy): ");
Scanner in = new Scanner(System.in);
date = in.nextLine();
} while (validDate(date) == false);
calcNum();
}
boolean validDate(String date)
{
// split the string based on white space
String [] fields = date.split("\\s");
// must have five fields
if ( fields.length != 5 )
{
return false;
}
// must have '/' separators
if ( ! ( fields[1].equals("/") && fields[3].equals("/") ) )
return false;
// must have integer strings
if ( ! ( Pattern.matches("^\\d*$", fields[0]) &&
Pattern.matches("^\\d*$", fields[2]) &&
Pattern.matches("^\\d*$", fields[4]) ) )
return false;
// data was good, convert strings to integer
// should also check for integer within range at this point
month = Integer.parseInt(fields[0]);
day = Integer.parseInt(fields[2]);
year = Integer.parseInt(fields[4]);
return true;
}
void calcNum() {}
}
Rather than thinking about what characters are used as separators, focus on the content you want, which is digits.
This code splits on non digits, do it doesn't matter how many digits are in each group or what characters are used as separators:
String[] parts = input.split("\\D+");
It's also hardly any code, so there's much less chance for a bug.
Now that you have the numerical parts in the String[], you can get on with your calculations.
Here's some code you could use following the above split:
if (parts.length != 3) {
// bad input
}
// assuming date entered in standard format of dd/mm/yyyy
// and not in retarded American format, but it's up to you
int day = Integer.parseInt(parts[0];
int month = Integer.parseInt(parts[1];
int year = Integer.parseInt(parts[2];
Look ahead in the stream to make sure it contains what you expect.
private static final Pattern SLASH = Pattern.compile("\\s*/\\s*");
static SomeTypeYouMadeToHoldCalendarDate getDate() {
while (true) { /* Might want to give user a way to quit. */
String line =
System.console().readLine("Please enter your birth date (mm / dd / yyyy): ");
Scanner in = new Scanner(line);
if (!in.hasNextInt())
continue;
int month = in.nextInt();
if (!in.hasNext(SLASH)
continue;
in.next(SLASH);
...
if (!validDate(month, day, year))
continue;
return new SomeTypeYouMadeToHoldCalendarDate(month, day, year);
}
}
This uses Scanner methods to parse:
import java.util.Scanner;
import java.util.InputMismatchException;
public class TestScanner {
int month, day, year;
public static void main(String[] args)
{
TestScanner theApp = new TestScanner();
theApp.getDate();
theApp.calcNum();
}
public void getDate()
{
int fields = 0;
String delim1 = "";
String delim2 = "";
Scanner in = new Scanner(System.in);
do
{
fields = 0;
System.out.print("Please enter your birth date (mm / dd / yyyy): ");
while ( fields < 5 && in.hasNext() )
{
try {
fields++;
switch (fields)
{
case 1:
month = in.nextInt();
break;
case 3:
day = in.nextInt();
break;
case 5:
year = in.nextInt();
break;
case 2:
delim1 = in.next();
break;
case 4:
delim2 = in.next();
break;
}
}
catch (InputMismatchException e)
{
System.out.println("ERROR: Field " + fields + " must be an integer");
String temp = in.nextLine();
fields = 6;
break;
}
}
} while ( fields != 5 || validDate(delim1, delim2) == false);
in.close();
System.out.println("Input date: " + month + "/" + day + "/" + year);
}
boolean validDate(String delim1, String delim2)
{
if ( ( ! delim1.equals("/") ) || ( ! delim2.equals("/") ) )
{
System.out.println("ERROR: use '/' as the date delimiter");
return false;
}
if ( month < 1 || month > 12 )
{
System.out.println("Invalid month value: " + month);
return false;
}
if ( day < 1 || day > 31 )
{
System.out.println("Invalid day value: " + day);
return false;
}
if ( year < 1 || year > 3000 )
{
System.out.println("Invalid year: " + year);
return false;
}
return true;
}
void calcNum()
{
}
}