How to validate Hour and Minutes that came from a Swing textBox? - java

I have a window that contains a HH:mm time TextField in it, in 24 hours format
I need to validate if the user entered any non valid hour, like 28:00, 99:00, 24:01.
What's the best and simpler way to do that ?
some code below of what is currently doing that job wrong and giving errors in date parsed.
Today I get an random hour and an user hit 99:99 in that text field.
This code is not mine, but I gotta fix it.
I am stuck with it, tried to validate as a String is useless, and I cannot find a nice way to make it a Date without having to put year, month, etc... too.
Please forget about the return -1 instead of throwing an exception this is old code and this cannot be changed.
to help understand :
Statics.hF2 = SimpleDateFormat (HH:mm)
this.cmpHora.getText() = Is the field with the value
Statics.df_ddmmyy = Another date format
Statics.m2ms = converts minutes to milliseconds
//CODE
public long getDataEmLong ()
{
try
{
Calendar hour= Calendar.getInstance();
new GregorianCalendar().
hour.setTime( Statics.hF2.parse( this.cmpHora.getText() ) );
return Statics.df_ddmmyy.parse( this.cmpData.getText() ).getTime() + Statics.m2ms( hour.get( Calendar.HOUR_OF_DAY ) * 60 ) + Statics.m2ms( hour.get( Calendar.MINUTE ) );
} catch ( Exception e )
{
e.printStackTrace();
return -1;
}
}
Cheers !

Regular expressions to the rescue:
public boolean validTime24(String time) {
return time.matches("^([01]\d|2[0-3]):[0-5]\d$")
}
This will validate the format of the string. Then you can parse out the time from there.

Insert this in your class, and perform the validateTime method from inside your junk code.
public boolean validateTime(String timeString) {
if (timeString.length() != 5) return false;
if (!timeString.substring(2, 3).equals(":")) return false;
int hour = validateNumber(timeString.substring(0, 2));
int minute = validateNumber(timeString.substring(3));
if (hour < 0 || hour >= 24) return false;
if (minute < 0 || minute >= 60) return false;
return true;
}
public int validateNumber(String numberString) {
try {
int number = Integer.valueOf(numberString);
return number;
} catch (NumberFormatException e) {
return -1;
}
}

You can use JFormattedTextField with proper Date or Time Format set. The field will return you proper values.

Since Java 8 you can use DateTimeFormatter:
public boolean validate(String time) {
try {
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
timeFormatter.parse(time);
return true;
} catch (DateTimeParseException e) {
return false;
}
}

Related

Filtering out the nearest date from an array

I have a scenario where i want to select the nearest date or the past date from a bunch of data which i am getting from a ajax call.
For example: If I am getting three rows with three different date like 12/12/2018, 12/3/2018 and 1/1/2018 then I want to return 1/1/2018.
And also if the array doesn't contains past date then it should return the nearest date to the current date.
Please suggest me something to achieve this.
Maybe a function like this would be useful:
function getNearestDate(dates, date) {
if (!dates || dates.length == 0) {
return null;
}
if (!date) {
date = new Date();
}
var result = dates[0];
var dt = Math.abs(new Date(dates[0])-date);
var minimum = dt;
for (var i=1;i<dates.length;i++) {
dt = Math.abs(new Date(dates[i])-date);
if (dt < minimum) {
result = dates[i];
minimum = dt;
}
}
return result;
}

Java: How to check whether given time lies between two times?

I want to check whether target time lies between two given times without considering date using Java8 time. Let say if starting time is "21:30" , ending time is "06:30" and target time is "03:00", so program should return true.
#Test
public void posteNuit()
{
DateTimeFormatter format = DateTimeFormatter.ofPattern("HH:mm");
String s = "21:30";
String e = "06:30";
String t = "03:00";
LocalTime startTime = LocalTime.parse(s, format);
LocalTime endTime = LocalTime.parse(e, format);
LocalTime targetTime = LocalTime.parse(t, format);
if ( targetTime.isBefore(endTime) && targetTime.isAfter(startTime) ) {
System.out.println("Yes! night shift.");
} else {
System.out.println("Not! night shift.");
}
}
You've used LocalTime which doesn't store date information, only time.
Then you are trying to check if target time is after start time (03:00 after 21:30). This statement is false.
Your start time should be before end time.
If you need to handle night shift try following:
if (startTime.isAfter(endTime)) {
if (targetTime.isBefore(endTime) || targetTime.isAfter(startTime)) {
System.out.println("Yes! night shift.");
} else {
System.out.println("Not! night shift.");
}
} else {
if (targetTime.isBefore(endTime) && targetTime.isAfter(startTime)) {
System.out.println("Yes! without night shift.");
} else {
System.out.println("Not! without night shift.");
}
}
in your scenario it seems that if startTime > endTime no matter what's targetTime you'll return true.
So update the if statement:
if (( startTime.isAfter(endTime) && targetTime.isBefore(startTime)
&& targetTime.isAfter(endTime) )
|| ( startTime.isBefore(endTime) && targetTime.isBefore(endTime)
&& targetTime.isAfter(startTime) )) {

jodatime - PeriodFormatter: suffix only for day/days

I need only to show suffix for day/days, how can I achieve that?
It doesn't work:
java.lang.IllegalStateException: No field to apply suffix to..
private PeriodFormatter getDayTextFormatter() {
return new PeriodFormatterBuilder()
.printZeroNever()
.appendSuffix("day", "days")
.toFormatter();
}
I don't think it's possible. According to JodaTime's javadoc, the appendSuffix method will throw an exception if there's no field to append the suffix:
Throws: IllegalStateException - if no field exists to append to
So I believe JodaTime can't help you this time. Although, you could do something like this:
private String suffix(Period p) {
int days = p.getDays();
if (days <= 0) {
return "";
}
return days == 1 ? "day" : "days";
}
With this code, the following:
System.out.println(suffix(Period.days(1)));
System.out.println(suffix(Period.days(2)));
System.out.println(suffix(new Period()));
produces the output:
day
days
// and a line with an empty string

Check whether dates are within the date range in selenium web driver ( Java)

In my website, I can select a date range and list all the transactions within the date range. My test case is to verify whether listed transactions dates are within the selected date range .
This is my code. I get all the transaction dates into a LinkedList. Comp_Dates method will compare the actual date is within the ‘From’ and ‘To’ dates.
The problem is this code will always return True. I have changed the FromDate and ToDate to test the false scenario, But still code will return True.
Can you please help? What’s the problem in this code?
//Set From Date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateFrom_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"),"01/03/2016");
//Set To date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateTo_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"),"30/04/2016");
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_btnList")).click();
List<WebElement> Date =
driver.findElements(By.xpath(".//* [#id='ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_stxOutstandingTransactions_gvOSTransactions']/tbody/tr[*]/td[1]"));
List<String> Dates = new LinkedList<String>();
for(int i=0;i<Date.size();i++)
{
Dates.add(Date.get(i).getText());
System.out.println(Dates);
}
boolean result = comp_Dates(Dates);
if (result=true)
{
System.out.println(result + ", Address are within the range");
}
else
{
System.out.println(result + ", Addresses are not within the range. Test Case Failed");
}
}
private static boolean comp_Dates(List<String> Dates) {
try
{
SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
//Date date = fmt.parse("2013-05-06");
String FromDate= "01/05/2016";
String ToDate= "30/06/2016";
java.util.Date Fdate =fmt.parse(FromDate);
java.util.Date Tdate =fmt.parse(ToDate);
for(String e : Dates)
{
java.util.Date ActualDate = fmt.parse(e);
if (ActualDate.compareTo(Fdate)>=0 & ActualDate.compareTo(Tdate)<=0 );
{
return true;
}
}
}
catch (Exception ex ){
System.out.println(ex);
}
return false;
}
}
Transactions dates in Linked list is [18/04/2016, 14/04/2016, 13/04/2016]
I have specified dates as below in the code.
String FromDate= "01/05/2016";
String ToDate= "30/06/2016";
When compare these dates, code should return false as dates doesn’t fall on within From and To dates. But it returns True. What am I doing wrong here?
Thanks
When you are returning true, it will exit the function whenever it founds a date in the range. Thus it would not check for all dates in the list.
If you want to check for all dates, proper comp_Dates method could be:
//Set From Date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateFrom_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"), "01/03/2016");
//Set To date
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_dtDateTo_txtDate")).sendKeys(Keys.chord(Keys.CONTROL, "a"), "30/04/2016");
driver.findElement(By.id("ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_btnList")).click();
List<WebElement> Date =
driver.findElements(By.xpath(".//* [#id='ctl00_ContentPlaceHolderMain_container_container_Block_172_tabPanelMyAccounts_stxOutstandingTransactions_gvOSTransactions']/tbody/tr[*]/td[1]"));
for (int i = 0; i < Date.size(); i++) {
String date = Date.get(i).getText();
boolean result = comp_Dates(date);
if (result) {
System.out.println(result + ", Address are within the range");
} else {
System.out.println(result + ", Addresses are not within the range. Test Case Failed");
}
}
private static boolean comp_Dates(String date) {
try {
SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
String FromDate = "01/05/2016";
String ToDate = "30/06/2016";
java.util.Date Fdate = fmt.parse(FromDate);
java.util.Date Tdate = fmt.parse(ToDate);
java.util.Date ActualDate = fmt.parse(date);
if (ActualDate.compareTo(Fdate) >= 0 && ActualDate.compareTo(Tdate) <= 0) {
return true;
}
} catch (Exception ex) {
System.out.println(ex);
}
return false;
}
N.B: There are many typos in your code. You should fix these.

StackOverflowError using joda-time new Period(long)

First, sorry this is so long. I probably don't need all the code, but wanted to be sure.
Second, my actual question is, am I doing something wrong, or is this a bug in the joda-time library?
I'm trying to use joda-time (1.6.1) to calculate, then format time durations.
I'm currently using Period, which may be the wrong choice. Please let me know if it is.
However, even if it is the wrong choice, I'm pretty sure this shouldn't happening.
I'm initialising a Period using milliseconds (by multiplying a duration in seconds by 1000). I'm using the Period so I can then format it and print it:
long durationLong = durationSec * 1000;
Period duration = new Period(durationLong);
PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder()
.appendHours()
.appendSeparator(":")
.appendMinutes()
.appendSeparator(":")
.appendSeconds()
.toFormatter();
String formattedString = daysHoursMinutes.print(callDuration.normalizedStandard());
I get the Exception below, and have looked through the source to confirm the loop.
Caused by: java.lang.StackOverflowError
at java.util.Hashtable.get(Hashtable.java:274)
at java.util.Properties.getProperty(Properties.java:177)
at java.lang.System.getProperty(System.java:440)
at java.lang.System.getProperty(System.java:412)
at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132)
at org.joda.time.DateTimeZone.forID(DateTimeZone.java:190)
at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132)
at org.joda.time.DateTimeZone.forID(DateTimeZone.java:190)
...snip (all the same)...
at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132)
at org.joda.time.DateTimeZone.forID(DateTimeZone.java:190)
at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132)
at org.joda.time.DateTimeZone.forID(Dat
Period(long):
public Period(long duration) {
super(duration, null, null);
}
super(long, PeriodType, Chronology):
protected BasePeriod(long duration, PeriodType type, Chronology chrono) {
super();
type = checkPeriodType(type);
chrono = DateTimeUtils.getChronology(chrono);
iType = type;
iValues = chrono.get(this, duration);
}
DateTimeUtils.getChronology(chrono):
public static final Chronology getChronology(Chronology chrono) {
if (chrono == null) {
return ISOChronology.getInstance();
}
return chrono;
}
ISOChronology.getInstance():
public static ISOChronology getInstance() {
return getInstance(DateTimeZone.getDefault());
}
DateTimeZone.getDefault():
public static DateTimeZone getDefault() {
DateTimeZone zone = cDefault;
if (zone == null) {
synchronized(DateTimeZone.class) {
zone = cDefault;
if (zone == null) {
DateTimeZone temp = null;
try {
try {
temp = forID(System.getProperty("user.timezone"));
} catch (RuntimeException ex) {
// ignored
}
if (temp == null) {
temp = forTimeZone(TimeZone.getDefault());
}
} catch (IllegalArgumentException ex) {
// ignored
}
if (temp == null) {
temp = UTC;
}
cDefault = zone = temp;
}
}
}
return zone;
}
forID(String) calls getDefault(), which creates the loop:
public static DateTimeZone forID(String id) {
if (id == null) {
return getDefault();
}
if (id.equals("UTC")) {
return DateTimeZone.UTC;
}
DateTimeZone zone = cProvider.getZone(id);
if (zone != null) {
return zone;
}
if (id.startsWith("+") || id.startsWith("-")) {
int offset = parseOffset(id);
if (offset == 0L) {
return DateTimeZone.UTC;
} else {
id = printOffset(offset);
return fixedOffsetZone(id, offset);
}
}
throw new IllegalArgumentException("The datetime zone id is not recognised: " + id);
}
As the looping part is only in the joda code, I would say that's a bug.
It has been corrected on the trunk and will be available in V2.0.
Resources :
The reported bug
Looks like it's a bug in that it assumes the user.timezone property will have been set.
That's the way to get round it in this case - just make sure that user.timezone is set appropriately. It's a shame that you have to though.
Joda Time uses "null means default" in a lot of places - unfortunately, in my view. I prefer "null is invalid" usually. In Noda Time (a port of Joda Time to .NET) we're trying to get rid of a lot of this kind of thing - as well as preventing the default time zone from being as prevalent in the first place.

Categories

Resources