Получить разницу в датах

Мне нужно получить разницу в датах. К примеру у меня есть

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 шт):

Автор решения: Arty Morris

Для работы с датой и временем рекомендую использовать формат 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);
→ Ссылка
Автор решения: Perfect Voyage

Чтобы разобрать конкретно ваш пример, я его немного усложнил, поместив создание ваших переменных в конструктор. 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;
    }
}
→ Ссылка
Автор решения: kami

Один из вариантов решения, основанный на использовании класса, специально предназначенного для работы с временными интервалами:

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;
}
→ Ссылка