Почему добавление недель в java.time.Instant не поддерживается? - PullRequest
0 голосов
/ 24 февраля 2019

Следующий фрагмент кода:

Instant inFourWeeks = Instant.now().plus(4L, ChronoUnit.WEEKS);

Выдает исключение:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Weeks

Почему недели не поддерживаются? Я понимаю, почему месяцы и годы не поддерживаютсяподдерживается, потому что их продолжительность в меньших единицах может варьироваться.Но неделя имеет постоянную продолжительность (7 дней), и я могу добиться того же, написав:

Instant inFourWeeks = Instant.now().plus(4L * 7L, ChronoUnit.DAYS);

Ответы [ 5 ]

0 голосов
/ 25 февраля 2019

Другие ответы верны.Я добавляю этот бит разъяснения.

Instant является базовым строительным блоком

Класс Instant является базовым строительным блоком в java.time классы.Это представляет момент, точку на временной шкале.Внутренне это просто подсчет целых секунд с начала эпохи первого момента 1970 года в UTC.Так что этот класс заслуживает мало функциональности.

Этот строительный блок может использоваться для отслеживания момента в любой из многих возможных систем календаря.Смысл Instant, трактовать его как дату, неделю, месяц и т. Д., Зависит от определений конкретной календарной системы.Система календаря может определять любое количество дней в неделе или любое количество месяцев в году и т. Д., Или может даже не иметь такие понятия, как неделя или месяц.

Наиболее очевидной календарной системой является современный стандарт ISO 8601, используемый на Западе и в других частях света.Классы OffsetDateTime & ZonedDateTime, построенные поверх Instant, составляют ключевые части этой системы календаря ISO.Эти классы связаны с Instant только потому, что ожидается, что они будут широко использоваться многими программистами Java.Но они ни в коем случае не являются единственной системой календаря.

Посмотрите на пакет java.time.chrono для этих различных систем календаря:

  • HijrahChronology Календарь хиджры - это лунный календарь с поддержкой исламских календарей.
  • IsoChronology
  • JapaneseChronologyЯпонская имперская календарная система.
  • MinguoChronologyСистема Minguo .
  • ThaiBuddhistChronologyТайская буддийская календарная система.

Проект ThreeTen-Extra предоставляет дополнительные функциональные возможности для классов java.time .Это включает в себя больше календарных систем:

  • AccountingChronologyПерспективная 52/53-недельная учетная календарная система согласно Публикации IRS 538 и Международным стандартам финансовой отчетности.
  • BritishCutoverChronologyБританская система юлиано-григорианского календаря.
  • CopticChronologyСистема Коптский календарь .
  • DiscordianChronologyСистема Discordian .
  • InternationalFixedChronologyСистема Международный Фиксированный календарь .Также известен как календарь Eastman Kodak.
  • JulianChronologyПролептическая система юлианского календаря, предшествующая современным григорианским и ISO календарям.
  • PaxChronologyСистема Pax .
  • Symmetry010Chronology
  • Symmetry454ChronologyСистема Symmetry454 .

От третьих лиц может быть еще кое-что, о чем я не знаю.

0 голосов
/ 24 февраля 2019

ChronoUnit.WEEKS может использоваться неделями в других календарных системах, кроме календаря ISO.И такие недели могут длиться, например, 6 или 10 дней.Таким образом, хотя можно утверждать, что имеет смысл, что Instant поддерживает дни, то же самое недействительно для недель.

Из документации:

Единица, которая представляет концепцию недели.Для календарной системы ИСО оно равно 7 дням.

При использовании с другими календарными системами оно должно соответствовать целому числу дней.

Из этого ясно следует, чтоWEEKS обычно не принимает систему календаря ISO и может использоваться с другими календарями.

Другая часть аргумента состоит в том, что Instant не предполагает одну систему календаря, но может использоваться с другим календаремсистемы тоже.(В отличие от этого, например, ZonedDateTime предполагает, что календарная система ISO-8601 поддерживает недели.)

PS Я бы скорее задал вопрос наоборот: почему Instant дни поддержки?Днем может быть 23, 23,5, 24, 24,5 или 25 часов, а также исторически другие продолжительности.

Ссылка: Документация ChronoUnit.WEEKS.

0 голосов
/ 24 февраля 2019

Если вы посмотрите на код для plus(long, TemporalUnit), он не поддерживает WEEK,

 @Override
     public Instant plus(long amountToAdd, TemporalUnit unit) {
         if (unit instanceof ChronoUnit) {
             switch ((ChronoUnit) unit) {
                 case NANOS: return plusNanos(amountToAdd);
                 case MICROS: return plus(amountToAdd / 1000_000, (amountToAdd % 1000_000) * 1000);
                 case MILLIS: return plusMillis(amountToAdd);
                 case SECONDS: return plusSeconds(amountToAdd);
                 case MINUTES: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_MINUTE));
                 case HOURS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_HOUR));
                 case HALF_DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY / 2));
                 case DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY));
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
         return unit.addTo(this, amountToAdd);
     }

Из кода видно, что результаты рассчитываются путем умножения представления единиц измерения на неделю / месяц /год не может быть логически и последовательно представлен секундами, поскольку это не универсальные константы согласно javadoc .

0 голосов
/ 24 февраля 2019

Класс Instant имеет дело с абсолютным временем и пытается избежать всех неясностей, связанных с тем, как различные календарные системы, регионы и культуры группируют и интерпретируют его.

Некоторые календарные системы имеют разную продолжительность недели, некоторые имеют разную группировку месяцев, имеют годы, начинающиеся с другой даты, и корректируются на високосные годы и високосные секунды по-разному (если вообще, как в случае сЮлианский календарь, в котором было слишком много високосных лет и который дрейфовал от «физических» явлений, с которыми они должны были быть синхронизированы, как времена года, солнцестояния и равноденствия).

Чтобы избежать этих проблем, класс Instant позволяет вам использовать более точно определенные и стандартизированные единицы измерения, такие как секунды, минуты, часы и дни.

В Java «сглаживаются» дополнительные секунды за последние 1000 секунд дня, в который они происходят, поэтому с точки зрения программиста их не существует.(Компьютерные часы в любом случае не столь точны, и их необходимо часто синхронизировать с NTP.)

1 день считается равным 24 часам СИ, при этом 1 час СИ определяется как 60 минут СИ, 1 минута СИ определяется как 60Секунды СИ и 1 секунда СИ составляют 9 192 631 770 периодов излучения цезия-133.24 часа - это на самом деле средний солнечный день (время, прошедшее между двумя последовательными «полуднями»), потому что из-за эллиптических орбит, орбиты самого Солнца и колебаний скорости орбиты каждый солнечный день может быть немного длиннее или короче.

Одна важная вещь, о которой вы должны быть осторожны, это летнее время.В эти особые дни день составляет 25 или 23 часа, в зависимости от того, в каком направлении движутся часы.Однако класс Instant не заботится об этом, он все равно будет двигаться 24 часа, если вы добавите 1 день к границе летнего времени.Он не несет никакой временной зоны или региональной информации (летнее время зависит от страны).

0 голосов
/ 24 февраля 2019

Это выбрасывает UnsupportedTemporalTypeException 7 дней в неделю не является универсальной и постояннойЭто может варьироваться в зависимости от календарной системы.Например, посмотрите на календарную систему Akan , которая использует 6 дней в неделю.

...