在填充字段中添加 x 分钟的代码

Code to add x minutes to time in fillin field

我是编程和 Progress 的初学者,首先 post 在 Whosebug 上,希望我 post 找对地方了!

我有一个填充字段,我在其中输入时间 (hh:mm),字符格式。我也有两个箭头,一个向前,一个向后,我想让它们在按下时分别加/减20分钟。

为此编写代码的好方法是什么?将当前时间值转换为整数和午夜后的秒数,然后添加/减去 1200 秒?我如何将结果恢复为 hh:mm 格式以显示在填充中?

非常感谢任何帮助! /艾伦

Progress TIME 函数 returns 午夜过后的整数秒数。因此,您转换为此类整数的想法与 4gl 中的其他用途一致,这是肯定的。

就我个人而言,我会保持 UI 和内部存储独立。所以我可能会有一个小时的变量,另一个是分钟的变量,第三个是秒的变量(如果你需要的话)。我会为所有 3 个使用整数,而不是字符。

我不知道 Progress 的版本是什么,也不知道你 运行 所处的环境是什么,但是这个快速而肮脏的小片段可能有一些有用的花絮:

define variable hh as integer no-undo format ">9".
define variable mm as integer no-undo format "99".
define variable ss as integer no-undo format "99".

define variable myTime as integer no-undo.

form
  hh mm ss
 with
  frame a
.

on value-changed of hh in frame a do:
  if integer( self:screen-value ) > 23 then
    do:
      hh = 23.
      display hh with frame a.
    end.
end.

on value-changed of mm in frame a do:
  if integer( self:screen-value ) > 59 then
    do:
      mm = 59.
      display mm with frame a.
    end.
end.

on value-changed of ss in frame a do:
  if integer( self:screen-value ) > 59 then
    do:
      ss = 59.
      display ss with frame a.
    end.
end.

update hh mm ss with frame a.

myTime = (( hh * 3600 ) + ( mm * 60 ) + ss ).

display string( myTime, "hh:mm:ss am" ).

我认为这会满足您的需要。让 ON CHOOSE 箭头按钮上的触发器 运行 changeMins 过程。传入您填写的字符时间字符串和 "Add" 或 "Subtract"。输出值将是新调整的时间字符串。然后您可以将填充的屏幕值设置为该输出值。

DEFINE VARIABLE cTime AS CHARACTER NO-UNDO.

cTime = "12:45".
RUN changeMins (INPUT-OUTPUT cTime, INPUT "Add").
MESSAGE cTime VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.


PROCEDURE changeMins:

    DEFINE INPUT-OUTPUT PARAMETER pcTime AS CHARACTER NO-UNDO.
    DEFINE INPUT PARAMETER pcAction AS CHARACTER NO-UNDO.

    DEFINE VARIABLE iHr AS INTEGER NO-UNDO.
    DEFINE VARIABLE iMn AS INTEGER NO-UNDO.

    /* Split the time string into hours and minutes */
    ASSIGN
        iHr = INTEGER(ENTRY(1, pcTime, ":"))
        iMn = INTEGER(ENTRY(2, pcTime, ":"))
        NO-ERROR.

    IF ERROR-STATUS:ERROR THEN RETURN.

    /* Adjust the time */
    CASE pcAction:
        WHEN "Add" THEN iMn = iMn + 20.
        WHEN "Subtract" THEN iMn = iMn - 20.
    END CASE.

    /* Correct for boundaries */
    IF iMn > 59 THEN
        ASSIGN
            iMn = iMn - 60
            iHr = iHr + 1.

    IF iMn < 0 THEN
        ASSIGN
            iMn = iMn + 60
            iHr = iHr - 1.

    IF iHr > 23 THEN iHr = iHr - 24.
    IF iHr < 0 THEN iHr = iHr + 24.

    /* Build the new time string */
    pcTime = STRING(iHr, "99") + ":" + STRING(iMn, "99").

END PROCEDURE.

在此示例中,将 cTime 字符串更改为不同的时间并运行它。

根据 TheDrooper 的代码,我可能会编写如下代码以充分利用内置函数。 通常更可取的是至少仍然易于理解的较短代码。 还要考虑 Progress 没有优化编译器。如果您可以用更少的语句替换几个简单的语句(即使这些语句比需要的更复杂和强大),代码不仅更易于维护,而且速度更快。

DEFINE VARIABLE cTime AS CHARACTER NO-UNDO.

cTime = "12:45".
RUN changeMins (INPUT-OUTPUT cTime, INPUT "Add").
MESSAGE cTime VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.


PROCEDURE changeMins:

DEFINE INPUT-OUTPUT PARAMETER pcTime AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcAction AS CHARACTER NO-UNDO.

DEFINE VARIABLE iMn AS INTEGER NO-UNDO.

iMn = INTEGER(ENTRY(1, pcTime, ":")) * 60
    + INTEGER(ENTRY(2, pcTime, ":"))
    NO-ERROR. /* Calculate minutes since midnight */

IF ERROR-STATUS:ERROR THEN RETURN.

/* Adjust the time */
CASE pcAction:
    WHEN "Add" THEN iMn = iMn + 20.
    WHEN "Subtract" THEN iMn = iMn - 20.
END CASE.

/* Build the new time string */
pcTime = string(iMn * 60, 'HH:MM'). /* Convert minutes to seconds and convert the result to a string */

END PROCEDURE.

如果您需要允许更高的小时值(例如,如果该字段不代表一天中的时间而是代表时间间隔),您不能只使用字符串函数转换结果整数。在那种情况下你可以写

pcTime = string(iMn / 60, '99') + ':' + string(iMn mod 60, '99').

(TheDrooper 和 Tom Bascom 似乎都假定了一天中的时间。)