Получить разницу в датах
Мне нужно получить разницу в датах. К примеру у меня есть
Date dt = new Date();
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.MINUTE, 100);
dt = c.getTime();
И мне нужно получить разницу так, чтобы если сама разница была меньше часа, то указывались только минуты. Т.е. Разница 40 минут => На выходе было 40 минут а не 00:40:00. И так же с днями, месяцами и т.п. Если есть такой regex для локализации, то было бы круто если вы написали его.
Это нужно мне для указания даты окончания блокировки пользователя. А разница, чтобы получать число и отправлять его на итоге пользователю
Ответы (3 шт):
Для работы с датой и временем рекомендую использовать формат long, в миллисекундах. Сравнение, хранение и т.д.
public static long getMilliFromDate(String dateFormat) {
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
try {
date = formatter.parse(dateFormat);
} catch (ParseException e) {
e.printStackTrace();
}
//System.out.println("Today is " + date);
return date.getTime();
}
public static String getTimeStamp(long timeinMillies) {
String date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy"); // modify format
date = formatter.format(new Date(timeinMillies));
//System.out.println("Today is " + date);
return date;
}
Пример
Date currentDate = new Date();
DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy", Locale.getDefault());
long _date_warn = getMilliFromDate(dateFormat.format(currentDate));
// или
long _date_warn = getMilliFromDate("23.04.2021");
и обратно
String _date_str = getTimeStamp(long _date_warn);
Чтобы разобрать конкретно ваш пример, я его немного усложнил, поместив создание ваших переменных в конструктор. UPD :
public class TimeTest {
private Calendar c;
private static long secondsInDay = 86400000;
private static long secondsInHour = 3600000;
private static long secondsInMin = 60000;
public TimeTest(int testMin){
Date dt = new Date();
this.c = Calendar.getInstance();
this.c.setTime(dt);
this.c.add(Calendar.MINUTE, testMin);
}
public static void main(String[] args) {
TimeTest timeTest = new TimeTest(0); // Текущее время
TimeTest timeAfter = new TimeTest(61); // Время которое настанет(+минуты)
System.out.println(printMessage(timeTest,timeAfter));
//Непосредственно вывод результата
}
public static String printMessage(TimeTest old,TimeTest now){
String result = "Вы будете заблокированы через :" + System.lineSeparator()
+ getTimeOf(old,now,secondsInDay)
+ getTimeOf(old,now,secondsInHour)
+ getTimeOf(old,now,secondsInMin);
return result;
}
private static String getTimeOf(TimeTest old, TimeTest now,long divider){
long rr = now.getC().getTimeInMillis() - old.getC().getTimeInMillis();
long dd = rr/(divider);
dd = extendMinCalc(dd,divider);
return dd > 0 ? dd + getWord(divider) : "";
// if value > 0 ? (yes) return value + key :
// (no) return empty
}
private static long extendMinCalc(long a, long devider){
if(devider==secondsInHour){
if (a<=24){return a;}
long c = a-24;
if(c>24){
c = extendMinCalc(c,devider);
return c;
}
else return c;
}
if(devider==secondsInMin){
if(a<=60){return a;}
long c = a-60;
if(c>60) {
c = extendMinCalc(c,devider);
return c;
}
else return c;
}
return a; // if day
// cant be more 365 :D
}
private static String getWord(long value){
String keyWord = "";
if(value==secondsInDay){keyWord=" Day ";}
if(value==secondsInHour){keyWord=" Hour ";}
if(value==secondsInMin){keyWord=" Min ";}
return keyWord;
}
public Calendar getC() {
return c;
}
}
Один из вариантов решения, основанный на использовании класса, специально предназначенного для работы с временными интервалами:
public static String appendTime(String source, long value, String suffix) {
String result = "";
if (source.isEmpty()) {
result = (value != 0) ? value + suffix : "";
} else {
result = source + ", " + value + suffix;
}
return result;
}
public static String getHumanReadableTimeBetween(Date leftBound, Date rightBound) {
Duration duration = Duration.between(leftBound.toInstant(), rightBound.toInstant());
String result = appendTime("", duration.toDaysPart(), "days");
result = appendTime(result, duration.toHoursPart(), "hours");
result = appendTime(result, duration.toMinutesPart(), "minutes");
result = appendTime(result, duration.toSecondsPart(), "seconds");
return result;
}
public static void main(String[] args) {
// среда, конец дня
Calendar leftBound = new Calendar.Builder().setDate(2021, 02, 31).setTimeOfDay(23, 50, 38).build();
// понедельник, начало дня
Calendar rightBound = new Calendar.Builder().setDate(2021, 03, 05).setTimeOfDay(05, 21, 11).build();
System.out.println(getTimeBetween(leftBound.getTime(), rightBound.getTime()));
}
Вывод: 4days, 5hours, 30minutes, 33seconds
Upd
действительно, как указал в комментарии @Sergey, getXXXPart появился в Java 9. Вариант для 8 версии, не особо отличающийся от обычных арифметических вычислений (публикую только изменившийся метод):
public static String getTimeBetween(Date leftBound, Date rightBound) {
Duration duration = Duration.between(leftBound.toInstant(), rightBound.toInstant());
long value = duration.toDays();
duration = duration.minusDays(value);
String result = appendTime("", value, "days");
value = duration.toHours();
duration = duration.minusHours(value);
result = appendTime(result, value, "hours");
value = duration.toMinutes();
duration = duration.minusMinutes(value);
result = appendTime(result, value, "minutes");
value = duration.getSeconds();
result = appendTime(result, value, "seconds");
return result;
}