I'm trying to shift datetime by a Duration which I get in the format "HHmm", for example "0010" meaning 10 minutes.
I've found similar ticket (Parsing time strings like "1h 30min") but I can't make it work properly.
Here's the code:
PeriodFormatter hoursMinutes = new PeriodFormatterBuilder().appendHours().appendMinutes().toFormatter();
Duration duration = hoursMinutes.parsePeriod("0010").toStandardDuration();
duration.getStandardMinutes(); //Returns 600
For some reason, I get 600 minutes instead of 10. So it looks like the minutes were interpreted as hours, but I can't understand why. I've tried adding .maximumParsedDigits(2) for hours, but the result was the same.
Why is my code wrong? Is there some other way to initialize duration parser? Something, where I could just use the standard format like "HHmm"?
So the issue was really with the maximum parseddigits. I only had to add it before hours, not minutes. So the solution is this:
PeriodFormatter hoursMinutes =
new PeriodFormatterBuilder().maximumParsedDigits(2).appendHours().appendMinutes().toFormatter();
Duration duration = hoursMinutes.parsePeriod("0010").toStandardDuration();
duration.getStandardMinutes(); //Returns 10
According to the documentation:
getStandardMinutes
public long getStandardMinutes()
Gets the length of this duration in minutes assuming that there are the standard number of milliseconds in a minute. This method assumes that there are 60 seconds in a minute and 1000 milliseconds in a second. All currently supplied chronologies use this definition.
This returns getMillis() / 60000. The result is an integer division,
thus excess milliseconds are truncated.
Returns: the length of the duration in standard seconds
Seeing as 600 is actually 10 minutes in seconds (60 * 10), you got the answer you expected.
Related
This question already has answers here:
How do I time a method's execution in Java?
(42 answers)
How to format a duration in java? (e.g format H:MM:SS)
(22 answers)
Closed 1 year ago.
I'm working on a program where I search through two text files and compare them (It's a task from JetBrains Academy). At the end I'm tasked to output the time it took to execute this, in the format of "mm:ss:ms". Picture as reference:
This is the code I've written to try to achieve this. I imagine it's pretty far from correct, so I apologize for this, I have been learning Kotlin and programming for not long.
val millis = System.currentTimeMillis()
val time = String.format("%1\$tM min. %1\$tS sec. %1\$tL ms.", millis);
println("Start searching...")
println("Found $number. Time taken: $time ")
The output I get is this:
> Start searching...
Found 864 / 864. Time taken: 19 min. 53 sec. 611 ms.
The minutes and seconds are wrong, as it took less than a second. I have doubts about the ms, as they would fit on how much time it took. Can someone help me with what I'm doing wrong? Thanks!
From System.currentTimeMillis():
Returns the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
So what you see in your output is the Hh:mm:ss portion of the time taken between 1970-01-01T00:00:00 up until now.
What you actually want is the taken time i.e the difference between start and end of your time measurement.
val start = System.currentTimeMillis()
// do your processing
val end = System.currentTimeMillis()
val time = String.format("%1$tM min. %1$tS sec. %1$tL ms.", end - start)
This should give you an appropriate output.
As noted in the comments weird stuff happens in some timezones. And String.format() seems to be quite unconfigurable (at least I didn't find anything).
If you really want to be on the safe side, you can use the answer suggested by #SergeyAfinogenov, but with some minor tweaks:
val minutes = duration.getSeconds() / 60
val seconds = duration.getSeconds() - minutes * 60
val millis = duration.getNano() / 1_000_000
val time = String.format("%d min. %d sec. %d ms.%n", minutes, seconds, millis)
This effectively manually calculates the different parts (minutes, seconds, millis) from the Duration and then formats them accordingly.
I would prefer to use Instant and ChronoUnit classes:
val now = Instant.now()
//doing something
val later = Instant.now()
val time = String.format("%02d min. %02d sec. %03d ms.",
ChronoUnit.MINUTES.between(now,later),
ChronoUnit.SECONDS.between(now,later)%60,
ChronoUnit.MILLIS.between(now,later)%1000
)
i am trying to find number of days from todays date from the below epoch timestamp:-
1560593315387
like this :
System.out.println(ChronoUnit.DAYS.between(Instant.ofEpochSecond(1558353632),Instant.now()));
It is working fine for 1558353632 but for 1560593315387 it cannot convert and not giving expected results.
1560593315387 looks to be milliseconds, not seconds, so use Instant.ofEpochMilli.
It is also too long (hah!) to fit into an int, so you have to use a long literal instead (with an L at the end).
ChronoUnit.DAYS.between(Instant.ofEpochMilli(1560593315387L), Instant.now())
Please do
int seconds = (int) 1560593315387l / 1000;// (millisecond to senconds conversion)
System.out.println(ChronoUnit.DAYS.between(Instant.ofEpochSecond(seconds), Instant.now()));
I am trying to convert code from Python to Java. I need to rewrite the timedelta function in Java. Here is the code in Python:
def timeDate(date):
return (timedelta(seconds=date * 3600 % 86400))
Does anyone have any idea on how to make a function that acts the same?
double hours = 21.37865107050986;
long nanos = Math.round(hours * TimeUnit.HOURS.toNanos(1));
Duration d = Duration.ofNanos(nanos);
// Delete any whole days
d = d.minusDays(d.toDays());
System.out.println(d);
This prints:
PT21H22M43.143853836S
Which means: a duration of 21 hours 22 minutes 43.143853836 seconds.
Assumptions: I understand that you want a duration (the docs you link to say “A timedelta object represents a duration”). I have taken date to be a floating-point number of hours, and your modulo operation lead me to believe that you want the duration modulo 1 day (so 26 hours should come out as a duration of 2 hours).
The Duration class in Java is for durations, hence is the one that you should use. It doesn’t accept a floating point number for creation, so I converted your hours so nanoseconds and rounded to whole number. For the conversion I multiplied by the number of nanoseconds in 1 hour, which I got from the call to TimeUnit (this gives clearer and less error-prone code than multiplying out ourselves).
The code above will tacitly give incorrect results for numerically large numbers of hours, so you should check the range before using it. Up to 2 500 000 hours (100 000 days or nearly 300 years) you should be safe.
Please note: if date was a time of day and not a duration, it’s a completely different story. In this case you should use LocalTime in Java. It’s exactly for a time of day (without date and without time zone).
nanos = nanos % TimeUnit.DAYS.toNanos(1);
LocalTime timeOfDay = LocalTime.ofNanoOfDay(nanos);
System.out.println(timeOfDay);
21:22:43.143853836
Link: Documentation of the Duration class
As far as I know, Java doesn't have a built in DeltaTime function. However you can easily make your own.long startTime;
long delta; public void deltaTime(){ long currentTime = System.currentTimeMillis(); delta = currentTime - startTime;}
Whenever you want to start your DeltaTime timer, you just do time = System.currentTimeMillis;. This way, the variable "delta" is the amount of time between when you started the DeltaTime timer and when you end it using ClassNameHere.deltaTime();.
private static LocalTime timeDate(double d) {
//converts into a local time
return LocalTime.ofSecondOfDay((long)(d*3600%86400));
}
Input (d):
36.243356711275794
Output:
21:22:43
i started with total milliseconds, which I've converted to to total minutes and total seconds:
long minutes = TimeUnit.MILLISECONDS.toMinutes(itemDuration);
long seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration)
- TimeUnit.MINUTES.toSeconds(minutes);
Now I want to display the minutes and seconds in a mm:ss format (and if occasionally there are hours, then convert to hh:mm:ss format). how would i go about doing this?
thanks!
edit: I've tried using SimpleDateFormat, however it would display the wrong time in time zone that differ by half an hour vs a full hour. (ie: if the time zone was GMT +5:30 and the item duraction was 5 seconds, the app would display 30:05 instead of 00:05).. however it works fine for other time zones that differ by a full hour, such as GMT+5.
unless i'm doing something wrong with the SimpleDateFormat?
private static final SimpleDateFormat mLengthFormatter = new SimpleDateFormat("mm:ss", Locale.getDefault());
(also, just out of curiosity, if I use a SimpleDateFormat, and the number of minutes is greater than 2 digits, then what would happen? would it max out at 99?)
Could probably do it with a string formatter.
formatter.format("%2d:%2d", minutes,seconds);
I got a millisecond value. I want to use a format string, to format those milliseconds into a time format. e.g. 45000ms = 45s or 0m 45s or whatever. So this is no special thing. I used SimpleDateFormat for this, but now comes my problem:
61000ms ends up in 1m 1s. This is okay for me, IF there is a minute given in the format string. But when there is no minute given in the format string, it should print out 61s instead of just 1s.
Is there any easy way to achieve this? Currently I dont see it without doing any ugly string formatting code.
I hope you can help me :)
Thanks in advanced!
slain
Edit:
For better understanding:
you got 65400 milliseconds.
format string has minutes, seconds, milliseconds: 1m 5s 400ms
format string has minutes and seconds: 1m 5s
format string has seconds: 65s
format string has seconds and milliseconds: 65s 4ms
format string has minutes and milliseconds: 1m 5400ms
I'm not sure what exactly you are trying to convert but have a look at time units.
If I understand correctly, you are given a number of milliseconds, and a time format string, and need to produce a correctly formatted time? If not, ignore the rest of this...
Maybe not the BEST way, but kind of a nice waterfall: Convert the milliseconds to a set of integers for days, hours, minutes, seconds (or more, or less, depending on the expected range), and then iterate forward through the format string. If day is present, great, stick the number of days in there. If not, skip it, multiply by 24 and add to hours. Do the same for hours->minutes, minutes->seconds, and you should end up with it correctly formatted, even if with weird formats (like days and seconds but not minutes).
Not exactly sure what you're looking for, but you can parse milliseconds like so;
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd MMM yyyy");
public static void main(String[] args) {
final long millis = System.currentTimeMillis();
System.out.println(DATE_FORMAT.format(new Date(millis))); // Prints 05 Aug 2011
}
Obviously, you can tweak the date format as necessary to display seconds, milliseconds, etc.