Наконец-то появилось время для более глубокого изучения.
Я начал экспериментировать и через некоторое время обнаружил, что на самом деле не присутствие System.out.println
повлияло на результат, а тот факт, что вы создаете экземпляр 2LocalDateTime
экземпляров перед ним.
Копая глубже, в код LocalDateTime
и SystemClock
(которому он делегирует), я обнаружил, что точность до миллимиллиона была достигнута путем вызовасобственный вызов jdk.internal.misc.VM#getNanoTimeAdjustment
.
Последний вызов зависит от ОС. Я немного поэкспериментировал с этим и обнаружил, что он не возвращает значения линейно, так как он вызывается в цикле (при условии, что мой цикл выполняется довольно регулярно).
Поэтому я решил запустить некоторый код для сопоставления возвращаемого значенияnano values.
Я сделал этот код выборки:
Clock clock = Clock.systemDefaultZone();
int samples = 1_000;
LocalDateTime[] instants = new LocalDateTime[samples];
int k = 0;
for (int i = 0; i < samples; i++) {
instants[i] = LocalDateTime.now(clock);
for (int j = 0; j < 10000; j++) {
k = j % 2;
}
}
записал значения в файл, а затем отобразил наноразности относительно первого значения в графике:
Как вы можете видеть, этот график (из 1000 значений) делает прерывистые скачки. Это, очевидно, частично из-за ограничения точности базовой системы. Но Ват меня поразил тем, что первые два значения последовательно были разными. Это похоже на то, как будто при обычном доступе система начинает некоторое время кэшировать значение (возможно, чтобы избежать нагрузки на системные ресурсы).
Но в результате получается, что вы настроили себя на получение того же значения на3-й и 4-й вызов (если не прошло достаточно времени).
Это объяснило бы, почему ваш тест проходит с неудачными тестами и завершается неудачей.
В качестве отступления, для модульных тестов, которые вы надеваетене хочу полагаться на системные часы. Убедитесь, что ваш бизнес-код получает время от внедренного экземпляра Clock. Затем вы можете ввести собственные часы для тестов и проверить, будет ли ваш код работать в день перехода на летнее время или в високосный день, не дожидаясь нескольких месяцев.