论文部分内容阅读
Abstract:This article gives a computer-defined function, descriptive the design mentality and the source code of the function process, expounds this method simplicity, versatility, easy operational and reliability, and introduce its service condition unified the application example.
Keywords:hydrological data;time interpolation;time average;function;example
摘要:本文给出一个计算机自定义函数,叙述了该函数过程的设计思路和源程序代码,阐明了此方法的简单性、通用性、易操作性和可靠性,并结合应用实例介绍了其使用情况。
关键词:水文资料时间差值和均值函数举例
中图分类号:O174文献标识码:A 文章编号:
1问题的提出
在工作实践中,经常需要我们对一个时间段进行各类操作,比如计算两个时间的历时即差值,两个时间的中间时间即均值。如果该差值是很小的,不难由人工直接计算这两项数据,而在计算机进行运算和管理时却变成了一个复杂的过程。因为,这两个时间往往都是日期-时间型数据,各类软件开发工具均未能直接给出它们的关系运算函数,或只是对日期和时间分别给出简单的运算,实践中遇到的跨日、跨月甚至跨年度的时间段的处理会给我们带来更大难度。从水文测验过程到水情拍报乃至资料整编,都常常遇到这一问题,给计算机处理带来极大的不便。为此,笔者经过摸索和反复验证,给出一个成熟可靠的自定义函数,调入计算机内存后便可灵活地对任意两个日期——时间型数据进行操作。
2自定义函数的设计
2.1设计思路
构造该函数过程,按不同的参数返回(Return)两个不同结果,即时间差值和均值。该函数有5个参数,分别设定为第一时间的日期和时分dat1和tim1、第二时间的日期和时分dat2和tim2 ,控制函数返回差值或均值参数cs(Integer型),取1或0 ,于是给出函数型式Op_DateTime(dat1,tim1,dat2,tim2,cs)。比较出两个日期-时间型数据的较小者,提取其中的年份并以该年份的1月1日00:00时为参照时间,如此就会最简单地使用系统函数计算出两个时间分别同这一参照时间的差值,换算为分钟,则这两个差值的差即为所求差值。将该差值除以2,按年月日时规则,通过循环数据结构控制累加到第一时间,即为所求均值。
2.2函数源代码(PowerScript脚本)
//函数形式 Op_DateTime(dat1,tim1,dat2,tim2,cs)
//返回值jisuan_date_time为 String 型
//dat1、dat2为Date型,tim1、tim2为Time型, cs为Integer 型
//cs = 1函数返回差值,否则返回均值
//下面声明程序使用的变量,考虑分钟等数值过大,尽量使用Long和Decimal型
Date dat,dat0
Time tim
Long tianshu1,tianshu2,ztime,xiaoshi,yue,tian,shi,fen
Long jisuan_d jisuan_m,jisuan_y,i,m_2
Dec fenzhong
String jisuan_date_time = ""
//如果给定的第一时间大于第二时间,则交换一下位置
IF DateTime(dat1,tim1) > DateTime(dat2,tim2) THEN
dat = dat1
dat1 = dat2
dat2 = dat
tim = tim1
tim1 = tim2
tim2 = tim
END IF
dat0 = Date(Year(dat1),1,1) //虚拟第一时间年份的1月1日00:00时做参照时间
tianshu1 = DaysAfter(dat0,dat1) //取得第一时间同参照时间的之间的天数
tianshu2 = DaysAfter(dat0,dat2) //取得第二时间同参照时间的之间的天数
//计算两个时间之间总分钟数
ztime = tianshu2 * 1440 + Hour(tim2) * 60 + Minute(tim2)
ztime = ztime - (tianshu1 * 1440 + Hour(tim1) * 60 + Minute(tim1))
IF cs = 1 THEN
jisuan_date_time = String(Ztime) //得到参数为1时的时间间隔(分钟,String型)
ELSE//参数不为1时,推算两个时间的中值或叫均值
jisuan_d = Day(dat1)//得到第一时间中的天数
jisuan_m = Month(dat1)//得到第一时间中的月份
jisuan_y = Year(dat1) //得到第一时间中的年度
fenzhong = Minute(tim1) + Ztime/2
i = 0
DO UNTIL fenzhong <= 32766//将分钟变得足够小,以便下边能取Integer
fenzhong = fenzhong - 32766//并要保证分钟整数部分原有的奇和偶
i = i + 1
LOOP
IF fenzhong > Int(fenzhong) THEN//考虑逢5奇进偶舍
IF Int(fenzhong)/2 = Int(Int(fenzhong)/2) THEN
fenzhong = Int(fenzhong)
ELSE
fenzhong = Int(fenzhong) + 1
END IF
END IF
fenzhong = fenzhong + 32766 * i
fen = Mod(fenzhong,60) //取余数得到平均时间的分钟值
xiaoshi = Int(fenzhong/60) + Hour(tim1)
shi = Mod(Dec(xiaoshi),24) //取余數得到平均时间的小时值
tian = Int(xiaoshi/24) //取整数得到进位的天数
IF tian > 0 THEN
FOR i = 1 TO tian//按不同的月份和年份逐日进位
CHOOSE CASE jisuan_m
CASE 1,3,5,7,8,10,12
IF jisuan_d < 31 THEN
jisuan_d = jisuan_d + 1
ELSE
jisuan_d = 1
IF jisuan_m = 12 THEN
jisuan_m = 1
jisuan_y = jisuan_y + 1
ELSE
jisuan_m = jisuan_m + 1
END IF
END IF
CASE 2
IF jisuan_y = Int(jisuan_y/4) * 4 THEN//考虑闰年情况
m_2 = 29
ELSE
m_2 = 28
END IF
IF jisuan_d < m_2 THEN
jisuan_d = jisuan_d + 1
ELSE
jisuan_d = 1
jisuan_m = jisuan_m + 1
END IF
CASE ELSE
IF jisuan_d < 30 THEN
jisuan_d = jisuan_d + 1
ELSE
jisuan_d = 1
jisuan_m = jisuan_m + 1
END IF
END CHOOSE
NEXT
END IF
//按yyyy-mm-dd hh:mm格式計算取得平均时间结果,String型
jisuan_date_time =jisuan_date_time + String(jisuan_y)
IF jisuan_m < 10 THEN
jisuan_date_time =jisuan_date_time + "-0" + String(jisuan_m)
ELSE
jisuan_date_time =jisuan_date_time + "-" + String(jisuan_m)
END IF
IF jisuan_d < 10 THEN
jisuan_date_time =jisuan_date_time + "-0" + String(jisuan_d)
ELSE
jisuan_date_time =jisuan_date_time + "-" + String(jisuan_d)
END IF
IF shi < 10 THEN
jisuan_date_time =jisuan_date_time + " 0" + String(shi)
ELSE
jisuan_date_time =jisuan_date_time + " " + String(shi)
END IF
IF fen < 10 THEN
jisuan_date_time =jisuan_date_time + ":0" + String(fen)
ELSE
jisuan_date_time =jisuan_date_time + ":" + String(fen)
END IF
END IF
RETURN jisuan_date_time//返回函数值,String型
3自定义函数的应用
3.1使用该函数应注意的问题
从程序代码可以看到,为最大限度满足其通用性,一方面,该函数不论是对几分钟的短时间段,还是对几年的长历时,都能正确返回差值或均值。另一方面,在使用系统函数时,尽量兼顾各类程序语言。例如,PowerScript函数库中的Ceiling(n)函数能够返回大于数值型变量n的最小整数,但在这里没有使用,而是使用的取整函数Int(),并对超出Integer型范围的数进行了处理。在使用该函数时,除考虑不同软件开发语言的差别外,还应注意以下几点:一是该函数在计算均值时考虑了“四舍六入,逢五奇进偶舍”的原则,如果在实际应用中不需要这种处理,就直接应用系统的“四舍五入”(Round)函数。二是由于该函数是通过参数控制返回2个可选择而且是不同类型的结果,因此,不论是差值还是均值都已经定义为字符型,那么返回的数据在使用时都须进行数据类型转换。三是该函数操作和返回的数据均精确到分钟,如果实际需要更精确,可通过增加循环控制来实现。
3.2在实测流量、输沙量管理系统中的应用实例
该函数在笔者研制的实测流量、输沙量管理系统中发挥了非常理想的作用,那就是在实测流量、输沙量的计算过程中能获取用户输入的起止2个施测时间,均为日期-时间型,由程序来取得平均施测时间以对应本次瞬时流量和输沙量,并据此点绘流量和输沙量过程线,推算日平均流量和输沙率,为了辅助报汛,还计算出累计过水量和输沙总量。如表1。
表130909999_2007-12-28流量(输沙)过程
实测流量、输沙量成果表同过程线图建立链接后,系统自动插入各日00:00时和24:00时的数据,按照连实测流量过程线法推流,可使用该自定义函数在任意两个时间段内插入一个均值时间及相应的流量、输沙量,再按照人为需要和过程线趋势进行手工调整,直到取得满意的过程线后实施相应的计算功能。该函数在计算各时段的历时过程中,为该程序模块取得了事半功倍的效果。
4结语
本文给出的这一函数,从思路到实现的过程都是严密的,全面考虑了各种情况,大量的实际应用更表明了该函数具有简单性、通用性、易操作性和可靠性,而且作为自定义函数,调入计算机内存后同系统函数的运算效果是相同的,在此提供给广大同仁及爱好者。当然,这只是笔者在水文资料电算中的一点经验之谈,不妥之处,敬请指正。
作者简介:
张英骏(1967-),男 ,河北省黄骅市人,高级工程师,主要从事水文水资源管理工作。
刘国强(1976-),男 ,河北省沧县人,工程师,主要从事水文资料整编工作。
赵国辉(1981-),男 ,河北省唐山人,助理工程师,主要从事水文资料整编工作。
注:文章内所有公式及图表请用PDF形式查看。
Keywords:hydrological data;time interpolation;time average;function;example
摘要:本文给出一个计算机自定义函数,叙述了该函数过程的设计思路和源程序代码,阐明了此方法的简单性、通用性、易操作性和可靠性,并结合应用实例介绍了其使用情况。
关键词:水文资料时间差值和均值函数举例
中图分类号:O174文献标识码:A 文章编号:
1问题的提出
在工作实践中,经常需要我们对一个时间段进行各类操作,比如计算两个时间的历时即差值,两个时间的中间时间即均值。如果该差值是很小的,不难由人工直接计算这两项数据,而在计算机进行运算和管理时却变成了一个复杂的过程。因为,这两个时间往往都是日期-时间型数据,各类软件开发工具均未能直接给出它们的关系运算函数,或只是对日期和时间分别给出简单的运算,实践中遇到的跨日、跨月甚至跨年度的时间段的处理会给我们带来更大难度。从水文测验过程到水情拍报乃至资料整编,都常常遇到这一问题,给计算机处理带来极大的不便。为此,笔者经过摸索和反复验证,给出一个成熟可靠的自定义函数,调入计算机内存后便可灵活地对任意两个日期——时间型数据进行操作。
2自定义函数的设计
2.1设计思路
构造该函数过程,按不同的参数返回(Return)两个不同结果,即时间差值和均值。该函数有5个参数,分别设定为第一时间的日期和时分dat1和tim1、第二时间的日期和时分dat2和tim2 ,控制函数返回差值或均值参数cs(Integer型),取1或0 ,于是给出函数型式Op_DateTime(dat1,tim1,dat2,tim2,cs)。比较出两个日期-时间型数据的较小者,提取其中的年份并以该年份的1月1日00:00时为参照时间,如此就会最简单地使用系统函数计算出两个时间分别同这一参照时间的差值,换算为分钟,则这两个差值的差即为所求差值。将该差值除以2,按年月日时规则,通过循环数据结构控制累加到第一时间,即为所求均值。
2.2函数源代码(PowerScript脚本)
//函数形式 Op_DateTime(dat1,tim1,dat2,tim2,cs)
//返回值jisuan_date_time为 String 型
//dat1、dat2为Date型,tim1、tim2为Time型, cs为Integer 型
//cs = 1函数返回差值,否则返回均值
//下面声明程序使用的变量,考虑分钟等数值过大,尽量使用Long和Decimal型
Date dat,dat0
Time tim
Long tianshu1,tianshu2,ztime,xiaoshi,yue,tian,shi,fen
Long jisuan_d jisuan_m,jisuan_y,i,m_2
Dec fenzhong
String jisuan_date_time = ""
//如果给定的第一时间大于第二时间,则交换一下位置
IF DateTime(dat1,tim1) > DateTime(dat2,tim2) THEN
dat = dat1
dat1 = dat2
dat2 = dat
tim = tim1
tim1 = tim2
tim2 = tim
END IF
dat0 = Date(Year(dat1),1,1) //虚拟第一时间年份的1月1日00:00时做参照时间
tianshu1 = DaysAfter(dat0,dat1) //取得第一时间同参照时间的之间的天数
tianshu2 = DaysAfter(dat0,dat2) //取得第二时间同参照时间的之间的天数
//计算两个时间之间总分钟数
ztime = tianshu2 * 1440 + Hour(tim2) * 60 + Minute(tim2)
ztime = ztime - (tianshu1 * 1440 + Hour(tim1) * 60 + Minute(tim1))
IF cs = 1 THEN
jisuan_date_time = String(Ztime) //得到参数为1时的时间间隔(分钟,String型)
ELSE//参数不为1时,推算两个时间的中值或叫均值
jisuan_d = Day(dat1)//得到第一时间中的天数
jisuan_m = Month(dat1)//得到第一时间中的月份
jisuan_y = Year(dat1) //得到第一时间中的年度
fenzhong = Minute(tim1) + Ztime/2
i = 0
DO UNTIL fenzhong <= 32766//将分钟变得足够小,以便下边能取Integer
fenzhong = fenzhong - 32766//并要保证分钟整数部分原有的奇和偶
i = i + 1
LOOP
IF fenzhong > Int(fenzhong) THEN//考虑逢5奇进偶舍
IF Int(fenzhong)/2 = Int(Int(fenzhong)/2) THEN
fenzhong = Int(fenzhong)
ELSE
fenzhong = Int(fenzhong) + 1
END IF
END IF
fenzhong = fenzhong + 32766 * i
fen = Mod(fenzhong,60) //取余数得到平均时间的分钟值
xiaoshi = Int(fenzhong/60) + Hour(tim1)
shi = Mod(Dec(xiaoshi),24) //取余數得到平均时间的小时值
tian = Int(xiaoshi/24) //取整数得到进位的天数
IF tian > 0 THEN
FOR i = 1 TO tian//按不同的月份和年份逐日进位
CHOOSE CASE jisuan_m
CASE 1,3,5,7,8,10,12
IF jisuan_d < 31 THEN
jisuan_d = jisuan_d + 1
ELSE
jisuan_d = 1
IF jisuan_m = 12 THEN
jisuan_m = 1
jisuan_y = jisuan_y + 1
ELSE
jisuan_m = jisuan_m + 1
END IF
END IF
CASE 2
IF jisuan_y = Int(jisuan_y/4) * 4 THEN//考虑闰年情况
m_2 = 29
ELSE
m_2 = 28
END IF
IF jisuan_d < m_2 THEN
jisuan_d = jisuan_d + 1
ELSE
jisuan_d = 1
jisuan_m = jisuan_m + 1
END IF
CASE ELSE
IF jisuan_d < 30 THEN
jisuan_d = jisuan_d + 1
ELSE
jisuan_d = 1
jisuan_m = jisuan_m + 1
END IF
END CHOOSE
NEXT
END IF
//按yyyy-mm-dd hh:mm格式計算取得平均时间结果,String型
jisuan_date_time =jisuan_date_time + String(jisuan_y)
IF jisuan_m < 10 THEN
jisuan_date_time =jisuan_date_time + "-0" + String(jisuan_m)
ELSE
jisuan_date_time =jisuan_date_time + "-" + String(jisuan_m)
END IF
IF jisuan_d < 10 THEN
jisuan_date_time =jisuan_date_time + "-0" + String(jisuan_d)
ELSE
jisuan_date_time =jisuan_date_time + "-" + String(jisuan_d)
END IF
IF shi < 10 THEN
jisuan_date_time =jisuan_date_time + " 0" + String(shi)
ELSE
jisuan_date_time =jisuan_date_time + " " + String(shi)
END IF
IF fen < 10 THEN
jisuan_date_time =jisuan_date_time + ":0" + String(fen)
ELSE
jisuan_date_time =jisuan_date_time + ":" + String(fen)
END IF
END IF
RETURN jisuan_date_time//返回函数值,String型
3自定义函数的应用
3.1使用该函数应注意的问题
从程序代码可以看到,为最大限度满足其通用性,一方面,该函数不论是对几分钟的短时间段,还是对几年的长历时,都能正确返回差值或均值。另一方面,在使用系统函数时,尽量兼顾各类程序语言。例如,PowerScript函数库中的Ceiling(n)函数能够返回大于数值型变量n的最小整数,但在这里没有使用,而是使用的取整函数Int(),并对超出Integer型范围的数进行了处理。在使用该函数时,除考虑不同软件开发语言的差别外,还应注意以下几点:一是该函数在计算均值时考虑了“四舍六入,逢五奇进偶舍”的原则,如果在实际应用中不需要这种处理,就直接应用系统的“四舍五入”(Round)函数。二是由于该函数是通过参数控制返回2个可选择而且是不同类型的结果,因此,不论是差值还是均值都已经定义为字符型,那么返回的数据在使用时都须进行数据类型转换。三是该函数操作和返回的数据均精确到分钟,如果实际需要更精确,可通过增加循环控制来实现。
3.2在实测流量、输沙量管理系统中的应用实例
该函数在笔者研制的实测流量、输沙量管理系统中发挥了非常理想的作用,那就是在实测流量、输沙量的计算过程中能获取用户输入的起止2个施测时间,均为日期-时间型,由程序来取得平均施测时间以对应本次瞬时流量和输沙量,并据此点绘流量和输沙量过程线,推算日平均流量和输沙率,为了辅助报汛,还计算出累计过水量和输沙总量。如表1。
表130909999_2007-12-28流量(输沙)过程
实测流量、输沙量成果表同过程线图建立链接后,系统自动插入各日00:00时和24:00时的数据,按照连实测流量过程线法推流,可使用该自定义函数在任意两个时间段内插入一个均值时间及相应的流量、输沙量,再按照人为需要和过程线趋势进行手工调整,直到取得满意的过程线后实施相应的计算功能。该函数在计算各时段的历时过程中,为该程序模块取得了事半功倍的效果。
4结语
本文给出的这一函数,从思路到实现的过程都是严密的,全面考虑了各种情况,大量的实际应用更表明了该函数具有简单性、通用性、易操作性和可靠性,而且作为自定义函数,调入计算机内存后同系统函数的运算效果是相同的,在此提供给广大同仁及爱好者。当然,这只是笔者在水文资料电算中的一点经验之谈,不妥之处,敬请指正。
作者简介:
张英骏(1967-),男 ,河北省黄骅市人,高级工程师,主要从事水文水资源管理工作。
刘国强(1976-),男 ,河北省沧县人,工程师,主要从事水文资料整编工作。
赵国辉(1981-),男 ,河北省唐山人,助理工程师,主要从事水文资料整编工作。
注:文章内所有公式及图表请用PDF形式查看。