How to get random time within next hour from given time? - java

I have a object which returns DateTime. I need to generate a random time within next hour.
For example
ZonedDateTime date1 = ZonedDateTime.now(); // returns 2020-01-29T15:00:00.934
ZonedDateTime date2 = ZonedDateTime.now(); // returns 2020-01-29T15:45:00.233
ZonedDateTime convertedDate1;
ZonedDateTime convertedDate2;
//Conversion logic
assertEquals("2020-01-29T15:37:56.345", convertedDate1.toString());
assertEquals("2020-01-29T16:22:22.678", convertedDate2.toString());

You can generate random minutes between 0-60 using ThreadLocalRandom and add them to ZonedDateTime
ZonedDateTime result = date.plusMinutes(ThreadLocalRandom.current().nextInt(60));
In the same way you can add randomly generated seconds and nano seconds also
ZonedDateTime result = date.plusMinutes(ThreadLocalRandom.current().nextInt(58))
.plusSeconds(ThreadLocalRandom.current().nextLong(59))
.plusNanos(ThreadLocalRandom.current().nextLong(999));
Note : nextInt(int bound), nextLong(int bound) will generate between 0 (including) and specific bound (excluding)
Returns a pseudorandom int value between zero (inclusive) and the specified bound (exclusive).

You can try the below code
long leftLimit = 1L;
long rightLimit = 3600000L;
long generatedLong = leftLimit + (long) (Math.random() * (rightLimit - leftLimit));
long currentMillis = System.currentTimeMillis();
long randomTime = currentMillis + generatedLong;
Time time = new Time(currentMillis);
I am getting just time but you can get date and time both.

Related

How to calculate distance between time excluding chunks of time efficiently?

I'm trying to calculate how many minutes are between two dates while excluding periods of time that are arbitrarily defined and occur weekly. I also need to be able to calculate the reverse, where given a time, calculate X number of minutes forward excluding those time periods.
For example, I may have two periods [Fri 5:31pm - Sat 2:26pm] and [Tuesday 3:37am - Thursday 1:14am] that I don't want to count when figuring out the minutes between two dates and when calculating forward.
I currently have code that does this for only one gap, though it's not super efficient and is becoming a strain on my system. I also need to accommodate multiple defined gaps which I currently do not do.
My code which does this for one gap looks like this (hideStart and hideEnter are the start and end DateTime for the gap, absoluteLowValue is the starting time from which I am calculating the distance or time between):
public int absoluteDistance(DateTime high){
long totalMinutes = new Duration(absoluteLowValue,high).getStandardMinutes();
if (!gapHider.isHidingGaps())
return (int)totalMinutes;
int minutesPerWeek = 10080;
long minutesPerHide = new Duration(hideStart, hideEnd).getStandardMinutes();
long numFullWeeks = totalMinutes/minutesPerWeek;
long remainder = totalMinutes%minutesPerWeek;
totalMinutes -= numFullWeeks*minutesPerHide;
DateTime latestEnd = high;
if (latestEnd.getDayOfWeek() == hideEnd.getDayOfWeek() && latestEnd.getSecondOfDay() < hideEnd.getSecondOfDay()){
latestEnd = latestEnd.minusWeeks(1);
}
while (latestEnd.getDayOfWeek() != hideEnd.getDayOfWeek())
latestEnd = latestEnd.minusDays(1);
latestEnd = latestEnd.withTime(hideEnd.getHourOfDay(),
hideEnd.getMinuteOfHour(),
hideEnd.getSecondOfMinute(),
hideEnd.getMillisOfSecond());
DateTime latestStart = high;
if (latestStart.getDayOfWeek() == hideStart.getDayOfWeek() && latestStart.getSecondOfDay() < hideStart.getSecondOfDay()){
latestStart = latestStart.minusWeeks(1);
}
while (latestStart.getDayOfWeek() != hideStart.getDayOfWeek())
latestStart = latestStart.minusDays(1);
latestStart = latestStart.withTime(hideStart.getHourOfDay(),
hideStart.getMinuteOfHour(),
hideStart.getSecondOfMinute(),
hideStart.getMillisOfSecond());
long timeToNearestEnd = new Duration(latestEnd, high).getStandardMinutes();
long timeToNearestStart = new Duration(latestStart, high).getStandardMinutes();
if (timeToNearestEnd < remainder){
totalMinutes -= minutesPerHide;
}else if (timeToNearestStart < remainder){
totalMinutes -= new Duration(latestStart, high).getStandardMinutes();
}
return (int)totalMinutes;
}
public DateTime timeSinceAbsLow(int index){
if (absoluteLowValue != null){
if (!gapHider.isHidingGaps())
return absoluteLowValue.plusMinutes(index);
DateTime date = absoluteLowValue;
long minutesPerWeek = 10080;
long minutesPerHide = new Duration(hideStart, hideEnd).getStandardMinutes();
int difference = (int)(minutesPerWeek - minutesPerHide);
int count = 0;
while (index - count >= difference){
date = date.plusWeeks(1);
count += difference;
}
int remaining = index - count;
DateTime nextStart = date;
while (nextStart.getDayOfWeek() != hideStart.getDayOfWeek())
nextStart = nextStart.plusDays(1);
nextStart = nextStart.withTime(hideStart.getHourOfDay(),
hideStart.getMinuteOfHour(),
hideStart.getSecondOfMinute(),
hideStart.getMillisOfSecond());
long timeDiff = new Duration(date, nextStart).getStandardMinutes();
if (timeDiff < remaining){
date = nextStart.plusMinutes((int)minutesPerHide);
count+= timeDiff;
remaining = index - count;
}
date = date.plusMinutes(remaining);
return date;
}
return new DateTime();
}
Is there a better or easier way of doing this process? I imagine that if I add in the amount of logic to loop through a list of "gaps" that it will just slow it down even more. I'm open to not using Jodatime, I just happen to be using that currently. Any help appreciated!
If I understood correctly, you want to compute the total time between a start and end date, and subtract one ore more periods. So, you could work with Duration objects and then, in the end, convert to whatever you want (minutes, seconds, etc):
// compute all periods you don't want to count
List<Duration> hideList = new ArrayList<>();
// duration between friday and saturday (assuming they have the values of your example)
hideList.add(new Duration(friday, saturday));
// add as many periods you want
// total duration between start and end dates
Duration totalDuration = new Duration(start, end);
// subtract all periods from total
for (Duration duration : hideList) {
totalDuration = totalDuration.minus(duration);
}
// convert to total number of minutes
long totalMinutes = totalDuration.getStandardMinutes();
I'm assuming that all dates used in hideList are between start and end dates (but it's easy to check this using isAfter and isBefore methods).
To do the opposite, you add the totalMinutes to the start date, and then sum all the durations in hideList:
// sum total minutes to start
DateTime dt = start.plusMinutes((int) totalMinutes);
// sum all the periods
for (Duration duration : hideList) {
dt = dt.plus(duration);
}
// dt is the end date
There's one detail: when converting the Duration to a number of minutes, you'll lose the seconds and milliseconds precision, so when doing the opposite algorithm, those fields will be lost. If that's not an issue, just do it as above. But if you want to preserve all the precision, just start by adding the totalDuration object instead of adding the number of minutes:
// sum totalDuratin to start (to preserve seconds and milliseconds precision)
DateTime dt = start.plus(totalDuration);

Current Time In Java(Logic Error) Time Zone: US Eastern Time

I seem to have a logic error in my code. The time now is: 14:38, but
my code says 18:38. I know there's a Calendar class I could use, but I want to
know why this code was wrong.
Code below:
public class welcome{
public static void main(String args[]){
//get total milliseconds since 1970
long total_millisec = System.currentTimeMillis();
// compute total seconds since 1970
long total_sec = total_millisec / 1000;
//compute current second
long current_sec = total_sec % 60;
//compute total minutes since epoch
long total_mins = total_sec / 60;
//compute current minute
long current_min = total_mins % 60;
//compute total hours
long total_hours = total_mins / 60;
//compute current hour
long current_hour = total_hours % 24;
System.out.println("Time is: "+current_hour+":"+current_min+":"
+current_sec);
}
}
When you perform your calculation, it's presumed that System.currentTimeMillis() returns difference in milliseconds between midnight of 1st January of 1970 (which is 1970-01-01 00:00) and current time. Try to evaluate the base date in your system and see what it'll be:
System.out.println("" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm").format(new java.util.Date(0)));
it might return something like 1969-12-31 19:00 and this is not the midnight.
System.currentTimeMillis() returns the same as expression:
long currentTime = new java.util.Date().getTime() - new java.util.Date(0).getTime();

How to use time in calculations (half hours)

I want to make a program that's checking if an input is greater than 8h30m. How do I accomplish this? I thought maybe about java.util.Calendar or Date but I don't know how those things work.
Use the Duration from Java 8:
String input = "8h";
Duration duration = Duration.parse("PT" + input);
Duration compared = Duration.ofHours(8).plus(Duration.ofMinutes(30));
int compare = duration.compareTo(compared); // -1
// compare would be 0 for input="8h30m" and 1 for input="8h40m"
Edit - You can substract times as well, get the seconds for example:
Duration diff = duration.minus(compared);
int seconds = diff.getSeconds();
Try using Joda Timer
http://www.joda.org/joda-time/
You can use DateTime for that and us function isAfter for your case.
If what you want is to check if the current time is before another time, you can do this:
public Boolean foo() {
Calendar currentlyCal = Calendar.getInstance(); // This is the currently time.
Calendar calToCheck = Calendar.getInstance();
calToCheck.set(Calendar.HOUR_OF_DAY, 8);
calToCheck.set(Calendar.MINUTE, 30);
return currentlyCal.before(calToCheck); // or use after() instead of before() if it's what you want.
}
EDIT
The difference:
public void getDifference(Calendar cal1, Calendar cal2) {
long diff = cal2.getTimeInMillis() - cal.getTimeInMillis();
long seconds = diff/1000;
long hour = seconds/3600;
seconds = seconds%3600;
long minutes = seconds/60;
seconds = seconds%60;
// .. do something
}

How to add two Milliseconds in android

I want to calculate difference between two times which is calculate correctly then i have to half it so i divide it with 2 results are okay. but when i am trying to add the timdedifferencemillis to startTime its not giving me the correct result...
starttime= 05:53
endtime= 17:57
i want results 11:55
but my code giving me 06:55
please help.....
protected String transitTime2(String endtime, String starttime) {
SimpleDateFormat dt = new SimpleDateFormat("hh:mm");
Date startTime = null;
Date endTime;
long timdedifferencemillis = 0;
try {
startTime = dt.parse(starttime);
endTime = dt.parse(endtime);
long diff=startTime.getTime();
timdedifferencemillis = (endTime.getTime() - startTime.getTime())/2;
//timdedifferencemillis
} catch (ParseException e) {
e.printStackTrace();
}
long timdedifferencemillis1=startTime.getTime()+timdedifferencemillis;
int minutes = Math
.abs((int) ((timdedifferencemillis1 / (1000 * 60)) % 60));
int hours = Math
.abs((int) ((timdedifferencemillis1 / (1000 * 60 * 60)) % 24));
String hmp = String.format("%02d %02d ", hours, minutes);
return hmp;
}
The problem is probably time zone; when you parse endtime and starttime initially, by default (in the absence of an explicit time zone indicated in the format string and represented in the input), Java assumes that the times provided are relative to the local time zone of the system. Then, when you call getTime(), it returns
the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object
One solution is to tell your SimpleDateFormat object to assume that all strings it parses are in GMT, rather than in the local time zone. Try adding this line after you initialize dt, but before calling dt.parse(...):
dt.setTimeZone(TimeZone.getTimeZone("GMT"));
This is quite easy to do with the new java.time API in Java 8 or with the JODA Time library:
import java.time.Duration;
import java.time.LocalTime;
public class TimeDiff {
public static void main(String[] args) {
LocalTime start = LocalTime.parse("05:53");
LocalTime end = LocalTime.parse("17:57");
// find the duration between the start and end times
Duration duration = Duration.between(start, end);
// add half the duration to the start time to find the midpoint
LocalTime midPoint = start.plus(duration.dividedBy(2));
System.out.println(midPoint);
}
}
Output:
11:55
By using LocalTime objects, you avoid any problems with time zones.
I think the problem is the types "long" and "int" in your code ;when we divide with 2 ( long timdedifferencemillis )the result must be "double".

Time difference in seconds gives me wrong answers

I have two date strings and I want to know how many seconds difference there is between them.
2014-05-19 16:37:36:690 // formattedDate
2014-05-19 19:38:00:000 // expString
I use the following code:
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss:SSS");
Date d1 = null;
Date d2 = null;
d1 = sdf.parse(expString);
d2 = sdf.parse(formattedDate);
long diff = d1.getTime() - d2.getTime();
long exp = diff / 1000 % 60;
In this particular example exp is 23. What is the problem here?
.getTime() returns the time in milliseconds since January 1, 1970, 00:00:00 GMT. So diff has the time in milliseconds between the two dates.
long diff = d1.getTime() - d2.getTime();
// diff = 10882310
You user integer division to get to seconds, which drops the extra milliseconds.
long temp = diff / 1000;
// temp = 10823
Then you modulus by 60, which gets you seconds and ignores seconds that were attributed to minutes.
long exp = temp % 60;
// exp = 23
If you want the total time in seconds between the two dates, you don't want to do that last operation.
Don't use modulus division! Just use plain division:
long diff = d1.getTime() - d2.getTime();
long exp = diff / 1000;
Better yet, use the TimeUnit enum from the JDK:
long exp = TimeUnit.MILLISECONDS.toSeconds(d1.getTime() - d2.getTime());
Joda-Time offers a Seconds class to just what you want.
The Joda-Time library also has classes to represent spans of time: Duration, Interval, and Period. You don’t strictly need them for this specific question, but they will be handy for related work.
Below is some untested code off the top of my head.
For simplicity, convert your strings to strict ISO 8601 format. Replace the SPACE with a T.
String inputStart = "…".replace( " ", "T" );
// same for stop
Create date-time objects. Explicitly assign a time zone by which to parse those strings. Are that UTC?
DateTime startDateTime = new DateTime( inputStart, DateTimeZone.UTC );
// repeat for stop
long secs = Seconds.secondsBetween( startDateTime, stopDateTime ).getSeconds();

Categories