Oracle APEX 固定日历邀请的日期格式

Oracle APEX Fixing Date Format for Calendar Invitation

我正在使用日期格式 DD-MM-YYYY HH24:MI(希腊语格式日期时间) 我有 'F_ICAL_EVENTS' 功能:

create or replace FUNCTION F_ICAL_EVENTS (
   p_summary       IN   VARCHAR2,
   p_description   IN   VARCHAR2,
   p_start_date    IN   DATE,
   p_end_date      IN   DATE
)
   RETURN VARCHAR2
AS
   lv_desc      VARCHAR2 (1000);
   lv_summary   VARCHAR2 (500);
   lv_dtstart   VARCHAR2 (100);
   lv_date      VARCHAR2 (100);
   lv_dtend     VARCHAR2 (100);
   l_retval     VARCHAR2 (2000);
   l_lf         CHAR (1)         := CHR (10);
BEGIN
   lv_summary := 'SUMMARY:' || p_summary;
   lv_date :=
         'DTSTAMP:'
      || TO_DATE (CURRENT_TIMESTAMP, 'DD-MM-YYYY')
      || 'T'
      || TO_CHAR (CURRENT_TIMESTAMP, 'HH24:MI:SS');
   lv_dtstart :=
         'DTSTART:'
      || TO_DATE (p_start_date, 'DD-MM-YYYY')
      || 'T'
      || TO_CHAR (p_start_date, 'HH24:MI');
   lv_dtend :=
         'DTEND:'
      || TO_DATE (p_end_date, 'DD-MM-YYYY')
      || 'T'
      || TO_CHAR (p_end_date, 'HH24:MI');
   l_retval :=
         'BEGIN:VCALENDAR
VERSION:2.0
PRODID:-// Oracle Application Express //ENCAL
SCALE:GREGORIAN
BEGIN:VEVENT
'
      || lv_date
      || CHR (10)
      || lv_dtstart
      || CHR (10)
      || lv_dtend
      || CHR (10)
      || lv_summary
      || CHR (10)
      || lv_desc
      || '
SEQUENCE:0
END:VEVENT
END:VCALENDAR';
   DBMS_OUTPUT.put_line (l_retval);
   RETURN l_retval;
END F_ICAL_EVENTS;

从我的页面动态操作中获取日期时间值,如下所示:

SELECT F_ICAL_EVENTS (p_summary          => v_summary,
                                p_description      => v_descr,
                                p_start_date       => to_date(:P2003_SESSION_DATE, 'DD-MM-YYYY HH24:MI'),
                                p_end_date         => to_date(:P2003_SESSION_STOP, 'DD-MM-YYYY HH24:MI')
                                )
            INTO l_ical_event
            FROM DUAL;

问题是当我收到邀请时,日期和时间是错误的。例如,我的 Start_date 是 10/08/2021 16:00(8 月 10 日),我得到 8 Dec 0009 12:00。
我认为正确的session.ics附件:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-// Oracle Application Express //GR
SCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:16-08-2021T12:11:37
DTSTART:10-08-2021T16:00
DTEND:10-08-2021T17:00
SUMMARY:New Appointment! 
                               
SEQUENCE:0
END:VEVENT
END:VCALENDAR

这是我在 Gmail 中收到的通知:

在 Apex 页面上,所有项目都是 字符串 。日期选择器使用您为该项目设置的格式,但它仍然是一个字符串。

如果将格式设置为 DD-MM-YYYY H24:MI,则调用过程看起来正常,因为格式掩码匹配。

p_start_date       => to_date(:P2003_SESSION_DATE, 'DD-MM-YYYY HH24:MI')

但是,如果过程的参数数据类型是 DATE,那么这是错误的:

|| TO_DATE (p_start_date, 'DD-MM-YYYY')

应该是 TO_CHAR,就像您在

中使用的那样
|| TO_CHAR (p_start_date, 'HH24:MI');

[编辑]

显然,这是关于格式掩码的。为了完整起见,请在此处发表评论:

根据此页面 (How to Insert Google Calendar Invites in Your Marketing Emails),date/time 格式掩码应为 YYYYMMDDTHHMISS

不要在已经是 DATETIMESTAMP 的值上使用 TO_DATE。你似乎想要 TO_CHAR 而不是:

create or replace FUNCTION F_ICAL_EVENTS (
   p_summary       IN   VARCHAR2,
   p_description   IN   VARCHAR2,
   p_start_date    IN   DATE,
   p_end_date      IN   DATE
)
   RETURN VARCHAR2
AS
   l_retval     VARCHAR2 (2000);
BEGIN
   l_retval   := 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:-// Oracle Application Express //ENCAL
SCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:' || TO_CHAR(CURRENT_TIMESTAMP, 'DD-MM-YYYY"T"HH24:MI:SS') || '
DTSTART:' || TO_CHAR(p_start_date, 'DD-MM-YYYY"T"HH24:MI') || '
DTEND:' || TO_CHAR(p_end_date, 'DD-MM-YYYY"T"HH24:MI') || '
SUMMARY:' || p_summary || '
' || p_description || '
SEQUENCE:0
END:VEVENT
END:VCALENDAR';
   DBMS_OUTPUT.put_line (l_retval);
   RETURN l_retval;
END F_ICAL_EVENTS;
/

此外,如果 :P2003_SESSION_DATE:P2003_SESSION_STOPDATE 绑定变量,那么您不需要 TO_DATE,只需使用:

SELECT F_ICAL_EVENTS (
         p_summary     => v_summary,
         p_description => v_descr,
         p_start_date  => :P2003_SESSION_DATE,
         p_end_date    => :P2003_SESSION_STOP,
       )
INTO   l_ical_event
FROM   DUAL;

如果绑定变量是字符串,那么您将需要 TO_DATE 并保持您的调用查询不变,但可以简化它以删除 SELECT 语句并仅使用 PL/SQL 作业:

l_ical_event := F_ICAL_EVENTS (
                  p_summary     => v_summary,
                  p_description => v_descr,
                  p_start_date  => TO_DATE(:P2003_SESSION_DATE, 'DD-MM-YYYY HH24:MI'),
                  p_end_date    => TO_DATE(:P2003_SESSION_STOP, 'DD-MM-YYYY HH24:MI')
                );

db<>fiddle here


如果您使用的外部服务需要 ISO8601 格式的日期,则使用 YYYY-MM-DD"T"HH24:MI:SS

create or replace FUNCTION F_ICAL_EVENTS (
   p_summary       IN   VARCHAR2,
   p_description   IN   VARCHAR2,
   p_start_date    IN   DATE,
   p_end_date      IN   DATE
)
   RETURN VARCHAR2
AS
   l_retval     VARCHAR2 (2000);
BEGIN
   l_retval   := 'BEGIN:VCALENDAR
VERSION:2.0
PRODID:-// Oracle Application Express //ENCAL
SCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:' || TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD"T"HH24:MI:SS') || '
DTSTART:' || TO_CHAR(p_start_date, 'YYYY-MM-DD"T"HH24:MI:SS') || '
DTEND:' || TO_CHAR(p_end_date, 'YYYY-MM-DD"T"HH24:MI:SS') || '
SUMMARY:' || p_summary || '
' || p_description || '
SEQUENCE:0
END:VEVENT
END:VCALENDAR';
   DBMS_OUTPUT.put_line (l_retval);
   RETURN l_retval;
END F_ICAL_EVENTS;
/