Converting running pace - java

I'm trying to convert a running pace that I get in the format of a String (say : "5:00" for a 5 min/mile). (I am converting min/mile to min/km).
So here's what I'm doing :
String milePace = "05:00";
DateFormat sdf = new SimpleDateFormat("mm:ss");
Date date = sdf.parse(milePace);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
long mileTime = cal.getTimeInMillis();
long kmPace = Math.round(mileTime * 0.623712);
cal.setTimeInMillis(kmPace);
This unfortunately makes sense to me, but does not work.
0.623712 would be the converting unit and does work (as long as I am concerned).
When I check the value of mileTime I get 18240000. As far I can see, this is the issue as this value should be 240000 (which would be 4mins * 60 secs * 1000)
Is there an issue with the code or is there something from the cal function that would give me that extra 18000000 miliseconds?
Thanks in advance!

getTimeInMillis() returns the number of milliseconds since 1970 UTC. It will be affected by the time zone of your parser, and what date the parser decides to use for your input.
I would suggest that you use Joda Time and parse the value as a Period instead.
Sample code:
import org.joda.time.*;
import org.joda.time.format.*;
import java.util.*;
public class Test {
public static void main(String[] args) {
String text = "05:00";
PeriodFormatter formatter = new PeriodFormatterBuilder()
.minimumPrintedDigits(2)
.appendMinutes()
.appendSeparator(":")
.appendSeconds()
.toFormatter();
Period milePeriod = formatter.parsePeriod(text);
long mileMillis = milePeriod.toStandardDuration().getMillis();
long kmMillis = Math.round(mileMillis * 0.623712);
PeriodType minutesSeconds = PeriodType.time()
.withMillisRemoved()
.withHoursRemoved();
Period kmPeriod = new Period(kmMillis, minutesSeconds);
System.out.println(formatter.print(kmPeriod)); // Prints 03:07
}
}

The problem is your
Calendar.getInstance(); change this to
Calendar cal = new GregorianCalendar();
cal.set(<Calendar Constants); Reference
long miletime = cal.getTimeInMillis();

If you know that your time will stay between 0s and 59 mins inclusive, with a granularity of 1s, you could do it like this:
s = new java.text.SimpleDateFormat ("s");
m = new java.text.SimpleDateFormat ("m");
int secs = Integer.parseInt (s.format (sdf.parse ("05:00")));
int mins = Integer.parseInt (m.format (sdf.parse ("05:00")));
Adding hours might not be necessary - or do you measure something that slow?

Related

How to do time running using Java

I have start_time and end_Time, so I tried to print those interval_times (time format 24).
How do I do it?
int start = Integer.parseInt("10:24:49");
int end = Integer.parseInt("11:24:49");
for (int i = start; i < end; i++)
{
System.out.println("result i ="+ i);
}
Since Java 8, the java.time package has been the optimal way to do all date/time related things.
It takes some getting used to, e.g. when it comes to timezones, but it's absolutely worth the effort!
Here's the code for your seconds printer:
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public static void main(final String[] args) {
// Just so you know it in the future. Not needed in this example.
final DateTimeFormatter dtfDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.US);
final DateTimeFormatter dtfTime = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.US);
final LocalTime ltStart = LocalTime.of(10, 24, 49);
final LocalTime ltEnd = ltStart.plusHours(1);
// If you want to use String parsing to get your instance:
final LocalTime ltStartViaParsing = LocalTime.from(dtfTime.parse("10:24:49"));
LocalTime i = ltStart;
while (i.isBefore(ltEnd)) {
System.out.println("result i = " + dtfTime.format(i));
i = i.plusSeconds(1);
}
}
Output:
result i = 10:24:49
result i = 10:24:50
result i = 10:24:51
...
result i = 11:24:46
result i = 11:24:47
result i = 11:24:48
It looks like you want to run the loop for particular duration of time.
In case you want to run the loop for fixed duration like for 5 minutes, with a 5 second interval, you can do it like this:
try {
// This loop will run for 5 minutes for every 5 second delay
for(int i=0;i<60;i++) {
System.out.println(new Date());
Thread.sleep(5 * 1000);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
Before using, see comments below.
If you are intending to print every hour between two given times, then you are totally on the wrong path.
Integer.parseInt
It is intended to get a String number and converts it to Java Integer.
Try to use SimpleDateFormat and Date and Calendar
String startTime = "10:24:49";
String endTime = "11:24:49";
DateFormat sdf = new SimpleDateFormat("hh:mm:ss");
Calendar calendar = Calendar.getInstance();
calendar.setTime(sdf.parse(startTime));
int start = calendar.get(Calendar.HOUR_OF_DAY);
calendar.setTime(sdf.parse(endTime));
int end = calendar.get(Calendar.HOUR_OF_DAY);
This may help:
DateTime startTime, endTime;
Period p = new Period(startTime, endTime);
int hours = p.getHours();
int minutes = p.getMinutes();
And also you can use Java.util.Timer to schedule a thread to be executed at a certain time in the future.

Set new time after the actual one

I'm trying to create a method that prints e.g. actual time of arrival (now) and then it prints the time of departure which I want to set plus 3 minutes compared to the first one.
public void updateTimes(){
SimpleDateFormat sdf = new SimpleDateFormat("H:mm");
this.arrivalTime = new Date();
this.departureTime = this.arrivalTime.plusMinutes(3);
}
Departure time doesn't work as intended.
Any help is welcome.
java.util.Date not have plusMinutes.
It can be better if you use Java 8, with java.time library :
LocalTime arrivalTime = LocalTime.now();//Current time
LocalTime departureTime = arrivalTime.plusMinutes(3);//plus 3 minutes to the time
//Then you can format the time
String result = departureTime.format(DateTimeFormatter.ofPattern("H:mm"));
Another solution using Calendar looks like:
Calendar cal = Calendar.getInstance();
cal.setTime(arrivalTime); // only if different from "now"
cal.add(Calendar.MINUTE, 3);
departureTime = cal.getTime();
I think you can do something like below:
SimpleDateFormat sdf = new SimpleDateFormat("H:mm");
Date date = new Date();
System.out.println("arrival time = " + sdf.format(date));
int min = date.getMinutes();
date.setMinutes(min+3);
System.out.println("departure time = " + sdf.format(date));

Creating date using integers and displaying in a textbox [duplicate]

This question already has answers here:
Convert linux timestamp to android date
(4 answers)
Closed 5 years ago.
I am new to Android Studio and have ran into a problem - I am trying to carry out a calculation whereby I need the current date and time in an integer format. I also need the current date and time to then display in a TextBox.
I have declared the date as an integer as follows:
public static int date1 = (int) (new Date().getTime()/1000);
datedisplay = (TextView) findViewById(R.id.date);
Then I have tried to get the current date and time displayed in a textbox, but it isn't displaying. I was just wondering would anyone know why?
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm");
System.out.println(new Date(new Date(date1).getTime()));
datedisplay.setText(dateFormat.format(date1));
Thank you in advance
Use it in any datatype you want either String or Integer.
java.util.Date date= new java.util.Date();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date.getTime());
datedisplay.setText(timeStamp);
new Date().getTime() ; return long value if you diving it by 1000
to convert long to int
better if you use long:
long date1 = new Date().getTime() ;
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm");
Date dt = new Date(date1);
datedisplay.setText(dateFormat.format(dt));
You can also use Calendar class:
Calendar myCalendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy HH:mm",Locale.getDefault());
String dateString = sdf.format(myCalendar.getTime());
then
datedisplay.setText(dateString);
If you really want to use a int to store your date representation, just use the number of day since the epoch instead of the number of seconds
new Date().getTime()
/1000 //second
/60 //minute
/60 //hour
/24; //day
This will give you a value that will fit in a int for quite some time.
But of course you won't be able to get back the exact precision, if you want the Time part of the Date, you won't be able to. This only allows you to get the Date like yyyy-MM-dd
private static final long EPOCH_DAY = 1000L * 60 * 60 * 24;
public static void main(String[] args){
int i = (int) (new Date().getTime()/EPOCH_DAY);
System.out.println(new Date(i * EPOCH_DAY));
}
Fri Nov 03 01:00:00 CET 2017
(the hours is because of my local being in GMT+1)

How to calculate remaining days?

private long calculateRemainingDays() {
final Calendar c = Calendar.getInstance();
c.set(2015, 7, 23);
final Calendar today = Calendar.getInstance();
final long millis = c.getTimeInMillis()
- today.getTimeInMillis();
// Convert to days
final long days = millis / 86400000;
return days;
}
I need to add a function in my android application. I want a remaining days from current day to 2015/9/30. When the date is change to next day, the remaining days will decrease. I would like to say like that:
7 days remaining... 6/5/4/etc... Please help me to get correct remaining days. Sorry for my poor english. Thanks!
Use Calender.JULY instead of 7 in the parameters for the set() method.
7 = August.
6 = July.
As it starts with January as 0. It's better to use the static instance variables like Calender.JANUARY.
But as you want to calculate till 2015/9/30, you should set the value as
c.set(2015, Calender.SEPTEMBER, 09);
The rest of the code seems ok. It will return the correct number of days.
Try this :-
final long millis = c.getTimeInMillis()
- today.getTimeInMillis();
System.out.println ("Days: " + TimeUnit.DAYS.convert(millis , TimeUnit.MILLISECONDS));
if you don't mind using joda.time
you can do something of this form:
final Calendar c = Calendar.getInstance();
c.set(2015, Calender.SEPTEMBER, 30);
Date endDate = c.getTime();
Instant startInstant = new Instant(new Date());
Instant endInstant = new Instant(endDate);
Days days = Days.daysBetween(startInstant, endInstant);

How to convert HH:mm:ss.SSS to milliseconds?

I have a String 00:01:30.500 which is equivalent to 90500 milliseconds. I tried using SimpleDateFormat which give milliseconds including current date. I just need that String representation to milliseconds. Do I have to write custom method, which will split and calculate milliseconds? or Is there any other way to do this? Thanks.
I have tried as follows:
String startAfter = "00:01:30.555";
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
Date date = dateFormat.parse(startAfter);
System.out.println(date.getTime());
You can use SimpleDateFormat to do it. You just have to know 2 things.
All dates are internally represented in UTC
.getTime() returns the number of milliseconds since 1970-01-01 00:00:00 UTC.
package se.wederbrand.milliseconds;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String inputString = "00:01:30.500";
Date date = sdf.parse("1970-01-01 " + inputString);
System.out.println("in milliseconds: " + date.getTime());
}
}
If you want to parse the format yourself you could do it easily with a regex such as
private static Pattern pattern = Pattern.compile("(\\d{2}):(\\d{2}):(\\d{2}).(\\d{3})");
public static long dateParseRegExp(String period) {
Matcher matcher = pattern.matcher(period);
if (matcher.matches()) {
return Long.parseLong(matcher.group(1)) * 3600000L
+ Long.parseLong(matcher.group(2)) * 60000
+ Long.parseLong(matcher.group(3)) * 1000
+ Long.parseLong(matcher.group(4));
} else {
throw new IllegalArgumentException("Invalid format " + period);
}
}
However, this parsing is quite lenient and would accept 99:99:99.999 and just let the values overflow. This could be a drawback or a feature.
Using JODA:
PeriodFormatter periodFormat = new PeriodFormatterBuilder()
.minimumParsedDigits(2)
.appendHour() // 2 digits minimum
.appendSeparator(":")
.minimumParsedDigits(2)
.appendMinute() // 2 digits minimum
.appendSeparator(":")
.minimumParsedDigits(2)
.appendSecond()
.appendSeparator(".")
.appendMillis3Digit()
.toFormatter();
Period result = Period.parse(string, periodFormat);
return result.toStandardDuration().getMillis();
If you want to use SimpleDateFormat, you could write:
private final SimpleDateFormat sdf =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
{ sdf.setTimeZone(TimeZone.getTimeZone("GMT")); }
private long parseTimeToMillis(final String time) throws ParseException
{ return sdf.parse("1970-01-01 " + time).getTime(); }
But a custom method would be much more efficient. SimpleDateFormat, because of all its calendar support, time-zone support, daylight-savings-time support, and so on, is pretty slow. The slowness is worth it if you actually need some of those features, but since you don't, it might not be. (It depends how often you're calling this method, and whether efficiency is a concern for your application.)
Also, SimpleDateFormat is non-thread-safe, which is sometimes a pain. (Without knowing anything about your application, I can't guess whether that matters.)
Personally, I'd probably write a custom method.
I am presenting two options:
Time4J, an advanced external date, time and time interval library.
java.time, the built-in modern Java date and time API.
SimpleDateFormat and Date are the wrong classes to use, both because a duration of 1 minute 30.5 seoncds is not a date and because those classes have long gone out of any reasonable use.
Time4J
This is the elegant solution. We first declare a formatter:
private static final Duration.Formatter<ClockUnit> DURATION_FORMAT
= Duration.formatter(ClockUnit.class, "hh:mm:ss.fff");
Then parse and convert to milliseconds like this:
String startAfter = "00:01:30.555";
Duration<ClockUnit> dur = DURATION_FORMAT.parse(startAfter);
long milliseconds = dur.with(ClockUnit.MILLIS.only())
.getPartialAmount(ClockUnit.MILLIS);
System.out.format("%d milliseconds%n", milliseconds);
Output is:
90555 milliseconds
java.time
The java.time.Duration class can only parse ISO 8601 format. So I am first converting your string to that format. It goes like PT00H01M30.555S (the leading zeroes are not required, but why should I bother removing them?)
String startAfter = "00:01:30.555";
String iso = startAfter.replaceFirst(
"^(\\d{2}):(\\d{2}):(\\d{2}\\.\\d{3})$", "PT$1H$2M$3S");
Duration dur = Duration.parse(iso);
long milliseconds = dur.toMillis();
System.out.format("%d milliseconds%n", milliseconds);
Output is the same as before:
90555 milliseconds
Another difference from Time4J is that the Java Duration can be directly converted to milliseconds without being converted to a Duration of only milliseconds first.
Links
Time4J - Advanced Date, Time, Zone and Interval Library for Java
Oracle tutorial: Date Time explaining how to use java.time.

Categories