Rrule До значения тега данных

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

String str="RRULE:FREQ=MONTHLY;UNTIL=20190625T000000Z;INTERVAL=2;";

ИДК, как конвертировать дату в "20190625T000000Z".Я использую Java-библиотеку rfc 2445. Если пользователь вводит дату в виде строки, например:25/06/2019......Мне нужно установить это значение в теге UNTIL, как показано выше. Если я установлю значение по умолчанию в UNTIL, тогда оно будет работать, но не тогда, когда я сделаю его удобным для пользователя. Я беру все значения от пользователя в качестве даты начала, даты окончания, интервала, дня рождения, до... Но не знаю, какое значение установить до. Если кто-то может помочь.. Заранее спасибо.

1 ответ

Решение

Разбор базового формата ISO 8601

Ваш вклад 20190625T000000Z это "базовый" вариант стандартного формата ISO 8601 для представления момента в формате UTC. Слово "базовый" означает минимизацию использования разделителей (я не рекомендую этого, поскольку это делает строку менее читаемой людьми).

Определение шаблона форматирования для соответствия вводу.

String input = "20190625T000000Z";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmssX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );

Дамп на консоль.

System.out.println("odt.toString(): " + odt);

Смотрите этот код в прямом эфире на IdeOne.com.

odt.toString (): 2019-06-25T00:00Z

Перевод даты в момент

Если пользователь вводит дату в виде строки, например:25/06/2019...... мне нужно установить это значение в теге UNTIL, как показано выше

Сначала проанализируйте эту входную строку в LocalDate, представляющий значение только для даты, без времени суток и без часового пояса.

DateTimeFormatter fDateOnly = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "25/06/2019" , fDateOnly );

ld.toString (): 2019-06-25

Что касается перевода этой даты в момент (дата с указанием времени дня в зоне или смещением от UTC), это сложнее, чем кажется на первый взгляд.

Такая дата, как 25 июня 2019 года, представляет собой целый день. И теоретическая дата в этом. Моменты, когда день начинается и заканчивается, различаются по всему земному шару в зависимости от часового пояса. Новый день начинается гораздо раньше в Токио, Япония, чем в Париже, Франция, и даже позже, в Монреале, Квебеке.

Другая проблема заключается в том, что день не всегда начинается в 00:00:00. Из-за таких аномалий, как летнее время (DST), первый момент дня в некоторые даты в некоторых зонах может быть примерно 01:00:00. Пусть классы java.time определяют первый момент.

ZoneId z = ZoneId.of( "Africa/Tunis" );
ZonedDateTime zdt = ld.atStartOfDay( z );

zdt.toString (): 2019-06-25T00:00 + 01: 00 [Африка / Тунис]

Тот ZonedDateTime объект представляет определенный момент. Но он использует настенные часы, принятые людьми определенного региона (часового пояса). Ваша цель - момент в UTC. К счастью, мы можем отрегулировать из зоны в UTC, преобразовав в OffsetDateTime (дата и время с контекстом смещения от UTC, а не с часовым поясом). Мы можем указать UTC (смещение нуля) по ZoneOffset.UTC постоянная.

OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC );

odt.toString (): 2019-06-24T23: 00Z

Обратите внимание, что 00:00 25-го в Тунисе 11 вечера "вчера" 24-го в UTC. Тот же самый момент, та же самая одновременная точка на временной шкале, но два разных времени настенных часов.

Наконец, нам нужна строка в этом "базовом" формате ISO 8601. Используйте тот же форматер, который мы определили выше.

DateTimeFormatter fIso8601DateTimeBasic = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmssX" );
String output = odt.format( fIso8601DateTimeBasic );

выход: 20190624T230000Z

Смотрите этот код в прямом эфире на IdeOne.com.

В чем разница между часовым поясом и смещением от UTC? Смещение - это просто количество часов, минут и секунд. Не больше, не меньше, просто число (ну, три цифры). Часовой пояс гораздо больше. Часовой пояс - это история прошлых, настоящих и будущих изменений в смещении, используемом людьми определенного региона. Например, в большей части Северной Америки смещение меняется два раза в год, начиная с часа вперед, а затем с уменьшением на час (безумие летнего времени (DST)).

Совет: обработка даты и времени на удивление хитрая и скользкая. Если вы работаете с календарями и спецификацией iCalendar для обмена данными, я предлагаю вам немало времени изучить концепции и практику с ведущими в отрасли классами java.time.


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date, Calendar & SimpleDateFormat,

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классы.

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как Interval, YearWeek, YearQuarter и многое другое.

Другие вопросы по тегам