Rrule Until 标记数据值

Rrule Until tag data value

我正在从事一个项目,该项目采用规则生成下一次事件。但是我无法理解我需要在 rrule 的 UNTIL 标签中添加什么。

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

不知道如何将日期转换为 "20190625T000000Z"。我正在使用 rfc 2445 java 库。例如,如果用户将日期作为字符串输入:25/06/2019......我需要在 UNTIL 标记中设置此值,如上所示。如果我在 UNTIL 中设置默认值,那么它可以工作,但当我让它对用户友好时就不行了。我将从用户那里获取所有值作为开始日期、结束日期、间隔、星期日、直到...但是我不知道什么值设置为 UNTIL。 如果有人可以提供帮助.. 在此先感谢。

解析基本 ISO 8601 格式

您的输入 20190625T000000Z 是标准 ISO 8601 format to represent a moment in UTC 的“基本”变体。 “基本”一词意味着尽量减少分隔符的使用(我不推荐这样做,因为它会降低字符串对人类的可读性)。

正在定义格式模式以匹配输入。

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

转储到控制台。

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

看到这个 code run live at IdeOne.com

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

将日期转换为时刻

If user enters the date as a string for example :25/06/2019......i need to set this value in UNTIL tag as shown above

首先,将该输入字符串解析为 LocalDate,表示仅日期值,没有时间和时区。

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

ld.toString(): 2019-06-25

至于将该日期转换为一个时刻(一个日期在一个区域或与 UTC 的偏移量中的时间),这比直观听起来要棘手。

2019 年 6 月 25 日等日期表示一整天。以及理论上的日期。一天开始和结束的时间因时区而异。新的一天在日本东京比在法国巴黎早得多,在魁北克蒙特利尔甚至更晚。

另一个问题是一天并不总是从 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[Africa/Tunis]

那个ZonedDateTime object represents a specific moment. But it uses the wall-clock time adopted by the people of a particular region (a time zone). Your goal is a moment in UTC. Fortunately, we can adjust from the zone to UTC by converting to an OffsetDateTime (a date and time with a context of offset-from-UTC rather than a time zone). We can specify UTC (an offset of zero) by the ZoneOffset.UTC常量。

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

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

请注意 00:00 突尼斯的 25 日是世界标准时间 24 日“昨天”晚上 11 点。同一时刻,时间轴上的同一同时点,但两个不同的挂钟时间。

最后,我们需要一个“基本”ISO 8601 格式的字符串。使用我们上面定义的相同格式化程序。

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

output: 20190624T230000Z

看到这个 code run live at IdeOne.com

时区和与 UTC 的偏移有什么区别?偏移量只是小时数-分钟-秒数。不多也不少,只是一个数字(好吧,三个数字)。时区要多得多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。例如,在北美大部分地区,偏移量每年变化两次,提前一个小时然后后退一个小时(Daylight Saving Time (DST) 的疯狂)。

提示:日期时间处理出奇地棘手和狡猾。如果您正在使用日历和 iCalendar 规范进行数据交换,我建议您花很长时间与行业领先的 java.time[=119= 学习概念和实践] 类。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time 类.

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类.

在哪里获取java.time类?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.