如何在时间戳中添加天数?

4

如何将一个TIMESTAMP类型的时间加1天,并正确地滚动月份/年份?

例如:

data lv_time type TIMESTAMP value '20180228000000'.
data(lv_new_time) = lv_time + 1. " should be '20180301000000', but instead is '20180228000001'
data(lv_new_time2) = lv_time + 1000000. " should be '20180301000000', but instead is '20180229000000'

3
在SAP中,TIMESTAMP类型只是一个浮点类型,因此您得到的结果是正确的。然而,有一种整洁的方法可以做到这一点。我记得我以前做过,但我需要查看我的资源。会让您知道。 - Jagger
5个回答

7

在查看Jagger的答案后,我查看了TIMESTAMP_DURATION_ADD函数的内部实现,并发现了一些ABAP语法,可以不需要调用函数就完成相同的工作。

constants: lc_time_zone type timezone value 'UTC'.
data lv_timestamp_before type timestamp value '20180228001234'.
data lv_timestamp_after type timestamp.
data lv_date like sy-datum.
data lv_time like sy-uzeit.

convert time stamp lv_timestamp_before time zone lc_time_zone
    into date lv_date time lv_time.
lv_date = lv_date + 1.
convert date lv_date time lv_time
    into time stamp lv_timestamp_after time zone lc_time_zone.

2
我仍然认为调用函数模块是一个更好的主意。 :) - Jagger
1
@ Jagger,怎么了? :) 就个人而言,我喜欢使用基本的ABAP语法的想法。它只需要3行代码,更加系统无关。 - Jonathan Benn
3
经验法则:SAP建议不要使用“未发布”函数模块(即有一天,SAP可能会在没有警告或标记为过时的情况下将其删除)。CONVERT已经发布并进行了文档化。同时CONVERT更快。 - Sandra Rossi
另一方面,经验法则通常是不要复制代码。 :) - Jagger
1
@Jagger 这不是“重复”,因为它只有3个ABAP语句 - 甚至可以简化它以删除2个CONVERT,并且只进行赋值操作,无需受到SAP代码的启发:) data(tstmp) = value tzntimestp( lv_timestamp ). ADD 1 TO tstmp(8). lv_timestamp = tstmp. 但是,我不太喜欢它,所以没有完美的解决方案!(主要是因为SAP没有提供基于内核的日期/时间库) - Sandra Rossi

7

如果您不想恢复旧的过程式编程,可以按照文档中所述使用CL_ABAP_TSTMP类。

DATA some_timestamp TYPE timestamp VALUE '20180228000000'.
DATA(new_timestamp) = cl_abap_tstmp=>add(
    tstmp = some_timestamp
    secs  = ( 365 * 24 * 60 * 60  )
).

很遗憾CL_ABAP_TSTMP=>SECSOFDAY是私有的...但是,至少这让你思考如何处理闰年...


你能否给我们的读者提供一个可工作的代码示例呢? :) - Jonathan Benn
好的,非常符合我想要的。谢谢! - TheNickest

5

这里有一个对你有用的解决方案。在你的系统中应该可以使用函数模块TIMESTAMP_DURATION_ADD

REPORT zzz.

DATA lv_time TYPE timestamp VALUE '20180228000000'.

START-OF-SELECTION.
  DATA timestamp_out TYPE timestamp.

  CALL FUNCTION 'TIMESTAMP_DURATION_ADD'
    EXPORTING
      timestamp_in    = lv_time
      timezone        = 'UTC'
      duration        = 1
      unit            = 'TAG' " day (in German)
    IMPORTING
      timestamp_out   = timestamp_out
    EXCEPTIONS
      timestamp_error = 1
      OTHERS          = 2.

  ASSERT sy-subrc = 0.

  WRITE timestamp_out.

-1
您可以使用 FM IAM_TIMESTAMP_CALC 将一天添加到时间戳中,结果将为 20180301000000:
  DATA lv_time TYPE timestamp VALUE '20180228000000'.

  CALL FUNCTION 'IAM_TIMESTAMP_CALC'
    EXPORTING
      iv_refdate = lv_time
*     IV_XBACKWARD       =
      iv_days    = '1'
*     IV_HOURS   = '0'
*     IV_MINUTES = '0'
*     IV_SECONDS = '0'
    IMPORTING
      ev_date    = lv_time.

转储错误消息为“找不到函数模块“IAM_TIMESTAMP_CALC””。 - Jonathan Benn
你用的是哪个SAP版本啊?这个函数模块自2005年就存在了(尽管没有发布)。 - VXLozano
2
函数模块 IAM_TIMESTAMP_CALC 在 S/4HANA Infinity 系统(软件组件 S4CORE)和 Suite on HANA Infinity 系统(软件组件 SAP_APPL)中都不存在。因此,它绝对不是标准函数。 - Jonathan Benn

-2
我不确定它是否能够工作,但也许值得一试。
提取时间戳的日期,将日期加一天,并使用新日期和时间戳的其余部分创建一个新的时间戳。
类似以下内容:
data: stamp type timestamp value '20180301000000000',
      stamp_date type dats,
      new_stamp type timestamp.
stamp_date = stamp(8). "if it doesn't work, just look for a FM
add 1 to stamp_date.
new_stamp = stamp_date && stamp+8.

我不确定它是否可以直接使用,但我相信你可以找到一种方法让它正常工作...在我们等待正确答案的同时;)


以上代码将在 stamp_date = stamp(8) 处抛出消息为 Overflow during an arithmetic operation (type P) 的错误。我知道这很奇怪,因为 DATETIME 实际上是一个字符串,人们会期望字符串操作函数可以对其进行操作。你会推荐哪个函数模块?你能给出在这种情况下使用它的示例吗?谢谢! - Jonathan Benn
我不提供完整的工作代码,只是提示。检查Joszef的答案,它有效。 - VXLozano
1
这甚至不是一个明智的方法。请删除这个“答案”,并停止引导其他人在寻找答案时走弯路。 - vwegert
1
到目前为止,最受欢迎的答案使用了那种不明智的方法,只是配合一个适当的工作代码片段。 也许你对我的回答是正确的,但由于我在这里还很新,而且我也不确定,如果可以的话,请随意标记它并让管理员删除它。我不会抱怨的。 如果你不介意的话,我会让人们通过提出更合适的答案来淘汰我的答案。 - VXLozano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接