在填充字段中添加 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 似乎都假定了一天中的时间。)
我是编程和 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 似乎都假定了一天中的时间。)