Java LocalDateTime minusYears для плавающего количества лет

Java LocalDateTime minusYears принимает длинный аргумент. В случае, если я хочу минус плавающее число года, например. 2,5 года, как я могу это сделать?

Есть ли встроенная поддержка?

Примечание. Я принимаю как значение, так и единицу измерения от пользователя. Вышеупомянутый вопрос немного обобщает (у меня такая же проблема с часами, годами, неделями и т. д.). Иногда это может быть 2,7 часа или 2,8 года или 5,3 недели и т. д.


person Kumar    schedule 31.07.2018    source источник
comment
Используйте минусГоды(2).минусМесяцы(6).   -  person Coder-Man    schedule 31.07.2018
comment
@Вау, спасибо! Я получаю эти значения в качестве входных данных. 2.5 (2 года и 6 месяцев) — это просто, но в случае, если кто-то даст 2.7 или 2.8, я чувствую, что ручное преобразование будет громоздким.   -  person Kumar    schedule 31.07.2018
comment
Вопрос в том, как вы можете отличить ввод, например, если пользователь вводит 2,7 часа или 2,8 года или 5,3 недели?   -  person YCF_L    schedule 31.07.2018
comment
@YCF_L: это я могу понять. Я получаю дату, значение с плавающей запятой и единицу измерения в качестве входных данных   -  person Kumar    schedule 31.07.2018


Ответы (4)


У вас нет встроенной поддержки для этого, но вы можете легко сделать это, преобразовав значение year в месяц (* 12):

float year = 2.5F;
LocalDateTime dateTime = dateTime.minusMonths((int)(year * 12);

И вы также можете создать метод util, если это необходимо:

public static LocalDateTime removeYear(LocalDateTime dateTime, float year) {
    int monthToRemove = (int)(year * 12);
    return dateTime.minusMonths(monthToRemove);
}

Протестировав его с помощью:

public static void main(String[] args) {
    LocalDateTime date = removeYear(LocalDateTime.now(), 2.5F);
    System.out.println(date);
}

Выход :

2016-01-31T16:33:26.755

Обратите внимание: чтобы сделать метод более надежным, вы можете проверить, что year представляет собой число с плавающей запятой, которое принимает только некоторые типы значений, такие как ноль для дробной части (2.0) или некоторые дробные части, такие как 0.5.

person davidxxx    schedule 31.07.2018

Как насчет :

double years = 2.5;
long months = (long) (years * 12);// 30 month
LocalDateTime ld = LocalDateTime.now();
ld = ld.minusMonths(months);

Но обратите внимание, что это может привести к потере нескольких дней, например, если у вас есть:

years = 2.7
=>years * 12 > 32.400000000000006

так что здесь можно потерять 0.400000000000006 месяца.

Так что, возможно, если вы округлите его, это может быть более полезным:

long months = Math.round(years * 12);

Редактировать :

на основании вашего комментария:

На самом деле я принимаю как значение, так и единицу измерения в качестве входных данных. Вышеупомянутый вопрос является небольшим обобщением. Иногда это может быть 2,7 часа или 2,8 года или 5,3 недели и т. д.

Я думаю, вам нужно что-то вроде этого:

Но будьте осторожны с месяцами

public static LocalDateTime changeDate(LocalDateTime date, float time, String unit) {
    long newTime;
    switch (unit) {
        case ("hour"):
            newTime = Math.round(time * 60);
            date = date.minusMinutes(newTime);// If hours then subtract minutes
            break;
        case ("day"):
            newTime = Math.round(time * 24);
            date = date.minusHours(newTime);// If days then subtract hours
            break;
        case ("week"):
            newTime = Math.round(time * 7);
            date = date.minusDays(newTime);// If week then subtract days
            break;
        case ("month"):
            newTime = Math.round(time * 30);// here You have to check again
            date = date.minusDays(newTime);// If month then subtract days
            break;
        case ("year"):
            newTime = Math.round(time * 12);
            date = date.minusMonths(newTime);// If days then subtract months
            break;
        default:
            break;
    }
    return date;
}
person YCF_L    schedule 31.07.2018
comment
На самом деле я принимаю как значение, так и единицу измерения в качестве входных данных. Вышеупомянутый вопрос является небольшим обобщением. Иногда это может быть 2,7 часа, 2,8 года, 5,3 недели и т. д. - person Kumar; 31.07.2018
comment
@Abhinav, откуда вы берете данные? из базы данных? - person YCF_L; 31.07.2018
comment
Мой метод принимает дату, значение с плавающей запятой и единицу измерения в качестве входных данных - person Kumar; 31.07.2018
comment
@YCF_L Кажется, это проще :) - person davidxxx; 31.07.2018
comment
Вы должны заменить String unit на ChronoUnit unit и обновить дела. Хотя я обновляю свой ответ, чтобы сделать его более общим, но сейчас не время :) - person davidxxx; 31.07.2018


Встроенной поддержки нет, но вы можете сделать это, если хотите пожертвовать точностью:

public static void main(String[] args) {
    LocalDate ld = LocalDate.of(2015, 12, 1);
    System.out.println(minusFpYears(ld, 2.5f));
}
static LocalDate minusFpYears(LocalDate ld, float fpyears) {
    float fpmonths = fpyears % 1;
    long years = (long)(fpyears - fpmonths);
    long months = (long)(12L * fpmonths);
    return ld.minusYears(years).minusMonths(months);
}

Спасибо за код! На самом деле я принимаю как значение, так и единицу измерения в качестве входных данных. Вышеупомянутый вопрос является небольшим обобщением. Иногда это может быть 2,7 часа, 2,8 года, 5,3 недели и т. д.

Создайте функции LocalDate minusFpWeeks(LocalDate ld, float fpweeks), LocalDateTime minusFpHours(LocalDateTime ld, float fphours) и т. д., чтобы справиться с этим.

person Coder-Man    schedule 31.07.2018
comment
Спасибо за код! На самом деле я принимаю как значение, так и единицу измерения в качестве входных данных. Вышеупомянутый вопрос является небольшим обобщением. Иногда это может быть 2,7 часа, 2,8 года, 5,3 недели и т. д. - person Kumar; 31.07.2018
comment
@Abhinav, вы можете соответствующим образом обработать каждый из этих случаев, используя функции minusWeeks, minusHours и т. Д., Я не буду описывать все за вас. В течение нескольких часов вам придется использовать LocalDateTime. - person Coder-Man; 31.07.2018
comment
Спасибо! Если нет другого варианта, то я напишу аналогичный код для всех функций - person Kumar; 31.07.2018
comment
@Abhinav да, я больше ничего не могу предложить. - person Coder-Man; 31.07.2018