2015年3月26日 星期四

ABAP4: Add or subtract SAP Date Time

ABAP4: Add or subtract SAP Date Time By Timestamp

SAP 的日期與時間 SY-DATUM & SY-UZEIT 是分開,並不像 Oracle datetime 可以直接加減運算,因此可透過轉換成 Timestamp (UTC) 變成秒後,再針對要增加 or 減少的時間轉換成秒後進行運算,最後再把 Timestamp 轉為 Date Time

第一種方法:

透過 RKE_TIMESTAMP_CONVERT_INPUT 把時間轉換成 UTC Timestamp,再透過 RKE_TIMESTAMP_CONVERT_OUTPUT 轉回 DATE/TIME.

CALL FUNCTION 'RKE_TIMESTAMP_CONVERT_INPUT'


CALL FUNCTION 'RKE_TIMESTAMP_CONVERT_OUTPUT'

Sample Code:

report Z_EX_CALC_DATE_TIME.

DATA: L_TIMESTMP LIKE CEST1-TIMESTMP.

DATA : L_DATUM LIKE SY-DATUM,
       L_UZEIT LIKE SY-UZEIT.

L_DATUM = SY-DATUM.
L_UZEIT = SY-UZEIT.

WRITE: '現在時間 - ', L_DATUM, L_UZEIT.

CALL FUNCTION 'RKE_TIMESTAMP_CONVERT_INPUT'
  EXPORTING
    I_DATE             = SY-DATUM
    I_DAYST            = ' '
    I_TIME             = SY-UZEIT
    I_TZONE            = SY-TZONE   "目前的時區,與 OUTPUT 需相同
  IMPORTING
    E_TIMESTMP         = L_TIMESTMP
  EXCEPTIONS
*   DATE_INVALID       = 1
    OTHERS             = 2.
IF SY-SUBRC <> 0.
  MESSAGE ID SY-MSGID TYPE 'I' NUMBER SY-MSGNO
          WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

"加 30 分鐘 * 10000 (Timestamp 後面有四個 0)
L_TIMESTMP = L_TIMESTMP + ( 30 * 60 * 10000 ).

WRITE :/.

CALL FUNCTION 'RKE_TIMESTAMP_CONVERT_OUTPUT'
  EXPORTING
    I_DAYST          = ' '
    I_TIMESTMP       = L_TIMESTMP
    I_TZONE          = SY-TZONE   "目前的時區,與 INPUT 需相同

  IMPORTING
    E_DATE           = L_DATUM
    E_TIME           = L_UZEIT.

WRITE: '加30分鐘 - ', L_DATUM, L_UZEIT.


要注意的是加 30 分鐘是 30 * 60 * 10000,其中乘 10000 主要是因為 FM : RKE_TIMESTAMP_CONVERT_INPUT 回傳的 Timestamp 中最後會有 0000 (待確認是否為 UTC+0000 的 timezone)


第二種方法:

是土法煉鋼 :  針對日期的計算可以透過 Unix epoch time 19700101 00:00:00 UTC 為基準,把目前的時間扣掉 19700101 00:00:00 轉換成秒後,再透過秒的加減再把秒轉換成 Date Time

SAMPLE CODE:


REPORT Z_CALC_DATE_TIME.

DATA: L_DATE LIKE SY-DATUM,
      L_TIME(10) TYPE C.
DATA: L_PARA TYPE P.

L_PARA = 30 * 60.   "增加 30 分鐘

WRITE:/ '目前時間:', SY-DATUM, SY-UZEIT.

PERFORM CALC_DATE_TIME USING SY-DATUM SY-UZEIT L_PARA
                       CHANGING L_DATE L_TIME.

WRITE:/ '加 30 分鐘時間:', L_DATE, L_TIME.

FORM CALC_DATE_TIME USING P_WRITEDATE
                          P_WRITETIME
                          P_SECOND
                    CHANGING C_WRITEDATE
                             C_WRITETIME.

  DATA: L_DATE  TYPE SY-DATUM,
        L_DATE2 TYPE SY-DATUM.
  DATA: L_DAYS  TYPE I.
  DATA: L_DAYS_TIMESTAMP TYPE TIMESTAMPL.
  DATA: L_HOUR(2) TYPE N,
        L_MIN(2)  TYPE N,
        L_SEC(2)  TYPE N,
        L_TIME_TIMESTAMP TYPE TIMESTAMPL.

  "THE UNIX EPOCH IS THE TIME 00:00:00 UTC ON 1 JANUARY 1970
  L_DATE = '19700101'.

  "計算日期與 1970/01/01 差的天數轉換秒數
  L_DATE2 = P_WRITEDATE.
  L_DAYS  = L_DATE2 - L_DATE.
  L_DAYS_TIMESTAMP = L_DAYS * 86400.  "24(HOURS) * 60(MINUTES) * 60(SECOND)

  "計算目前時間的秒數
  L_HOUR = P_WRITETIME+0(2).
  L_MIN  = P_WRITETIME+2(2).
  L_SEC  = P_WRITETIME+4(2).
  L_TIME_TIMESTAMP = L_HOUR * 60 * 60 + L_MIN * 60 + L_SEC.

  "計算完目前要累加 or 扣掉的時間 from p_second
  L_DAYS_TIMESTAMP = L_DAYS_TIMESTAMP + L_TIME_TIMESTAMP + P_SECOND.

  "透過 DIV 86400 取得轉換的天數
  L_DAYS = L_DAYS_TIMESTAMP DIV 86400.
  L_DATE = L_DATE + L_DAYS.

  "透過 MOD 86400 取得扣掉天的剩餘秒數
  L_TIME_TIMESTAMP = L_DAYS_TIMESTAMP MOD 86400.
  "get hours
  L_HOUR = L_TIME_TIMESTAMP DIV 3600.
  "透過 MOD 3600 取得扣掉小時的剩餘秒數
  L_TIME_TIMESTAMP = L_TIME_TIMESTAMP MOD 3600.
  "get minutes
  L_MIN = L_TIME_TIMESTAMP DIV 60.
  "透過 MOD 60 取得剩餘的秒數
  L_TIME_TIMESTAMP = L_TIME_TIMESTAMP MOD 60.
  "get second
  L_SEC = L_TIME_TIMESTAMP.

  C_WRITEDATE = L_DATE.
  CONCATENATE L_HOUR ':' L_MIN ':' L_SEC INTO C_WRITETIME.

ENDFORM.                    " TRANSLATE_UTC0_TO_LOCAL



第三種方法:

另外還可以透過 FORM P6_TO_DATE_TIME_TZ(RSTR0400),但因為 P6_TO_DATE_TIME_TZ 傳入的 l_days_timestamp 必需是 UTC+00 的時間,所以除非能夠傳入這個時間,不然傳入的時間有可能會因為目前所在的 Server sy-zonlo 參數而影響傳入的時間

  DATA: l_time_timestamp.
  DATA: L_GET_TIME(10),
        L_GET_DATE LIKE SY-DATUM.

  PERFORM P6_TO_DATE_TIME_TZ(RSTR0400) USING l_days_timestamp
                                             L_GET_TIME
                                             L_GET_DATE.

沒有留言:

張貼留言

How to install & specified python version or distreibtuion package version in google colab

在買了 RTX 3080 要來 挖礦...  嗯~是跑機器學習後,結果發現了 GOOGLE COLAB,其實之前在「GAN 對抗式生成網路」一書就有看到,但資訊人就是什麼都想自己安裝,在本機用 Anaconda + pyCharm 弄了 GPU 環境,結果有天從新竹回家發現家裡沒...