forked from upstream-mirrors/OpenTracks
Replace long time_ms with Instant and Duration, respectively.
Fixes #561.
This commit is contained in:
@@ -4,13 +4,16 @@ import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||
|
||||
public class AnnouncementUtils {
|
||||
|
||||
private AnnouncementUtils() {}
|
||||
private AnnouncementUtils() {
|
||||
}
|
||||
|
||||
public static String getAnnouncement(Context context, TrackStatistics trackStatistics, String category, @Nullable IntervalStatistics.Interval currentInterval) {
|
||||
boolean metricUnits = PreferencesUtils.isMetricUnits(context);
|
||||
@@ -41,11 +44,11 @@ public class AnnouncementUtils {
|
||||
} else {
|
||||
double timePerDistance = distancePerTime == 0 ? 0.0 : 1 / distancePerTime;
|
||||
int paceId = metricUnits ? R.string.voice_pace_per_kilometer : R.string.voice_pace_per_mile;
|
||||
long time = Math.round(timePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS);
|
||||
Duration time = Duration.ofMillis((long) (timePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS));
|
||||
rate = context.getString(paceId, getAnnounceTime(context, time));
|
||||
|
||||
double currentTimePerDistance = currentDistancePerTime == 0 ? 0.0 : 1 / currentDistancePerTime;
|
||||
long currentTime = Math.round(currentTimePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS);
|
||||
Duration currentTime = Duration.ofMillis((long) (currentTimePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS));
|
||||
currentRate = context.getString(paceId, getAnnounceTime(context, currentTime));
|
||||
currentRateMsg = context.getString(R.string.voice_pace_lap, currentRate);
|
||||
}
|
||||
@@ -58,23 +61,25 @@ public class AnnouncementUtils {
|
||||
return context.getString(R.string.voice_template, totalDistance, getAnnounceTime(context, trackStatistics.getMovingTime()), rate) + currentRateMsg;
|
||||
}
|
||||
|
||||
private static String getAnnounceTime(Context context, long time) {
|
||||
int[] parts = StringUtils.getTimeParts(time);
|
||||
String seconds = context.getResources()
|
||||
.getQuantityString(R.plurals.voiceSeconds, parts[0], parts[0]);
|
||||
String minutes = context.getResources()
|
||||
.getQuantityString(R.plurals.voiceMinutes, parts[1], parts[1]);
|
||||
String hours = context.getResources()
|
||||
.getQuantityString(R.plurals.voiceHours, parts[2], parts[2]);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (parts[2] != 0) {
|
||||
sb.append(hours);
|
||||
sb.append(" ");
|
||||
//TODO We might need to localize this using strings.xml if order is relevant.
|
||||
private static String getAnnounceTime(Context context, Duration duration) {
|
||||
String result = "";
|
||||
|
||||
int hours = (int) (duration.getSeconds() / (60 * 60));
|
||||
int minutes = (int) (duration.getSeconds() / 60);
|
||||
int seconds = (int) (duration.getSeconds() % 60);
|
||||
|
||||
if (hours != 0) {
|
||||
String hoursText = context.getResources()
|
||||
.getQuantityString(R.plurals.voiceHours, hours, hours);
|
||||
result += hoursText + " ";
|
||||
}
|
||||
sb.append(minutes);
|
||||
sb.append(" ");
|
||||
sb.append(seconds);
|
||||
return sb.toString();
|
||||
String minutesText = context.getResources()
|
||||
.getQuantityString(R.plurals.voiceMinutes, minutes, minutes);
|
||||
String secondsText = context.getResources()
|
||||
.getQuantityString(R.plurals.voiceSeconds, seconds, seconds);
|
||||
|
||||
return result + minutesText + " " + secondsText;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,9 @@ package de.dennisguse.opentracks.util;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
|
||||
/**
|
||||
@@ -28,8 +31,7 @@ public class LocationUtils {
|
||||
|
||||
private static final String TAG = LocationUtils.class.getSimpleName();
|
||||
|
||||
// 1 minute in milliseconds
|
||||
private static final long MAX_LOCATION_AGE_MS = (long) (UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS);
|
||||
private static final Duration MAX_LOCATION_AGE = Duration.ofMinutes(1);
|
||||
|
||||
private LocationUtils() {
|
||||
}
|
||||
@@ -48,6 +50,8 @@ public class LocationUtils {
|
||||
}
|
||||
|
||||
public static boolean isTrackPointOld(TrackPoint trackPoint) {
|
||||
return System.currentTimeMillis() - trackPoint.getTime() > MAX_LOCATION_AGE_MS;
|
||||
return Duration.between(trackPoint.getTime(), Instant.now())
|
||||
.minus(MAX_LOCATION_AGE)
|
||||
.isNegative();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,11 @@ import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
@@ -50,41 +53,32 @@ public class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the date and time_ms based on user's phone date/time_ms preferences.
|
||||
*
|
||||
* @param context the context
|
||||
* @param time_ms the time_ms in milliseconds
|
||||
* Formats the date and time based on user's phone date/time preferences.
|
||||
*/
|
||||
public static String formatDateTime(Context context, long time_ms) {
|
||||
return DateUtils.formatDateTime(context, time_ms, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE)
|
||||
+ " " + DateUtils.formatDateTime(context, time_ms, DateUtils.FORMAT_SHOW_TIME);
|
||||
public static String formatDateTime(Context context, Instant time) {
|
||||
return DateUtils.formatDateTime(context, time.toEpochMilli(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE)
|
||||
+ " " + DateUtils.formatDateTime(context, time.toEpochMilli(), DateUtils.FORMAT_SHOW_TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the time using the ISO 8601 date time_ms format with fractional seconds in UTC time zone.
|
||||
*
|
||||
* @param time_ms the time in milliseconds
|
||||
* Formats the time using the ISO 8601 date time format with fractional seconds in UTC time zone.
|
||||
*/
|
||||
public static String formatDateTimeIso8601(long time_ms) {
|
||||
return Instant.ofEpochMilli(time_ms).toString();
|
||||
public static String formatDateTimeIso8601(@NonNull Instant time) {
|
||||
return time.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the elapsed timed in the form "MM:SS" or "H:MM:SS".
|
||||
*
|
||||
* @param time_ms the time in milliseconds
|
||||
*/
|
||||
public static String formatElapsedTime(long time_ms) {
|
||||
return DateUtils.formatElapsedTime((long) (time_ms * UnitConversions.MS_TO_S));
|
||||
public static String formatElapsedTime(@NonNull Duration time) {
|
||||
return DateUtils.formatElapsedTime(time.getSeconds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the elapsed time in the form "H:MM:SS".
|
||||
*
|
||||
* @param time_ms the time in milliseconds
|
||||
*/
|
||||
public static String formatElapsedTimeWithHour(long time_ms) {
|
||||
String value = formatElapsedTime(time_ms);
|
||||
public static String formatElapsedTimeWithHour(@NonNull Duration time) {
|
||||
String value = formatElapsedTime(time);
|
||||
return TextUtils.split(value, ":").length == 2 ? "0:" + value : value;
|
||||
}
|
||||
|
||||
@@ -289,45 +283,20 @@ public class StringUtils {
|
||||
*
|
||||
* @param xmlDateTime the XML date time string
|
||||
*/
|
||||
public static long parseTime(String xmlDateTime) {
|
||||
public static Instant parseTime(String xmlDateTime) {
|
||||
try {
|
||||
TemporalAccessor t = DateTimeFormatter.ISO_DATE_TIME.parseBest(xmlDateTime, ZonedDateTime::from, LocalDateTime::from);
|
||||
if (t instanceof LocalDateTime) {
|
||||
Log.w(TAG, "Date does not contain timezone information: using UTC.");
|
||||
t = ((LocalDateTime) t).atZone(ZoneOffset.UTC);
|
||||
}
|
||||
return Instant.from(t).toEpochMilli();
|
||||
return Instant.from(t);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Invalid XML dateTime value");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time as an array of three integers.
|
||||
* Index 0 contains the number of seconds, index 1 contains the number of minutes, and index 2 contains the number of hours.
|
||||
*
|
||||
* @param time the time in milliseconds
|
||||
* @return an array of 3 elements.
|
||||
*/
|
||||
public static int[] getTimeParts(long time) {
|
||||
if (time < 0) {
|
||||
int[] parts = getTimeParts(time * -1);
|
||||
parts[0] *= -1;
|
||||
parts[1] *= -1;
|
||||
parts[2] *= -1;
|
||||
return parts;
|
||||
}
|
||||
int[] parts = new int[3];
|
||||
|
||||
long seconds = (long) (time * UnitConversions.MS_TO_S);
|
||||
parts[0] = (int) (seconds % 60);
|
||||
int minutes = (int) (seconds / 60);
|
||||
parts[1] = minutes % 60;
|
||||
parts[2] = minutes / 60;
|
||||
return parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the frequency display options.
|
||||
*
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Locale;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
@@ -40,20 +41,13 @@ public class TrackNameUtils {
|
||||
private TrackNameUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the track name.
|
||||
*
|
||||
* @param context the context
|
||||
* @param trackId the track id
|
||||
* @param startTime the track start time
|
||||
*/
|
||||
public static String getTrackName(Context context, Track.Id trackId, long startTime) {
|
||||
public static String getTrackName(Context context, Track.Id trackId, Instant startTime) {
|
||||
String trackName = PreferencesUtils.getString(context, R.string.track_name_key, context.getString(R.string.track_name_default));
|
||||
|
||||
if (trackName.equals(context.getString(R.string.settings_recording_track_name_date_local_value))) {
|
||||
return StringUtils.formatDateTime(context, startTime);
|
||||
} else if (trackName.equals(context.getString(R.string.settings_recording_track_name_date_iso_8601_value))) {
|
||||
return new SimpleDateFormat(ISO_8601_FORMAT, Locale.US).format(startTime);
|
||||
return new SimpleDateFormat(ISO_8601_FORMAT, Locale.US).format(startTime.toEpochMilli());
|
||||
} else {
|
||||
return context.getString(R.string.track_name_format, trackId.getId());
|
||||
}
|
||||
|
||||
@@ -18,22 +18,6 @@ public class TrackPointUtils {
|
||||
return trackPoint.hasSpeed() && trackPoint.getSpeed() >= MAX_NO_MOVEMENT_SPEED;
|
||||
}
|
||||
|
||||
public static boolean equalTime(TrackPoint t1, TrackPoint t2) {
|
||||
if (t1 == null || t2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return t1.getTime() == t2.getTime();
|
||||
}
|
||||
|
||||
public static boolean after(TrackPoint t1, TrackPoint t2) {
|
||||
if (t1 == null || t2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return t1.getTime() > t2.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is accuracy better than threshold?
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user