abap - 为什么在添加 DAYLIGHT SAVING TIME 时 CONVERT DATE 会因 sy-subrc 12 而失败?
问题描述
以下代码失败并显示sy-subrc=12
.
CONVERT DATE '20191105'
TIME '123000'
DAYLIGHT SAVING TIME 'X'
INTO TIME STAMP DATA(timestamp)
TIME ZONE 'CET '.
在ABAP 文档中它说:
12:无法转换指定的时间,因为 dat、tim 或 dst 包含无效或不一致的值。
我注意到,当我在调试器中删除 sy-dayst 中的“X”时,它会进行转换。
但是我当然想考虑夏令时,所以我怎样才能做到这一点?
解决方案
TL;博士
切勿使用
DAYLIGHT SAVING TIME
(如果您是专家,则在非常特殊的情况下除外)
@konstantin 说得好:
“CONVERT DATE 命令自动处理 DST”
解释:
DAYLIGHT SAVING TIME 'X'
仅当本地时间(DATE 和 TIME)匹配一小时(很少是两小时)间隔以从夏令时切换到冬令时,才能使用给定时区(请注意,某些时区没有夏令时) .
例如,2003 年,巴西在 3 月 9 日(星期日)凌晨 2 点切换到冬季时间;凌晨 2 点,时钟不得不拨回一小时到凌晨 1 点,因此凌晨 1 点 30 分出现了两次。
因此,如果 ABAP 必须将本地时间 2003/03/09 01:30:00 转换为 UTC 时间,它必须知道本地时间是否在夏令时(冬令时)或不在夏令时(夏令时),分别对应 UTC 时间 2003/03/09 03:30:00 或 2003/03/09 04:30:00。
示范:
DATA: time_stamp TYPE timestamp,
dat TYPE d,
tim TYPE t,
tz TYPE ttzz-tzone.
tz = 'BRAZIL'. "UTC-03:00
dat = '20030309'.
tim = '013000'.
CONVERT DATE dat TIME tim DAYLIGHT SAVING TIME 'X' " winter time
INTO TIME STAMP time_stamp TIME ZONE tz.
ASSERT time_stamp = '20030309033000'. " UTC time
CONVERT DATE dat TIME tim DAYLIGHT SAVING TIME ' ' " summer time
INTO TIME STAMP time_stamp TIME ZONE tz.
ASSERT time_stamp = '20030309043000'. " UTC time
现在,问题是,如何知道是否DAYLIGHT SAVING TIME 'X'
必须使用。事实上,如果一个数据库表包含我在上面示例中使用的本地时间,则无法知道它是夏令时还是冬令时,因为夏令时从未与日期和时间列一起分配给表列。
这就是为什么SAP 在大约 10 年前推出了一个DAYLIGHT SAVING TIME
几乎已经过时的解决方案。实际问题不是夏令时,而是可能导致时间排序等问题的非连续时间。解决的原理是在夏令时切换过程中将时间放慢,这样一个给定的时间就不会出现两次,并且时间保持连续。从技术上讲,它会影响系统变量SY-DATUM
(日期)和SY-UZEIT
(时间)。在这个“双小时”间隔中,需要两个实际秒才能产生一个 SAP 秒。zdate/DSTswitch_contloctime
默认情况下(值“on”)通过您可以通过事务代码查看的配置文件参数激活此行为RZ11
. 下面是根据旧(“off”)或新方式(“on”)的 SAP 时间,如果切换发生在当地时间凌晨 2 点(使用“on”,则看不到切换):
off: 1:00, 1:30, 1:00, 1:30, 2:00
on : 1:00, 1:15, 1:30, 1:45, 2:00
只是为了增加复杂性,请注意CONVERT
仍然有一个小时的差距。例如,zdate/DSTswitch_contloctime
设置为 "on" 和不设置DAYLIGHT SAVING TIME
,CONVERT
将分别给出这些 UTC 时间戳,在 03:59:59 和 05:00:00 之间有一个小时的间隔:
3:00, 3:15, 3:30, 3:45, 5:00
但与出现时间排序问题的风险相比,这种差距并不是一个大缺点。
更多信息:https ://blogs.sap.com/2009/12/09/daylight-saving-time-and-slowing-down-the-time/和SAP note 950114 - Profile parameter zdate/DSTswitch_contloctime。
请注意,它SY-DAYST
对应于应用程序服务器当前时间的 DST 指示符(SY-DATUM
、SY-UZEIT
和表中定义的时区TTZCU
)。我看不出它有任何可能的用途。如果要将最初使用SY-DATUM
and获得的时间SY-UZEIT
转换为 UTC 时间戳,则应使用SYSTEMTSTMP_SYST2UTC
class的方法CL_ABAP_TSTMP
。获取当前时间的示例:
cl_abap_tstmp=>systemtstmp_syst2utc(
EXPORTING
syst_date = sy-datum
syst_time = sy-uzeit
IMPORTING
utc_tstmp = DATA(now_utc) ).
正如@konstantin 所展示的那样(“ DATE '20190331' TIME '023000' [...] local time 在德国不存在”),如果输入日期和时间对应于“消失时间”内的某些内容,则在极少数情况CONVERT DATE
下DAYLIGHT SAVING TIME
可能会返回sy-subrc=12
“由于从冬季时间切换到夏季时间,如果时区有 DST。例如:“at 2am, it is 3am”,当地时间“2:30am”根本不存在。
推荐阅读
- android - 如何在android studio中为特定屏幕尺寸创建值文件夹
- javascript - Javascript:Tippy.js 不适用于动态内容
- javascript - 使函数仅影响 onclick=function(this) 中的“this”对象
- c# - SQLite 无法正常运行 c#
- mongodb - 如何在 MongoDB 中执行联接(在 SQL 中类似)?
- vue.js - 如何通过单击按钮触发 fromEvent() rxjs?
- php - PHP Curl 什么都不返回,没有错误,也没有数据
- flutter - 如何避免着陆页在颤动中返回
- php - 显示表单结果与表单相同的页面
- android - 如何将我的本机服务添加到 Android 中的现有组