紫薇斗数 财富
处理日期和时间是每个程序员的基本技能之一,但是当你开发Fiori应用程序时,你会发现问题开始变得复杂起来。
在典型的Fiori开发场景中,我们要使用多种不同的技术组合,例如ABAP,OData服务,SAPUI5。除此之外如果你使用SAP云平台,或者使用开源的OPENUI5和其他后 *** 言集成,你会面临更复杂的场景。所有这些技术都有自己处理日期和时间的方式,把他们组合起来之后会不会产生问题呢?
这个系列文章的目的包括:
基于S/4 HANA的Fiori开发的完整场景,分析各个组成部分处理日期。
帮助使用其他技术组合进行Fiori开发的程序员梳理一个分析此类问题的思路。

系列文章列表:
ABAP如何处理日期/时间(本文)
将ABAP日期/时间类型转换为OData日期/时间类型
SAPUI5如何处理OData日期/时间
如何在SAPUI5中处理日期/时间的表示
使用日期/时间字段处理对实体的创建请求
具有日期/时间关键字段的处理实体
使用日期/时间字段作为OData查询选项
处理时区和时差
ABAP如何处理日期和时间
Fiori日期和时间处理之一
本文是系列文章《Fiori日期时间处理》的 *** 篇。
在这篇文章中,我们一起来看一看ABAP如何处理日期和时间。
01
日期/时间的数据类型
ABAP具有四种日期/时间数据类型,他们分别是:
(1)日期类型
日期类型在ABAP当中的类型名称为d,在数据字典当中使用DATS表示,实际存储是一个8位的文本。例如’20180121’。
(2)时间类型
时间类型的ABAP数据类型名称为t,数据字典中为TIMS,实际存储是6位的文本。如’104355’。
(3)短时间戳
短时间戳并不是一个ABAP数据类型,也不是数据字典基本类型,实际在ABAP中是8字节的类型,在ABAP数据字典中是15位长度的DEC类型。
在ABAP数据字典中,默认用来做短时间戳的域是TZNTSTMPS,数据元素是TIMESTAMP。短时间戳是一个精确到秒的p类型变量,例如’20170121104355’。
(4)长时间戳
长时间戳并不是一个ABAP数据类型,也不是数据字典基本类型,实际在ABAP中是11字节,7位小数的类型,在ABAP数据字典中是21位长度7位小数的DEC类型。
在ABAP数据字典中,默认用来做短时间戳的域是TZNTSTMPL,数据元素是TIMESTAMPL。长时间戳是一个精确到千万分之一秒的p类型变量,例如’20170121104355.1234567’。
02
如何取得当前的日期和时间
下面的示例代码表达了如何取得当前的日期和时间:
DATA(server_date)= sy-datum."取得ABAP服务器的当前日期DATA(server_time)= sy-uzeit."取得ABAP服务器的当前时间DATA(user_date)= sy-datlo."取得服务器日期,并输出成用户主数据设定时区的日期DATA(user_time)= sy-timlo "取得服务器时间,并输出成用户主数据设定时区的时间GET TIME STAMP FIELD DATA(timestamp)."取得格林威治标准时间戳,存储为短时间戳DATA tsl TYPE timestampl.GET TIME STAMP FIELD tsl." 取得格林威治标准时间戳,存储为长时间戳
注意事项:
当说到要取得当前时间时,我们有下面5种可能:
(1)ABAP服务器的时间
(2)数据库服务器的时间
(3)客户端电脑的时间
(4)用户主数据所设定时区的时间
(5)格林威治时间(UTC)
在ABAP服务器中,我们有一套机制把所有的ABAP服务器的时间和后台数据库服务器的时间同步,所以在可容许的误差范围内,时间(1)等于时间(2)。
客户端电脑的时间容易受到各种外部因素影响,而且客户用的 *** 作 *** 也可能不同,当获取用户时间时,一般会使用用户主数据里面(SU01或SU3)所设定的时区。如果用户没有设定时区,则使用存储在TTZCU表里面的默认时区。
日期/时间变量永远是某个特定时区输出的,开发者必须关注时区问题。时间戳永远是存储格林威治时间(UTC)。
ABAP的时间 *** 变量并不是实时刷新的,只有当程序启动,屏幕刷新等时间节点,时间字段才会刷新。所以在一段运行时间较长的ABAP代码中,如果想得到实时的时间,要使用GET TIME语句手动更新时间。
03
日期/时间变量的处理
(1)把日期/时间当作文本来处理
日期和时间变量存储成文本,当然可以使用文本的处理 *** 。我们一般用这种 *** 截取日期和时间中的不同部分。下面是一个简单的例子:
date = sy-datlo.time = sy-timlo.year = substring( val = date off =0 len =4).month = substring( val = date off =4 len =2).day = substring( val = date off =6 len =2).hour = substring( val = time off =0 len =2).minute = substring( val = time off =2 len =2).second = substring( val = time off =4 len =2).
(2)把日期/时间当作数字处理
与文本不同的是他们还可以隐式转换成整数进行运算,当然这样的运算不一定都有实际意义。下表是一个对有意义的计算的总结。
注意:
本文不讨论在特定业务场景的计算,如工厂日历等。
如果需要做复杂的日期计算,或者计算两个日期时间组合之间的关系,最简单的 *** 是把她们都转换成时间戳再计算。
(3)处理时间戳
虽然时间戳存储位小数,但是千万不要把她们当成一般的小数来处理。在处理时间戳时,应该使用 *** 类CL_ABAP_TSTMP来处理。
注意:
*** 上能够找到很多ABAP的日期和时间处理函数,在使用的时候我们要谨慎。因为这些函数并不属于SAP_BAS *** 模块,可能只是依附于某一个业务模块。如果你的自开发程序不是仅依赖于某个模块的,就尽量不要使用依赖于某个模块的代码,否则当程序从一个 *** 迁移到另一个 *** 的时候就可能出现问题。
(4)日期/时间相关的SQL函数
在编写OPEN SQL和Core Data Serv *** 时,还可以使用以下SQL函数来处理日期和时间:
DATS_DAYS_BETWEEN( date1, date2 )用来计算两个日期差几天;
DATS_ADD_DAYS( date, days , on_error )用来为一个日期添加天数;
DATS_ADD_MONTHS( date, months, on_error )用来为一个日期添加月份;
TSTMP_CURRENT_UTCTIMESTAMP( )取得当前时间戳;
TSTMP_SECONDS_BETWEEN( tstmp1, tstmp2, on_error )计算两个时间戳见想差的秒数;
TSTMP_ADD_SECONDS( tstmp, seconds, on_error )为时间戳添加秒数。
注意:
前3个可以在OPEN SQL和CoreData Serv *** 中使用,后三个只能在Core Data Serv *** 中使用
在使用基于SQL的技术时,尽量不要把经过计算的列用作查询条件,即使在HANA下这也会对性能产生不好的影响。我们可以使用S/4 HANA 1709中新增的Date Function,或者创建日期/时间维度来解决日期计算问题。在后续的文章中我们还会详细讨论这两种手段。
04
类型的相互转换
你可以在日期/时间和时间戳之间进行相互的类型转换。

(1)将日期/时间转换为时间戳
将日期/时间转换为时间戳时,需要注意你的日期和时间是有时区的,在转换时间戳的时候,会转换成格林威治时间,所以你必须告诉 *** 你当前的变量是哪个时区,这样才能计算出UTC时间。
下面是一段代码示例:
DATA: dat TYPE d,"日期 tim TYPE t,"时间 tz TYPE ttzz-tzone."时区"通过变量sy-zonlo可以取得用户时区"下面这一段OPENSQL可以去的 *** 时区"SELECT SINGLE tzonesys " FROM ttzcu " INTO @DATA(tz).tz ='EST'.dat ='20161030'.tim ='013000'.CONVERT DATE dat TIME tim INTO TIME STAMP DATA(time_stamp) TIME ZONE tz.
(2)将时间戳转换为日期/时间
由于时间戳总会以格林威治时间存储,所以在转换成日期和时间时,也必须提供时区。
下面是一段代码示例:
CONVERT TIME STAMP time_stamp TIME ZONE tz INTO DATE DATA(dat) TIME DATA(tim)
(3)日期/时间转换的SQL函数
日期/时间转换的SQL函数目前只能在Core Data Serv *** 中使用,OPEN SQL不能使用。
TSTMP_TO_DATS( tstmp, tzone, clnt, on_error )将时间戳的日期部分转为d类型
TSTMP_TO_TIMS( tstmp, tzone, clnt, on_error )将时间戳的时间部分转换为t类型
DATS_TIMS_TO_TSTMP( date, time, tzone, clnt, on_error )将日期和时间拼成时间戳
ABAP_ *** _TIMEZONE( clnt, on_error )取得 *** 时区
ABAP_USER_TIMEZONE( user, clnt, on_error )取得用户主数据的时区
05
输出
数据输出不仅意味着把她们输出到屏幕,我们也可以以一定格式输出到一个文本变量中。
按照现在的情况来看,使用String Templates进行输出是更佳的方式。
如果你还不知道什么是String Templates,可以参考以下两篇博客。
*** s://blogs.sap *** /2013/05/17/using-new-abap-stuff-new-options-for-strings/
这篇博客介绍了String Templates的基本功能
*** s://blogs.sap *** /2017/03/25/string-template-in-abap-es6-angular-and-react/
这篇博客来自于子涵兄(Jerry),SAP成都研究院的高手,横向比较了ABAP和其他语言/框架的String Template的功能差异。
在String Template中,有以下格式化选项和日期/时间有关系:
DATE,日期的格式化选项
TIME,时间的格式化选项
TIMESTAMP,时间戳的格式化选项
TIMEZONE,配合时间戳使用,输出时按照要求的时区输出
COUNTRY,设定国家,临时输出符合某个国家要求的样式
06
参考文档
成为一名真正的开发顾问,需要永远保持和一手资料的连接。任何文章,教材,包括本文,都只是帮助你能够更好的阅读一手资料。
请访问以下链接参阅完整的ABAP文档:
*** s://help.sap *** /doc/abapdocu_752_index_htm/7.52/en-US/index.htm
本文涉及的章节路径主要包括:
Date / Time Processing: ABAP – Keyword Documentation → ABAP – Reference → Processing Internal Data → Date and Time Processing
Deal with date/time in SQL / Core Data Serv *** : ABAP – Dictionary → Built-In Functions in ABAP Dictionary → Special Functions → Date Functions and Time Functions
Format Options for Date and Time ABAP – Reference → Processing Internal Data → Character String and Byte String Processing → Expressions and Functions for String Processing → string_exp – String Expressions → string_exp – String Templates → String Templates – embedded_expressions → Embedded Expressions – format_options

07
继续向前
尽管本文不能描述所有细节,但我相信你对ABAP的日期/时间处理有了基本的了解。
在下一篇文章中,我们将会看一看当ABAP的变量转变为OData服务的属性时,在日期/时间的问题上 *** 帮助我们完成了哪些处理,又有哪些注意事项呢?
更多精彩内容,尽在“科莱特”!
科莱特pc官网: *** :// *** kelote ***
科莱特wap官网: *** ://wap.kelote ***












