Как использовать класс Clock, чтобы вычесть 2 месяца из текущей даты в Java - PullRequest
1 голос
/ 02 апреля 2019

Я работаю над кодом и мне нужно использовать класс Clock, чтобы узнать текущее время. И я хочу вычесть текущую дату с 2 месяцами.

Это код:

public class DemoApp {
    private Clock clock = Clock.systemDefaultZone();

    public List<String> subtractMonths(String[][] str) {
        List<String> ids = new ArrayList<>();
        // The code
        return ids;
    }
}

А в основном классе у меня есть этот массив строк:

private static final String[][] str = {
    {"id1", "2017-11-01T14:10:30"},
    {"id2", "2018-01-20T18:01:34"},
    {"id3", "2018-01-22T08:45:22"},
    {"id4", "2018-02-18T12:42:37"},
    {"id5", "2019-03-16T03:56:32"},
};

В основном классе я вызову метод subtractMonths с параметром str и верну идентификатор, если дата не является текущим и предыдущим месяцем. Например, если текущий месяц январь, верните только идентификатор с месяцем до декабря. Любые отзывы будут оценены!

Ответы [ 3 ]

2 голосов
/ 02 апреля 2019

Используя LocalDateTime или Instant, у вас есть методы для minus() и plus() для вычитания или добавления количества времени:

LocalDateTime beforeTwoMonths = LocalDateTime.now()
        .minus(2, ChronoUnit.MONTHS);

Или используйте метод minusMonths():

LocalDateTime beforeTwoMonths = LocalDateTime.now().minusMonths(2);

Использование только класса Clock невозможно.Единственный способ - преобразовать его в ZonedDateTime и затем вычесть месяцы:

ZonedDateTime beforeTwoMonths = Clock.systemDefaultZone().instant().atZone(ZoneId.systemDefault()).minusMonths(2);

В противном случае вы можете выполнить вычисления самостоятельно, но я не думаю, что это лучший путь.

1 голос
/ 02 апреля 2019

Я думаю, что-то вроде этого было задумано:

public List<String> subtractMonths(String[][] str) {
    YearMonth lastMonth = YearMonth.now(clock).minusMonths(1);
    List<String> ids = Arrays.stream(str)
            .filter(pair -> YearMonth.parse(pair[1], DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                    .isBefore(lastMonth))
            .map(pair -> pair[0])
            .collect(Collectors.toList());
    return ids;
}

Когда я вызываю этот метод сегодня и передаю ваш str в качестве аргумента, я получаю такой результат:

[id1, id2, id3, id4]

Да, в дополнение к данному экземпляру Clock я также использую классы YearMonth и DateTimeFormatter.Но YearMonth получает время от часов.Это, в свою очередь, гарантирует поведение, которого они придерживались, когда требовали от вас использования часов.Они могут заменить другие часы, и код будет использовать эти часы исключительно для определения, в каком месяце мы находимся.

Это отлично подходит для тестируемости и часто используется для этой цели.Когда вы заменяете часы, которые всегда сообщают вам, что, скажем, январь 2019 года, вы знаете, каких результатов ожидать.Затем вы можете повторно запустить свои автоматизированные тесты в 2025 году и по-прежнему ожидать того же результата.И сообщайте о сбое, если вы его не получаете, и хорошо спите ночью, если вы это делаете.

Ссылка: Написание и тестирование удобных методов с использованием классов Java 8 Date / Time

1 голос
/ 02 апреля 2019

Я не думаю, что это возможно, легкий путь.Единственный метод в Clock, который выполняет сложение / вычитание для даты Clock, это

static Clock offset(Clock baseClock, Duration offsetDuration)

Длительности не имеют месяцев, потому что длительность не зависит от местоположения и момента времени.

Однако продолжительность месяца зависит именно от этого (добавление месяца в феврале короче добавления месяца в январе. Аналогичным образом, добавление месяца при наличии високосного года или перехода на летнее время приводит кразница).

В настоящее время нет простого способа добавить один месяц к определенной дате.Это одно из больших изменений в основных библиотеках для dart 2.0.

Тем временем самым безопасным является создание нового DateTime со всеми переданными аргументами, но с добавлением 1 к месяцу: new DateTime(other.year, other.month + 1, other.day, other.hour, ...).

Даже в этом случае вам все равно нужно обратить внимание: что должно означать добавлениемесяц до 31 марта?При простом подходе, описанном выше, вы окажетесь 1 мая.Если это не то, что вы хотите, вы должны зажать месяцы.Это требует немного больше кода (включая знание, когда существуют високосные годы).

Ссылка: https://github.com/flutter/flutter/issues/12141

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...