How do I validate a timestamp? - java

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.

Related

How to read a date of birth from a txt file and check if older than 18

I have a text file which contains a list of athletes with their date of birth.
I'm trying to figure out how I can read from the text file only the athletes who are on the "elite" team and who are older than 18.
I have figured out how to get only the "elite" athletes, but I can't think of how to solve the age problem.
The birthdates are created separated integers day, month and year
This is the code I've been working on
public void readUngdomElite() throws FileNotFoundException, IOException {
BufferedReader br = null;
try {
String sCurrentLine;
//file to read
br = new BufferedReader(new FileReader("medlemlist.txt"));
while ((sCurrentLine = br.readLine()) != null) {
if (sCurrentLine.contains("elite")) {
System.out.println(sCurrentLine);
}}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
This code gets me all the athletes who are elite, but I want the elite athletes who are older than 18.
Firstly you should provide a .txt file content. But to check if team is older than 18 years you can use this method. Date there is String type and YYYY-MM-dd format.
public boolean isAdult(String birthday) {
String[] parts = birthday.split("-");
if (parts.length==3) {
int year = Integer.parseInt(parts[0]);
int month = Integer.parseInt(parts[1]);
int day = Integer.parseInt(parts[2]);
String currentDate = getCurrentDate();
if (!currentDate.isEmpty() && currentDate.contains("-")) {
String[] parts2 = currentDate.split("-");
if (parts2.length==3) {
int cYear = Integer.parseInt(parts2[0]);
int cMonth = Integer.parseInt(parts2[1]);
int cDay = Integer.parseInt(parts2[2]);
int rYear = cYear - year;
int rMonth = cMonth - month;
int rDay = cDay - day;
if (rMonth<0)
rYear = rYear - 1;
else if (rMonth == 0 && rDay<0)
rYear = rYear - 1;
if (rYear > 17)
return true;
}
}
}
return false;
}
private String getCurrentDate() {
Date todayDate = Calendar.getInstance().getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String todayString = formatter.format(todayDate);
return (todayString!=null)? todayString : "";
}
Feel free to edit the code as you need
The new Date and Time library provides you with convenient methods such as:
LocalDate.of(2015, 02, 20);
LocalDate.parse("2015-02-20");
Period.between(firstDate, secondDate)
With that it shouldn't be too hard to find an age based on how your string looks.
String str = "12 01 1996";
String[] arr = str.split(" ");
LocalDate birth = LocalDate.of(Integer.valueOf(arr[2]), Integer.valueOf(arr[1]), Integer.valueOf(arr[0]));
LocalDate now = LocalDate.now();
if (Period.between(birth, now).getYears() > 18) {
System.out.println("major");
} else {
System.out.println("minor");
}

changing XMLgregorianCalender default format to "yyyyMMdd"

need assistant, i need to change the default format (2017-01-18) for XMLGregorianCalendar to example "20170118" , i have tried a lot of examples through here but its not helping
private static SimpleDateFormat formats = new SimpleDateFormat("yyyyMMdd");
public static XMLGregorianCalendar unmarshal(String value) {
try {
return toXMLGregorianCalendar(formats.parse(value));
} catch ( ParseException e ) {
e.printStackTrace();
return null;
}
}
I'm afraid you cannot do that. If you take a look into the class XMLGregorianCalendar, you'll find that the toString() method just call the toXMLFormat() and the toXMLFormat() doesn't provide any possibility for format customization.
public String toXMLFormat() {
QName typekind = getXMLSchemaType();
String formatString = null;
// Fix 4971612: invalid SCCS macro substitution in data string
// no %{alpha}% to avoid SCCS macro substitution
if (typekind == DatatypeConstants.DATETIME) {
formatString = "%Y-%M-%DT%h:%m:%s" + "%z";
} else if (typekind == DatatypeConstants.DATE) {
formatString = "%Y-%M-%D" + "%z";
} else if (typekind == DatatypeConstants.TIME) {
formatString = "%h:%m:%s" + "%z";
} else if (typekind == DatatypeConstants.GMONTH) {
formatString = "--%M" + "%z";
} else if (typekind == DatatypeConstants.GDAY) {
formatString = "---%D" + "%z";
} else if (typekind == DatatypeConstants.GYEAR) {
formatString = "%Y" + "%z";
} else if (typekind == DatatypeConstants.GYEARMONTH) {
formatString = "%Y-%M" + "%z";
} else if (typekind == DatatypeConstants.GMONTHDAY) {
formatString = "--%M-%D" + "%z";
}
return format(formatString);
}
Is there any work-around solution?
Well, if you just want to get a string of type yyyyMMdd from a XMLGregorianCalendar object, you can do:
XMLGregorianCalendar c = YourCalendarHelper.unmarshal("2017-01-18");
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
String str = format.format(c.toGregorianCalendar().getTime());
System.out.println(str); // 20170118
By the way, if an exception raised during the conversion, DO NOT catch it unless you know you're 100% sure how to handle it. Throw it through the method declaration, so that the caller this method is aware of the potential failure.

Converting Youtube Data API V3 video duration to hh:mm:ss format in java?

I am using Youtube data api v3 to get video information like title, views count and duration.The duration value is new to me as it's an ISO8601 date which I need to convert to a readable format like hh:mm:ss. Duration can have the following different values:
PT1S --> 00:01
PT1M --> 01:00
PT1H --> 01:00:00
PT1M1S --> 01:01
PT1H1S --> 01:00:01
PT1H1M1S --> 01:01:01
I could use Joda Time library to parse the value and calculate the duration in seconds but the library is of 500kb in size which will increase the size of my application that I don't want.
look at this code :
private static HashMap<String, String> regexMap = new HashMap<>();
private static String regex2two = "(?<=[^\\d])(\\d)(?=[^\\d])";
private static String two = "0$1";
public static void main(String[] args) {
regexMap.put("PT(\\d\\d)S", "00:$1");
regexMap.put("PT(\\d\\d)M", "$1:00");
regexMap.put("PT(\\d\\d)H", "$1:00:00");
regexMap.put("PT(\\d\\d)M(\\d\\d)S", "$1:$2");
regexMap.put("PT(\\d\\d)H(\\d\\d)S", "$1:00:$2");
regexMap.put("PT(\\d\\d)H(\\d\\d)M", "$1:$2:00");
regexMap.put("PT(\\d\\d)H(\\d\\d)M(\\d\\d)S", "$1:$2:$3");
String[] dates = { "PT1S", "PT1M", "PT1H", "PT1M1S", "PT1H1S", "PT1H1M", "PT1H1M1S", "PT10H1M13S", "PT10H1S", "PT1M11S" };
for (String date : dates) {
String d = date.replaceAll(regex2two, two);
String regex = getRegex(d);
if (regex == null) {
System.out.println(d + ": invalid");
continue;
}
String newDate = d.replaceAll(regex, regexMap.get(regex));
System.out.println(date + " : " +newDate);
}
}
private static String getRegex(String date) {
for (String r : regexMap.keySet())
if (Pattern.matches(r, date))
return r;
return null;
}
The regex2two has been used to add a leading zero0 to 1-digit numbers. you can try this demo.
In the regexMap I'v stored all 7 cases and appropriate regex-replace.
I did by myself
Let's try
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.
public class YouTubeDurationUtils {
/**
*
* #param duration
* #return "01:02:30"
*/
public static String convertYouTubeDuration(String duration) {
String youtubeDuration = duration; //"PT1H2M30S"; // "PT1M13S";
Calendar c = new GregorianCalendar();
try {
DateFormat df = new SimpleDateFormat("'PT'mm'M'ss'S'");
Date d = df.parse(youtubeDuration);
c.setTime(d);
} catch (ParseException e) {
try {
DateFormat df = new SimpleDateFormat("'PT'hh'H'mm'M'ss'S'");
Date d = df.parse(youtubeDuration);
c.setTime(d);
} catch (ParseException e1) {
try {
DateFormat df = new SimpleDateFormat("'PT'ss'S'");
Date d = df.parse(youtubeDuration);
c.setTime(d);
} catch (ParseException e2) {
}
}
}
c.setTimeZone(TimeZone.getDefault());
String time = "";
if ( c.get(Calendar.HOUR) > 0 ) {
if ( String.valueOf(c.get(Calendar.HOUR)).length() == 1 ) {
time += "0" + c.get(Calendar.HOUR);
}
else {
time += c.get(Calendar.HOUR);
}
time += ":";
}
// test minute
if ( String.valueOf(c.get(Calendar.MINUTE)).length() == 1 ) {
time += "0" + c.get(Calendar.MINUTE);
}
else {
time += c.get(Calendar.MINUTE);
}
time += ":";
// test second
if ( String.valueOf(c.get(Calendar.SECOND)).length() == 1 ) {
time += "0" + c.get(Calendar.SECOND);
}
else {
time += c.get(Calendar.SECOND);
}
return time ;
}
}
Had to deal with this problem as well. I had to convert the length to milliseconds, but once you get the secs/mins/hours variables populated you can convert to any format you want:
// Test Value
$vidLength = 'PT1H23M45S';
$secs = '';
$mins = '';
$hours = '';
$inspecting = '';
for($i=(strlen($vidLength)-1); $i>0; $i--){
if(is_numeric($vidLength[$i])){
if($inspecting == 'S'){
$secs = $vidLength[$i].$secs;
}
else if($inspecting == 'M'){
$mins = $vidLength[$i].$mins;
}
else if($inspecting == 'H'){
$hours = $vidLength[$i].$hours;
}
}
else {
$inspecting = $vidLength[$i];
}
}
$lengthInMS = 1000*(($hours*60*60) + ($mins*60) + $secs);
I needed a array of all these converted duration. So I wrote the below as a workaround and also java.time.duration was not working for me, don't know why.
String[] D_uration = new String[10];
while(iteratorSearchResults.hasNext()){String Apiduration1=Apiduration.replace("PT","");
if(Apiduration.indexOf("H")>=0){
String Apiduration2=Apiduration1.replace("H",":");
if(Apiduration.indexOf("M")>=0){
String Apiduration3=Apiduration2.replace("M",":");
if(Apiduration.indexOf("S")>=0){
D_uration[i]=Apiduration3.replace("S","");
}
else{
String Apiduration4=Apiduration2.replace("M",":00");
D_uration[i]=Apiduration4;
}
}
else{
String Apiduration4=Apiduration2.replace(":",":00:");
if(Apiduration.indexOf("S")>=0){
D_uration[i]=Apiduration4.replace("S","");
}
else{
String Apiduration3=Apiduration4.replace(":00:",":00:00");
D_uration[i]=Apiduration3;
}
}
}
else{
if(Apiduration.indexOf("M")>=0){
String Apiduration2=Apiduration1.replace("M",":");
if(Apiduration.indexOf("S")>=0){
D_uration[i]=Apiduration2.replace("S","");
}
else{
String Apiduration4=Apiduration2.replace(":",":00");
D_uration[i]=Apiduration4;
}
}
else{
D_uration[i]=Apiduration1.replace("S","");
}
}
"Apiduration" is returned by the Youtube data Api in ISO8601 format.
Made some edits now i think it should work fine.

enforcing specific date format in 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;
}
}

Parse Error in Java Program

the error occur near the parsing of proj_close_date.( java.text.ParseException: Unparseable date: "09/09/2010" )
i am reading project_close_date value from database which is in string format. i want convert it in to date format to find that, is proj_close_date present between from_date and to_date
public ArrayList viewAllCustProj1(String frm_date,String to_date,String cust,String proj)
{
ArrayList list= new ArrayList();
try
{
String strCust="";
String strproj="";
if(!cust.equalsIgnoreCase("ALL") && !cust.equals(null))
{
strCust="and customer_code='"+cust+"'";
}
if(!proj.equalsIgnoreCase("ALL") && !proj.equals(null))
{
strproj="and project_code='"+proj+"'";
}
if(cust.equalsIgnoreCase("ALL") && !proj.equalsIgnoreCase("ALL"))
{
}
else
{
stmt=conn.prepareStatement("select customer_code from mst_customer where visible=1 "+strCust+" and category='EU' and multiple_project=0");
rs=stmt.executeQuery();
while(rs.next())
{
reportBean bean=new reportBean();
bean.setCust_code(rs.getString("customer_code"));
bean.setProject_code("");
list.add(bean);
}
rs.close();
stmt.close();
}
System.out.println(" select customer_code,project_code,proj_close_date,added_on from mst_project where visible=1 "+strCust+" "+strproj+"");
stmt=conn.prepareStatement("select customer_code,project_code,proj_close_date,added_on from mst_project where visible=1 "+strCust+" "+strproj+"");
rs=stmt.executeQuery();
while(rs.next())
{
reportBean bean=new reportBean();
String proj_close_date=rs.getString(3);
String added_on=rs.getString(4);
DateFormat myDateFormat = new SimpleDateFormat("MM-dd-yyyy");
DateFormat myDateFormat1= new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
Date myDate1 = null;
Date myDate2 = null;
Date myDate3 = null;
Date myDate4 = null;
Date myDate5 = null;
try
{
if(proj_close_date==null || proj_close_date.trim().equals("") || proj_close_date=="NULL")
{
System.out.println("\n ****** In IF Loop ");
bean.setCust_code(rs.getString("customer_code"));
bean.setProject_code(rs.getString("project_code"));
list.add(bean);
}
else
{
System.out.println("\n ****** In Else Loop ");
myDate1 = myDateFormat.parse(proj_close_date);
myDate2 = myDateFormat.parse(frm_date);
myDate3 = myDateFormat.parse(to_date);
myDate5 = myDateFormat1.parse(added_on);
//myDate4 = myDateFormat.format(myDate5);
System.out.println("Project Code ---->"+rs.getString(2));
System.out.println("Proj_close_date ------>"+myDate1);
System.out.println("From Date ---->"+myDate2);
System.out.println("to Date ---->"+myDate3);
//System.out.println("Added_on --->"+myDate4);
System.out.println("Added_on 1 ie Date 5 ---->"+myDate5);
if(myDate1.after(myDate2) && myDate1.before(myDate3)) // means --> if(proj_close_date.after(frm_date) && proj_close_date.before(to_date))
{
if(myDate1.after(myDate4)) // means --> if(proj_close_date.after(added_on))
{
bean.setCust_code(rs.getString("customer_code"));
bean.setProject_code(rs.getString("project_code"));
list.add(bean);
}
else
{
bean.setCust_code(rs.getString("customer_code"));
bean.setProject_code(rs.getString("project_code"));
list.add(bean);
}
}//if
}//else
}//try
catch (ParseException e)
{
System.out.println("Invalid Date Parser Exception ");
e.printStackTrace();
}
}
rs.close();
stmt.close();
}
catch(SQLException sex)
{
sex.printStackTrace();
}
finally
{
closeConnection();
}
return list;
}
Change this line
DateFormat myDateFormat = new SimpleDateFormat("MM-dd-yyyy");
to this:
DateFormat myDateFormat = new SimpleDateFormat("MM/dd/yyyy");
However, it's quite unclear why you get all the values as strings, perhaps you should consider dedicated ResultSet methods such as getDate or getTimeStamp.
As another side remark I'd like to mention that building SQL queries by concatenation should be avoided -- you should generate queries with ? placeholders, and then set the parameters on your PreparedStatement.

Categories