Compare string within numerical ranges - Java - java

I need help with this string format: "08/13/2015 10:03:50"
I would like to compare the time within a range of 2 min. I get regex to a point but would not know how to go about this when the time is in string format and the cross over to another hour, (Ex. 10:59:30 would lap over to 11:01:30 not 10:61:30).
Code would be something like
string1 = "08/13/2015 10:03:50";
string2 = "08/13/2015 10:05:50, 08/13/2015 10:55:50, 08/13/2015 10:15:50,
08/13/2015 10:14:50, 08/13/2015 10:25:50, 08/13/2015 10:55:50";
if(string2.contains("string1(with plus or minus 2 of string1 min)"){
//Pass
}
Code I am using to grab the date
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Calendar cal = Calendar.getInstance();
String timeOfUpdate = dateFormat.format(cal.getTime());
System.out.println(timeOfUpdate);

Parse the Strings as Date like suggested in the comments, then retrieve the timestamps of both Date objects through the getTime() method. Subtract these two numbers from one another. This get's you the chronological distance of these times in milliseconds, which you can compare to your criteria converted to milliseconds.
Update regarding the date list addendum: To evaluate a String containing a list of dates, you have to split the string along the list separator into an array of strings by using String#split().
Then, you can parse each sub string into a Date object and retrieve the timestamp of each as per the #getTime() method mentioned in the first paragraph. Collect these timestamps into a list.
This list can be searched for entries within the expected range, for example using the Stream API's filter function (Java 8 and newer). Here's a short tutorial about that function.

Try executing the below steps:
Convert String1 into Date Object and apply getTime() method, store the result in some variable
Convert String2 into a array of Strings by using split on comma
Run a loop on results retrieved in step#2, inside loop
Convert each value fetched into Date Object
Call getTime on date object converted
Subtract this number with the one fetched in Step#1
Now you will get the difference in milliseconds(1 min = 60000 miliseconds)
if the difference is either greater than -120000 or less than 120000 miliseconds than break the loop and set the flag to true.
Let me know if you still face any issue.

You can use date.getTime() for getting date in milliseconds since 1970 and split your date string arrays :
int offsetMinutes = 2;
String string1 = "08/13/2015 10:03:50, 08/14/2015 10:05:50, 08/14/2015 10:05:50";
String string2 = "08/13/2015 10:05:49, 08/14/2015 10:05:50, 08/15/2015 10:05:50";
String[] string1Array = string1.split(",");
String[] string2Array = string2.split(",");
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss", Locale.ENGLISH);
for (int j = 0 ; j< string1Array.length;j++)
{
Date date1 = format.parse(string1Array[j].trim());
for (int i = 0; i < string2Array.length; i++) {
Date date2 = format.parse(string2Array[i].trim());
if (date1.getTime() >= (date2.getTime() + offsetMinutes * 60 * 1000) || date1.getTime() <= (date2.getTime() - offsetMinutes * 60 * 1000)) {
//Here we are
}
}
}

Related

Compare 24hr Strings with Java

I have the following String representation of 24hr like 1423 and 1956
I would like to check if the current time (with time zone) is between this pair
my current solution gets the hour and minute of the day using
int h = Instant.now().atZone(ZoneId.systemDefault()).getHour()
int t = Instant.now().atZone(ZoneId.systemDefault()).getMinute()
creating a 4 digit strings from the numbers, and do a string comparison
I don't like my solution at all, What's the elegant way to do it?
You can convert String representation of time to LocalTime as follows:
var formatter = DateTimeFormatter.ofPattern("HHmm");
var lowerTime = LocalTime.parse("1423", formatter);
var upperTime = LocalTime.parse("1956", formatter);
Then you can use isAfter()/isBefore methods to check if it is in between:
var nowTime = LocalTime.now(ZoneId.systemDefault());
boolean inBetween = nowTime.isAfter(lowerTime) && nowTime.isBefore(upperTime);
Create a LocalTime object using the ZonedDateTime.now() reference and subsequent call to ZonedDateTime#toLocalTime. Then create a DateTimeFormatter object using the Pattern HHmm which stands for hours (HH) and minutes (mm). Then you can create a LocalTime from the start time 1423 using the pattern, and an end time of 1956 from the pattern. You can then create a boolean representing whether or not your time is between by determining if the current time is after the start time and before the end time.
LocalTime time = ZonedDateTime.now().toLocalTime();
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("HHmm");
LocalTime startTime = LocalTime.parse("1423", pattern);
LocalTime endTime = LocalTime.parse("1956", pattern);
boolean between = time.isAfter(startTime) && time.isBefore(endTime);
As you note in the question, your strings are in 24-hour time with leading zeros, so you can compare them as strings. Here is a more convenient way to convert the current time to a string in the required format:
String now = DateTimeFormatter.ofPattern("HHmm")
.withZone(ZoneId.systemDefault())
.format(Instant.now());

how to difference between two dates whose Date time type should yyyy-mm-dd hh:mm:ss [duplicate]

This question already has answers here:
Difference in days between two dates in Java?
(19 answers)
Closed 6 years ago.
i want to get difference between two dates whose input parameter will
if pass any input date then it should Convert in to yyyy-mm-dd hh:mm:ss
Date1 :2016-05-30 20:16:00
Date2: 2016-05-29 20:17:00
public long totalHour(Date startDate, Date endDate) {
int diffInDays = (int) ((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
return diffInDays;
}
I am using this code but unable to get Output in integer form please help me in this.
The classical way to calculate the difference between two dates in Java is to:
parse them to Date objects
convert both of them to "milliseconds since the UNIX epoch" by calling Date.getTime()
subtract one from the other.
divide by a constant to convert from milliseconds to the time unit that you require.
Your code seems to be doing that but there are a couple of problems:
the constant is wrong
you are truncating to an int which is liable to give you errors if the two dates are far enough apart.
This would be better:
public long hoursDifference(Date start, Date end) {
return ((end.getTime() - start.getTime()) / (1000 * 60 * 60));
}
Also, you might want to consider rounding rather than truncation.
Parsing dates in an arbitrary format is impossible ... unless you know a priori what the expected format or formats are. In that case, you just try the formats, one at a time, until your parse succeeds. For example, something like this.
SimpleDateFormat[] sdf = new SimpleDateFormat[] {
new SimpleDateFormat(/* format 1 */),
new SimpleDateFormat(/* format 2 */),
...
};
...
Date date = null;
for (int i = 0; i < sdf.length && date == null; i++) {
try {
date = sdf[i].parse(dateString);
} catch (ParseException ex) { /* */ }
}
if (date == null) {
/* report parse error ... */
}
But beware, you won't be able to handle every possible date format correctly. For example, you won't be able to distinguish 7/6/2000 (English 7th of June 2000) from 7/6/2000 (American 6th of July 2000).
IMO, you are better off giving the user a Date chooser of some kind.
... but i want Dataformat is like this yyyy-mm-dd hh:mm:ss
The date format strings are documented in the javadocs for SimpleDateFormat. Read the documentation and you will be able to work it out. And you will be able to work out how to parse other formats too!

Converting string like "15:45" into a double like 15.45

I'm struggling to figure out how to convert a string like "15:45" into a double like 15.45,
I have previously come across methods like .toString() and was looking up a similar method to use in order to convert string to double, however there are several issues, I need to figure out how to make : be a place where dot . is inserted in double.
This is where I would like to use it.
if(westOne > (takeOff.firstInQueue().time)) {}
At the moment westOne is a double where as takeOff.firstInQueue().time is a string like "16.15" I'm assuming I'll need to create my own method to get this working so I can than apply it at the end of it?
You can simply:
myDouble = Double.parseDouble(myStr.replace(":", "."));
If that's really what you want, this will replace : with . and the String x:y will be the double x.y.
Edit:
If you want to add 5 minutes to the time, you can add 0.05 to the double and convert it back to String, but this is not a good way of doing it because:
You should take care of cases like 14:55, adding 0.05 will result 14.6.
And cases like 14:45 where adding 0.05 will result 14.5 (No 0 after 5).
If all what you want is to add 5 minutes to the time, you can use SimpleDateFormat and Calendar:
String myStr = "17:23";
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
Date date = df.parse(myStr );
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MINUTE, 5);
myStr = dateFormat.format(calendar.getTime()); //Now myStr will be 17:28
I think this would work;
String value;
double value1;
value = String.replaceAll(":",".") // Converts the 15:45 to 15.45
value1 = Double.parseDouble(value) // Converts the 15.45 to a double value.
String timevalue = "15:45";
Double pointvalue = Double.parseDouble(timevalue.replace(':', '.'));
//Not double quote like the previous answer because it takes a char as a parameter and not a string

Get Average of two java.util.Date

I have an array of java.util.Date objects. I am trying to find the average.
For example, if I have 2 date objects with 7:40AM and 7:50AM. I should get an average date object of 7:45AM.
The approach I am thinking of is inefficient:
for loop through all dates
find difference between 0000 and time
add that time diff to a total
divide that by the total count
convert that time to a date object
Is there an easier function to do this?
Well fundamentally you can just add up the "millis since the Unix epoch" of all the Date objects and find the average of those. Now the tricky bit is avoiding overflow. Options are:
Divide by some known quantity (e.g. 1000) to avoid overflow; this reduces the accuracy by a known amount (in this case to the second) but will fail if you have more than 1000 items
Divide each millis value by the number of dates you're averaging over; this will always work, but has hard-to-understand accuracy reduction
Use BigInteger instead
An example of approach 1:
long totalSeconds = 0L;
for (Date date : dates) {
totalSeconds += date.getTime() / 1000L;
}
long averageSeconds = totalSeconds / dates.size();
Date averageDate = new Date(averageSeconds * 1000L);
An example of approach 3:
BigInteger total = BigInteger.ZERO;
for (Date date : dates) {
total = total.add(BigInteger.valueOf(date.getTime()));
}
BigInteger averageMillis = total.divide(BigInteger.valueOf(dates.size()));
Date averageDate = new Date(averageMillis.longValue());
With a lot of dates, taking the sum of all dates together will certainly go into an overflow. If you want to prevent that you should do it like this (in pseudo code):
var first = dates.getFirst
var sumOfDifferences = 0
loop over all dates
for each date sumOfDifferences += date - first
var averageDate = first + sumOfDifferences/countOfDates
This will never make you run in an overflow.
There's already an answer here: Sum two dates in Java
You just need to sum up all your date objects using getTime() and then divide it by the number of objects and convert it back to a Date object. Done.
Try this. In here each date convert to long value my getTime(). This will return mil-second value. Then we can proceed.
SimpleDateFormat sdf = new SimpleDateFormat("HH:mma");
Date date1=sdf.parse("7:40AM");
Date date2=sdf.parse("7:50AM");
long date1InMilSec=date1.getTime();
long date2InMilSec=date2.getTime();
System.out.println("Average "+sdf.format((date1InMilSec+date2InMilSec)/2));
To avoid overflow in caluclation of average time:
first sort by date;
store value of first date in time0;
Caluclate the average of the deltaTimes by subtractiong first time0 from all times.
Then sum up and divide.
The result = new Date(time0 + avgDeltas);
Once java 8 is published, you can use
Date avgDate = new Date( LongStream.of(datesAsLongArray).sum() / datesAsLongArray.length * 1000);

adding/removing days from date code fix needed

I have this code here:
public static String AddRemoveDays(String date, int days) throws ParseException
{
SimpleDateFormat k = new SimpleDateFormat("yyyyMMdd");
Date d = k.parse(date);
d = new Date(d.getTime() + days*86400000);
String time = k.format(d);
return time;
}
It take String formed "yyyyMMdd", and adds int days to it. It should work then the days is negative - then he would substract the days from the date. When it does it's math, it returns String formated "yyyyMMdd".
At least that is what it should do. It works for small numbers, but if I try to add (or remove), for example, a year (365 or -365), it returns wierd dates.
What's the problem?
Should I do it a completley another way?
d = new Date(d.getTime() + days*86400000);
If you multiply 86400000 by 365 integer cant hold it. Change 86400000 to Long
d = new Date(d.getTime() + days*86400000L);
and it will be fine.
Hard to say what's going on without specific dates.
If you're committed to doing this with the raw Java classes, you might want to look at using Calendar -e.g.
Calendar calendar = Calendar.getInstance();
calendar.setTime(d);
calendar.add(Calendar.DATE, days); // this supports negative values for days;
d = calendar.getTime();
That said, I would recommend steering clear of the java Date classes, and look to use jodaTime or jsr310 instead.
e.g. in jsr310, you could use a DateTimeFormatter and LocalDate:
DateTimeFormatter format = DateTimeFormatters.pattern("yyyyMMdd");
LocalDate orig = format.parse(dateString, LocalDate.rule());
LocalDate inc = orig.plusDays(days); // again, days can be negative;
return format.print(inc);

Categories

Resources