How to calculate relative time spans using Java (code converting problem)? [duplicate] - java

This question already has answers here:
Java 8: Difference between two LocalDateTime in multiple units
(11 answers)
Closed 2 years ago.
I decided to give myself a challenge on Java that implements this question's achievement.
The things I have to do is get LocalDateTime, convert the same code from the linked question's answers, then receiving a string from the function.
Here's what I've done so far:
public static String relTime(LocalDateTime now)
{
// accepted answer converted to Java
const int min = 60 * SECOND;
const int hour = 60 * MINUTE;
const int day = 24 * HOUR;
const int mon = 30 * DAY;
// still don't know how to convert this method
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 1 * MINUTE)
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
if (delta < 2 * MINUTE)
return "a minute ago";
if (delta < 45 * MINUTE)
return ts.Minutes + " minutes ago";
if (delta < 90 * MINUTE)
return "an hour ago";
if (delta < 24 * HOUR)
return ts.Hours + " hours ago";
if (delta < 48 * HOUR)
return "yesterday";
if (delta < 30 * DAY)
return ts.Days + " days ago";
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
}
The only problem that I should encounter is from var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);.
Although I read 2 questions from Stack Overflow finding equivalents of TimeSpan and Ticks, I baely have any ideas how to properly convert the line of code. Also, I have to get a double which will need math.abs() to get TotalSeconds which I can't really find a proper way to deal with either, but I did find ZoneOffset.ofTotalSeconds and still don't know how to deal with it.
So how can I convert this properly?
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);

You need to gain a deeper understanding of what this method actually does. Literally translating code from C# to Java won't give you a good solution and gets you stuck on language-specific details.
The two lines basically calculate the (absolute) difference in seconds of a timestamp to the current time. This can be written in Java as follows:
Duration duration = Duration.between(LocalDateTime.now(), timestamp);
long delta = duration.abs().getSeconds();
I'm just addressing your actual question here on how to transform these two lines. The provided snippet is not valid Java code and some parts are missing. delta is the difference in seconds which does not necessarily need to be a double. The argument you pass to your method should be named anything else than now because this is the timestamp you want to compare to the current time inside the method.

You could use SimpleDateFormat to create a nice display format (use something like "HH hours, mm minutes and ss seconds ago" for the format (not sure if this exact example works)). You could also use Instant to get the current time, and you can use Instant.now().minusSeconds(Instant.now().minusSeconds(seconds).getEpochSeconds()) for the time difference (or just use System.currentTimeMillis() and multiply by 1000).
Alternatively, you could use Duration and write a custom display format using getSeconds() and getHours() etc.

Related

LocalTime Military Time Parsing 00:00 [duplicate]

This question already has answers here:
LocalTime() difference between two times
(2 answers)
Closed 3 years ago.
I've looked at just about all the other posts pertaining to my question without finding a similar issue as mine.
I'm trying to get the time between two fields using this code.
LocalTime timeFrom = LocalTime.parse("16:00");
LocalTime timeTo = LocalTime.parse("00:00");
System.out.println(Duration.between(timeFrom,timeTo).toHours());
The issue I'm having is that the print out is negative 16 hours. What I want to accomplish is to get the amount of time from 4pm (which is 1600) to 12am (which is 00:00).
The result that I'm looking for would be 8 hours.
I have an idea of taking 1 minute from the 00:00, then getting the duration between those then just simply adding the 1 minute back to it, but I was thinking there must be an easier way.
After pondering I feel like I was looking for a programmer solution instead of a simple one...
The answer to this is just adding 24 hours back to the negative result!
LocalTime timeFrom = LocalTime.parse("16:00");
LocalTime timeTo = LocalTime.parse("00:00");
long elapsedMinutes = Duration.between(timeFrom, timeTo).toMinutes();
//at this point Duration for hours is -16.
//checking condition
if(timeTo.toString().equalsIgnoreCase("00:00")){
//condition met, adding 24 hours(converting to minutes)
elapsedMinutes += (24 * 60);
}
long elapsedHours = elapsedMinutes / 60;
long excessMinutes = elapsedMinutes % 60;
System.out.println("Hours: " + elapsedHours);
System.out.println("Minutes: " + excessMinutes);
I propose to check if the result is negative, then you don't limit the code to check for exact string equality, and 00:01 will still come out 8 hours:
import java.time.Duration;
import java.time.LocalTime;
public class StackOverflowTest {
public static void main(String[] args) {
String from = "16:00";
String to = "00:01";
LocalTime timeFrom = LocalTime.parse(from);
LocalTime timeTo = LocalTime.parse(to);
Duration duration = Duration.between(timeFrom,timeTo);
if (duration.isNegative()) duration = duration.plusDays(1);
System.out.println(duration.toHours());
}
/*
Prints:
8
*/
}
Or perhaps or more reader-friendly option:
...snip
Duration duration;
if (timeFrom.isBefore(timeTo)) {
duration = Duration.between(timeFrom,timeTo);
} else {
duration = Duration.between(timeFrom,timeTo).plusDays(1);
}

How to countdown to a date in java? [duplicate]

This question already has answers here:
Timer - counting down and displaying result in specific format [duplicate]
(2 answers)
Closed 6 years ago.
So i am creating an application to countdown to a date in java.
So lets say i parse these 2 days:
Date Now = 2016/01/15 16:52:22
Date End = 2016/01/15 18:37:18
How would i calculate the differences so that i can get the output like so:
1 hour, 44 minutes and 56 seconds
instead of the total hours, total minutes and total seconds.
I guess the best way to explain it is that i need to get the seconds left of the minute, the minutes left of the hour, etc, etc.
You haven't specify your date format. Supposed you use the Date class, the following code gives you a difference in milliseconds.
long difference = dateEnd.getTime() - dateNow.getTime();
Then you approach to your result with a simple calculation:
int seconds = (int) (difference / 1000) % 60 ;
int minutes = (int) ((difference / (1000*60)) % 60);
int hours = (int) ((difference / (1000*60*60)) % 24);

Calculate difference between two hour's strings

I have a string that contain certain hour ex. 14:34, and now I want to calculate the difference between the current hour ex. 21:36-14:34=7 hours 2 minutes (or something like that.) Can someone explain me how can I do that?
It's very easy: You need to separate the string in terms you can add or substract:
String timeString1="12:34";
String timeString2="06:31";
String[] fractions1=timeString1.split(":");
String[] fractions2=timeString2.split(":");
Integer hours1=Integer.parseInt(fractions1[0]);
Integer hours2=Integer.parseInt(fractions2[0]);
Integer minutes1=Integer.parseInt(fractions1[1]);
Integer minutes2=Integer.parseInt(fractions2[1]);
int hourDiff=hours1-hours2;
int minutesDiff=minutes1-minutes2;
if (minutesDiff < 0) {
minutesDiff = 60 + minutesDiff;
hourDiff--;
}
if (hourDiff < 0) {
hourDiff = 24 + hourDiff ;
}
System.out.println("There are " + hourDiff + " and " + minutesDiff + " of difference");
UPDATE:
I'm rereading my answer and I'm surprised is not downvoted. My fault. I wrote it without any IDE check. So, the answer should be minutes1 and 2 for the minutesDiff and obviously and a check to carry the hour difference if the rest of minutes is negative, making minutes (60+minutesDiff). If minutes is negative, rest another hour to the hourDiff. If hours become negative too, make it (24+hourDiff). Now is fixed.
For the sake of fastness, I'm using a custom function. For the sake of scalability, read Nikola Despotoski answer and complete it with this:
System.out.print(Hours.hoursBetween(dt1, dt2).getHours() % 24 + " hours, ");
System.out.println(Minutes.minutesBetween(dt1, dt2).getMinutes() % 60 + " minutes, ");
I would start by using the .split method to get the string into its two components (minutes and hours) then I would convert both times into minutes by mutliplying the hours by 60 and then adding the minutes
String s = "14:34";
String[] sArr = s.split(",");
int time = Integer.parseInt(sArr[0]);
time *= 60;
int time2 = Integer.parseInt(sArr[1]);
time = time + time2;
do this for both strings and then subtract one from the other. You can convert back to normal time by using something like this
int hours = 60/time;
int minutes = 60%time;
The answer labeled as correct will not work. It does not account for if the first time is for example 3:17 and the second is 2:25. You end up with 1 hour and -8 minutes!

Represent date from long, starting from year 0 instead of 1970 [duplicate]

This question already has an answer here:
How to calculate difference between two dates in years...etc with Joda-Time
(1 answer)
Closed 8 years ago.
I have a long-variable which represents an amount of delay in milliseconds. I want to transform this long to some kind of Date where it says how many hours, minutes, seconds, days, months, years have passed.
When using Date toString() from Java, as in new Date(5).toString, it says 5 milliseconds have passed from 1970. I need it to say 5 milliseconds have passed, and 0 minutes, hours, ..., years.
you cannot get direct values , without any reference date for your requirements, you need define first reference value like below:
String dateStart = "01/14/2012 09:29:58";
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
Date d1 = format.parse(dateStart);
the above is your reference date , now you need to find the current date and time using following.
long currentDateTime = System.currentTimeMillis();
Date currentDate = new Date(currentDateTime);
Date d2.format(currentDate)
and the difference of these values like long diff=d2-d1 will gives values in milliseconds.
then
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
and similarly for months and years.
you can also refer the example given on this link for more information http://javarevisited.blogspot.in/2012/12/how-to-convert-millisecond-to-date-in-java-example.html
From what I understand from your question you could achieve your goal by writing a method that will suit your needs i.e.:
static public String dateFromMili (long miliseconds) {
// constants that will hold the number of miliseconds
// in a given time unit (year, month etc.)
final int YEAR_IN_MILISECONDS = 12*30*24*60*60*1000;
final int MONTH_IN_MILISECONDS = 30*24*60*60*1000;
final int DAY_IN_MILISECONDS = 24*60*60*1000;
final int HOUR_IN_MILISECONDS = 60*60*1000;
final int MINUTE_IN_MILISECONDS = 60*1000;
final int SECONDS_IN_MILISECONDS = 1000;
// now use those constants to return an appropriate string.
return miliseconds +" miliseconds, "
+miliseconds/SECONDS_IN_MILISECONDS+" seconds, "
+miliseconds/MINUTE_IN_MILISECONDS+" minutes, "
+miliseconds/HOUR_IN_MILISECONDS+" hours, "
+miliseconds/DAY_IN_MILISECONDS+" days, "
+miliseconds/MONTH_IN_MILISECONDS+" months, "
+miliseconds/YEAR_IN_MILISECONDS+" years have passed";
}
Than you will have to pas the number of miliseconds as a parameter to your new function that will return the desired String (i.e for two seconds):
dateFromMili (2000);
You could also print your answer:
System.out.println(dateFromMili(2000));
The result would look like this:
2000 miliseconds, 2 seconds, 0 minutes, 0 hours, 0 days, 0 months, 0 years have passed
Note that this method will return Strings with integer value (you will not get for example "2.222333 years" but "2 years"). Furthermore, it could be perfected by changing the noun from plural to singular, when the context is appropriate ("months" to "month").
I hope my answer helped.
This is how I solved the problem:
I used a library called Joda-Time (http://www.joda.org/joda-time/) (credits to Keppil!)
Joda-Time has various data-structures for Date and Time. You can represent a date and time by a DateTime-object.
To represent the delay I was looking for, I had two options: a Period data-structure or a Duration data-structure. A good explanation of the difference between those two can be found here: Joda-Time: what's the difference between Period, Interval and Duration? .
I thus used a Duration-object, based on the current date of my DateTime-object. It has all the methods to convert the amount of milliseconds to years, months, weeks, days, hours, minutes and seconds.

JodaTime Calculate total hours worked in a week

Currently I have a function which can take the start time and end time of one day, and calculate the difference between the two, giving me the hours worked in a day. What I would like to do is be able to get the hours worked for 7 days, and return a grand total, while remaining with the display format (HH:mm).
My function for a single day's total:
Period p = new Period(this.startTime[dayIndex], this.endTime[dayIndex]);
long hours = p.getHours();
long minutes = p.getMinutes();
String format = String.format("%%0%dd", 2);//Ensures that the minutes will always display as two digits.
return Long.toString(hours)+":"+String.format(format, minutes);
this.startTime[] & this.endTime[] are both arrays of DateTime objects.
Any suggestions?
You'll need something to hold a week's worth of days, and call your function once for each day.
But that means you'll want to refactor so that your calculator method doesn't format as a string, but instead returns a numeric value, so you can easily add them together.
Another simple solution:
Here is a method that receives separate the hours and minutes.The parameters are:
Start Hour
Start Minutes
End Hour
End Minutes
first, calculate the difference between hours and minutes separate:
int hours = pEndHour - pStartHour;
int minutes = ((60 - pStartMinutes) + pEndMinutes) - 60;
then, validates if the value of "minutes" variable is negative:
// If so, the "negative" value of minutes is our remnant to the next hour
if (minutes < 0) {
hours--;
minutes = 60 + minutes ;
}
Finally you can print the period of time in the hour format:
String format = String.format("%%0%dd", 2);
System.out.println( "*** " + hours + " : " + minutes);
That's all.
Solution I ended with for those interested
Period[] p=new Period[7];
long hours = 0;
long minutes =0;
for(int x=0; x<=this.daysEntered;x++)
{
p[x] = new Period(this.startTime[x], this.endTime[x]);
hours += p[x].getHours();
minutes += p[x].getMinutes();
}
hours += minutes/60;
minutes=minutes%60;
String format = String.format("%%0%dd", 2);
return Long.toString(hours)+":"+String.format(format, minutes);

Categories

Resources