enforcing specific date format in java - java

In my java program a java variable String inputDate accepts input form user. I want to enforce users to enter date in (dd/MM/yyyy) format only as my other modules depend on that format only. Here's what I tried so far:
public class InputQuery {
private static String FLIGHT_DATE;
public String getFLIGHT_DATE() {
return FLIGHT_DATE;
}
public void setFLIGHT_DATE() {
boolean invalid = true;
Scanner sc = null;
while(invalid){
System.out.println("Enter FLIGHT_DATE(dd/MM/yyy) :");
sc = new Scanner(System.in);
FLIGHT_DATE = sc.nextLine();
if( (invalid = isValidDate(FLIGHT_DATE)) ) {
System.out.println("For Feb 21,2016 enter 21/02/2016");
}
}
sc.close();
}
private boolean isValidDate(String flight_DATE) {
SimpleDateFormat myDateFormat = new SimpleDateFormat("dd/MM/yyyy");
if( flightDate.parse(flight_DATE)){
System.out.println("accepted OK");
return true;
}
return false;
}

Use myDateFormat.setLenient(false).
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setLenient(false);
try{
sdf.parse(incomingDateString);
// if you get here, the incomingDateString is valid
}catch(ParseException ex){
// if you get here, the incomingDateString is invalid
}

This won't work, try this
private boolean isValidDate(String flightDate) {
SimpleDateFormat myDateFormat = new SimpleDateFormat("dd/MM/yyyy");
myDateFormat.setLenient(false);
try {
myDateFormat.parse(flightDate);
} catch (ParseException e) {
return false;
}
System.out.println("accepted OK");
return true;
}

You can use regex to check given input is in format or not try this:
public class DateValidator {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String flightDate = null;
boolean isDateValid = false;
while(!isDateValid){
System.out.print("Enter FLIGHT_DATE(dd/MM/yyy) :");
flightDate = scanner.nextLine().trim();
isDateValid = isDateValid(flightDate);
if(!isDateValid){
System.out.println("Wrong Format.");
}
}
System.out.println("continue.");
}
public static boolean isDateValid(String flightDate){
String regex = "^\\d{2}/\\d{2}/\\d{4}$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(flightDate);
return matcher.find();
}
}

To my understanding, what you'd like to do is to ensure that the date entered corresponds to the format.
The parse(String) method doesn't return a boolean, and it never returns null. If it's successful, it returns a date; if it's unsuccessful, it throws an exception. The way to do this is:
private boolean isValidDate(String flight_DATE) {
SimpleDateFormat myDateFormat = new SimpleDateFormat("dd/MM/yyyy");
try {
myDateFormat.parse(flight_DATE);
return true;
} catch (ParseException ex) {
// You may want to print the exception here, or do something else with it
return false;
}
}

Related

How to read array list object to text file in java?

I want to make a method where I can read the text file to the array lists. My ArrayList contains objects, I use some system out println so I can detect where it went wrong, and turns out it's on the while loop part can anyone help me?
public class DataIO {
public static ArrayList<CitizenData> citizenData = new ArrayList<CitizenData>();
public static ArrayList<AppointmentData> appointment = new ArrayList<AppointmentData>();
public static void read(){
try{
Scanner s = new Scanner(new File("Citizen.txt"));
DateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
while(s.hasNext()){
String fullName = s.nextLine();
String numberID = s.nextLine();
int age = Integer.parseInt(s.nextLine());
Date date = formatter.parse(s.nextLine());
String address = s.nextLine();
String phoneNum = s.nextLine();
String email = s.nextLine();
s.nextLine();
CitizenData data = new CitizenData(fullName,numberID,age,date,address,phoneNum,email);
citizenData.add(data);
}
Scanner sc = new Scanner(new File("Appointment.txt"));
DateFormat formatter1 = new SimpleDateFormat("dd-MMM-yyyy");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm");
while(s.hasNext()){
CitizenData numberID = DataIO.check(s.nextLine());
VaccinationCentre vacCentre = VaccinationCentre.valueOf(s.nextLine());
LocalDateTime date = LocalDateTime.parse(s.nextLine());
String vaccineType = s.nextLine();
s.nextLine();
AppointmentData data1 = new AppointmentData(numberID, vacCentre, date,vaccineType);
appointment.add(data1);
}
}catch(Exception e){
System.out.println("Error in read");
}
}
public static void write(){
try{
PrintWriter p = new PrintWriter("Citizen.txt");
for(int i=0; i<citizenData.size(); i++){
p.println(citizenData.get(i).getFullName());
p.println(citizenData.get(i).getNumber());
p.println(citizenData.get(i).getAge());
p.println(citizenData.get(i).getDob());
p.println(citizenData.get(i).getAddress());
p.println(citizenData.get(i).getPhoneNum());
p.println(citizenData.get(i).getEmail());
p.println();
}
p.close();
PrintWriter q = new PrintWriter("Appointment.txt");
for(int i=0; i<appointment.size(); i++){
AppointmentData j = appointment.get(i);
q.println(j.getNumberID());
q.println(j.getVaccineCentre());
q.println(j.getDate());
q.println(j.getVaccineType());
q.println();
}
q.close();
} catch(Exception e){
System.out.println("Error in write!");
}
}
public static CitizenData check(String x){
for(CitizenData d : citizenData){
if(d.equals(d.getNumber())){
return d;
}
}
return null;
}
}
But here every time I run the code, it keeps on going to the catch and it says "error in read". Is my code wrong, but in which part of it?

Convert String to a String having a date format

I want to write a java method that takes a string in input and outputs another string following this rule:
input output
"123456" "12:34:56"
"23456" "02:34:56"
"3456" "00:34:56"
"456" "00:04:56"
"6" "00:00:06"
Any help would be appreciated. Thanks.
I would advice to use DateFormat as below. This will take care of all the burdens of conversion.
DateFormat formatFrom = new SimpleDateFormat("HHmmss");
DateFormat formatTo = new SimpleDateFormat("HH:mm:ss");
String origTimeString = "456";
String newDateString = null;
try {
String formattedString =
String.format("%06d", Integer.parseInt(origTimeString));
Date date = formatFrom.parse(formattedString);
newDateString = formatTo.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("Updated string : " + newDateString);
Copy this method and use it.
1) If string length is more than 6, it's going to return "ERROR".
2) First fixes the String with '0'
3) Second fixes the String with ':'
4) StringBuilder is used for concat. Avoid using '+' operator for concat.
5) Method 'getDate' is static because of 'main' method is static, too.
public static String getDate(String variable){
StringBuilder aux= new StringBuilder();
StringBuilder string= new StringBuilder();
int length = variable.length();
if(length>6 || length<=0){
return "ERROR";
}else{
//first to fill blanks with 0
for(int i=0;i<6-length;i++){
aux.append("0");
}
variable = aux.append(variable).toString();
//second to put :
for(int i=0;i<6;i++){
if(i%2==0 && i!=0){
string.append(":");
}
string.append(variable.charAt(i));
}
return string.toString();
}
}
public static void main(String[] args) {
System.out.print(getDate("464"));
}

Java BigDecimal Rounding

I am learning BigDecimal and i want it to retrieve the exact number i entered, the following code is rouding the number and i dont know why
public static BigDecimal parseFromNumberString(String numberString) {
if (numberString != null) {
String nonSpacedString =
numberString.replaceAll("[ \\t\\n\\x0B\\f\\r]", "").replaceAll("%", "");
int indexOfComma = nonSpacedString.indexOf(',');
int indexOfDot = nonSpacedString.indexOf('.');
NumberFormat format = null;
if (indexOfComma < indexOfDot) {
nonSpacedString = nonSpacedString.replaceAll("[,]", "");
format = new DecimalFormat("##.#");
} else if (indexOfComma > indexOfDot) {
nonSpacedString = nonSpacedString.replaceAll("[.]", "");
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator(',');
format = new DecimalFormat("##,#", otherSymbols);
} else {
format = new DecimalFormat();
}
try {
return new BigDecimal(format.parse(nonSpacedString).doubleValue(), new MathContext(12));
} catch (ParseException e) {
// unrecognized number format
return null;
}
}
return null;
}
If i do something like
public static void main(String[] args){
BigDecimal d = Test.parseFromNumberString("0.39");
System.out.println(d);
}
The value printed is 0,00 and not 0.39
Try this code:
public static BigDecimal parseFromNumberString(String numberString) {
if (numberString != null) {
String nonSpacedString =
numberString.replaceAll("[ \\t\\n\\x0B\\f\\r]", "").replaceAll("%", "");
int indexOfComma = nonSpacedString.indexOf(',');
int indexOfDot = nonSpacedString.indexOf('.');
DecimalFormat decimalFormat = new DecimalFormat();
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
String pattern = "#0.0#";
if (indexOfComma < indexOfDot) {
symbols.setDecimalSeparator('.');
} else if (indexOfComma > indexOfDot) {
symbols.setDecimalSeparator(',');
}
try {
decimalFormat = new DecimalFormat(pattern, symbols);
decimalFormat.setParseBigDecimal(true);
BigDecimal toRet = (BigDecimal) decimalFormat.parse(nonSpacedString);
return toRet.setScale(12);
} catch (ParseException e) {
return null;
}
}
return null;
}
public static void main(String... args) {
BigDecimal d = Test.parseFromNumberString("0,39");
System.out.println(d);
}
Is that what you want??
i just ran your code and i get. 0.390000000000 maybe you forgot to save?
try cleanning your project, restart your ide and recompile. the code should work fine

Finding Correct exception to catch

Which exception can i use to check if the input has the right number of "/"
The input should be like DD/MM/YYYY
try{
String str = text.getText();
StringTokenizer st = new StringTokenizer(str);
String DD = st.nextToken("/");
String MM = st.nextToken("/");
String YYYY = st.nextToken();
}
catch( ???){
}
You will find it in the javadoc of nextToken.
It says it will throw a NoSuchElementException when there is no more token.
That said you should better not use the try/catch but test it using the hasMoreTokens method.
You can use Custom Exception for this but for that you need to declare method which validate your date (No of slashes).
Try Like this
public class Demo
{
public static void main (String[] args) {
try {
new MyClass().metToValidate("01/12/2014");
} catch (A e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class A extends Exception{}
class MyClass{
public void metToValidate(String dateText) throws A{
if( dateText.charAt(2) == '/'&& dateText.charAt(5) == '/' )
System.out.println("DATE IS OK");
else
throw new A();
}
}
The exception throws by nextToken is NoSuchElementException.
String str = "12/21223";
int counter = 0;
for( int i=0; i<str.length(); i++ ) {
if( str.charAt(i) == '/' ) {
counter++;
}
}
if(counter == 3){
StringTokenizer st = new StringTokenizer(str);
String DD = st.nextToken("/");
String MM = st.nextToken("/");
String YYYY = st.nextToken();
System.out.println(str);
}else{
System.out.println("Exception");
}

How do I validate a timestamp?

my application takes in a string like this "2002-10-15 10:55:01.000000". I need to validate that the string is a valid for a db2 timestamp.
How can I do this?
EDIT: This mostly works
public static boolean isTimeStampValid(String inputString) {
SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
try {
format.parse(inputString);
return true;
} catch (ParseException e) {
return false;
}
}
The problem is that if I pass it a bad format for milliseconds like "2011-05-02 10:10:01.0av" this will pass validation. I am assuming that since the first millisecond character is valid then it just truncates the rest of the string.
I'm not exactly sure about the format but you you can play around it and can try something like this
public static bool isTimeStampValid(String inputString)
{
SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
try{
format.parse(inputString);
return true;
}
catch(ParseException e)
{
return false;
}
}
EDIT: if you want to validate for numbers after successful parsing, you could do
format.parse(inputString);
Pattern p = Pattern.compile("^\\d{4}[-]?\\d{1,2}[-]?\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}[.]?\\d{1,6}$");
return p.matcher(inputString).matches();
instead of
format.parse(inputString);
return true;
http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
I believe the format would be "yyyy-MM-dd HH:mm:ss.SSSSSS"
Call parse(String) and catch ParseException indicating it is invalid.
/**
* This method validates the given time stamp in String format
* #param timestamp
* #return
*/
public static boolean isTimeStampValid(String timestamp) {
//(Considering that formal will be yyyy-MM-dd HH:mm:ss.SSSSSS )
//Tokenize string and separate date and time
boolean time = false;
try {
//Tokenize string and separate date and time
StringTokenizer st = new StringTokenizer(timestamp, " ");
if (st.countTokens() != 2) {
return false;
}
String[] dateAndTime = new String[2];
int i = 0;
while (st.hasMoreTokens()) {
dateAndTime[i] = st.nextToken();
i++;
}
String timeToken = dateAndTime[1];
StringTokenizer timeTokens = new StringTokenizer(timeToken, ":");
if (timeTokens.countTokens() != 3) {
return false;
}
String[] timeAt = new String[4];
int j = 0;
while (timeTokens.hasMoreTokens()) {
timeAt[j] = timeTokens.nextToken();
j++;
}
try {
int HH = Integer.valueOf(timeAt[0].toString());
int mm = Integer.valueOf(timeAt[1].toString());
float ss = Float.valueOf(timeAt[2].toString());
if (HH < 60 && HH >= 0 && mm < 60 && mm >= 0 && ss < 60 && ss >= 0) {
time = true;
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
//Got Date
String dateToken = dateAndTime[0];//st.nextToken();
//Tokenize separated date and separate year-month-day
StringTokenizer dateTokens = new StringTokenizer(dateToken, "-");
if (dateTokens.countTokens() != 3) {
return false;
}
String[] tokenAt = new String[3];
//This will give token string array with year month and day value.
int k = 0;
while (dateTokens.hasMoreTokens()) {
tokenAt[k] = dateTokens.nextToken();
k++;
}
//Now try to create new date with got value of date
int dayInt = Integer.parseInt(tokenAt[2]);
int monthInt = Integer.parseInt(tokenAt[1]);
int yearInt = Integer.parseInt(tokenAt[0]);
Calendar cal = new GregorianCalendar();
cal.setLenient(false);
cal.set(yearInt, monthInt - 1, dayInt);
cal.getTime();//If not able to create date it will throw error
} catch (Exception e) {
e.printStackTrace();
return false;
}
//Here we ll check for correct format is provided else it ll return false
try {
Pattern p = Pattern.compile("^\\d{4}[-]?\\d{1,2}[-]?\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}[.]?\\d{1,6}$");
if (p.matcher(timestamp).matches()) {
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
//Cross checking with simple date format to get correct time stamp only
SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
try {
format.parse(timestamp);
//return true;
if (time) {
return true;
} else {
return false;
}
} catch (ParseException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
If you're already connected to the database, you can execute a query that attempts to cast the input string as a timestamp, and check for a failure message (in this case, SQLSTATE 22007).
VALUES CAST( ? AS TIMESTAMP )
The above query will fully validate the input string while consuming hardly any resources on the database server. If the string is invalid for any reason, your database client will encounter an exception.

Categories