标题:VFP 学习、开发漫谈 (三)
只看楼主
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:649
专家分:2156
注 册:2014-2-7
结帖率:96.77%
已结贴  问题点数:10 回复次数:19 
VFP 学习、开发漫谈 (三)
今天,就从一个古老的 DATE()函数聊起吧。

DATE()函数的主要功能是返回系统时钟的当前日期,如:?DATE() 的运行结果是 2014.02.24。显示的格式受 Set Date和 Set Century设置的影响。我们中国人习惯于“年月日”格式,一般设置 Set Date Ansi,为了避免2000年问题,设置 Set Century ON 以便用4位数表示年份。

DATE()函数还有一个附属功能:返回指定年、月、日的日期,如:DATE(2014,2,24)将返回 2014.02.24。这里要注意一点:由年月日三个数值组成的日期必须是一个有效的日期,如 ? DATE(2014,13,24) 在运行时就出现语法错误,因为月份不可能有13月。这一点就没有 CTOD()函数健壮,? CTOD('2014.13.24') 返回空日期。

我们可以利用CTOD()函数对无效字符串返回空日期的特点,轻松判断某一年是闰年还是平年。思路就是判断该年度的2月29日是否是一个有效的日期。下述代码可判断2014年是闰年还是平年:

? IIF(EMPTY(CTOD('2014.2.29')),'2014年是平年','2014年是闰年')

这要比闰年的判断依据“能被4整除不能被100整除或能被400整除……”要简单的多!

给一个变量赋一个空日期常数:dNow = {},给一个变量赋一个特定的值:dNow = {^2014.2.24},注意年份前的“^”。有些书上,对常数和常量混为一谈,常数是一个字面量,如:1,"China",.T.,{^2012.02.24},常量是指用 #DEFINE 定义的符号,如:#DEFINE CR CHR(13)。

在实际编程中,我们经常碰到需要取某月的最后一天,如:查询材料明细帐时,需要输入日期范围,若当前日期大于10号,一般查询本月业务较多,默认日期范围设置为本月1日到当前日期是合适的;若当前日期小于10号,则查询上月业务较多,默认日期范围设为上月1日至上月月末较合适。类似的应用还有很多。

若要取上个月最后一天可采用:DATE()-DAY(DATE()),其思路是将当前日期前移若干天数。若要取变量 dDate的月份最后一天,可采用:GOMONTH(dDate,1)-DAY(GOMONTH(dDate,1)),思路是将日期后移一个月然后再前移若干天。

我们都知道 DTOS(dDate) 返回 YYYYMMDD 的字符串,如:20140224。那么如何将 YYYYMMDD 字符串转换为日期型变量呢?

第一种方法:将源字符串中的年、月、日分离出来,加上分隔符“.”后再使用 CTOD()转换成日期型变量。这是最先想到的方法。

? CTOD(LEFT(cDate,4) + '.' + SUBSTR(cDate,3,2) + '.' + RIGH(cDate,2))

第二种方法:将源字符串中的年、月、日分离出来转换成数值型,再使用 DATE()函数返回一个日期型变量。这种方法也不太简练。

? DATE(VAL(LEFT(cDate,4)),VAL(SUBSTR(cDate,3,2)),VAL(RIGH(cDate,2)))

第三种方法:使用TRANSFORM()函数,将源字符串转换成“YYYY.MM.DD”格式,再使用 CTOD()函数。这种方法最简练。

? CTOD(TRANS(cDate,'@R 9999.99.99'))

说起 TRANSFORM()函数,我真是爱死它啦!再举几个应用实例:

1. 将日期变量 dDate 显示成“2014年2月24日”字样

    ? TRANS(dDate,'@YL')        && @YL 表示长日期格式,限于中文操作系统
   
2. 对于一个数值型变量 nNum,将其转换成字符串,没有前导空格和小数点后面的 0,如:123.00 转换成 123

    ? TRANS(nNum)

3. 若不知道变量 uVal 的数据类型,现在要将其转换成字符串,最简单的方法还是使用 TRANS()函数。

    ? "uVal=" + TRANS(uVal)

4. 将一个整型变量 nNum 转换成长度为 6 位的字符串,左边用 0 填充,如:123 转换为 000123。

    ? TRANS(nNum,'@L 999999')
   
    实际应用中,我也经常使用 PADL()函数,如下:
   
    ? PADL(nNum,6,'0')
   
5. 变量 cMac 存储的值为网卡的 MAC 地址,如:002421DD0303,现在要将其显示为 00-24-21-DD-03-03

    ? TRANS(cMac,'@R XX-XX-XX-XX-XX-XX')

DATE()函数提取的是本地终端上的当前日期。实际应用中,因CMOS电池失效造成系统时钟错误的情况经常遇到。此时,DATE()函数返回的是错误的日期。对于不太重要的日期或只对日期赋初值,而用户还可以二次编辑时,可以使用 Date()函数,问题不大。对于重要的日期,必须另辟蹊径。解决的思路是将终端的日期与服务器上的日期同步或干脆直接取服务器日期。

假设服务器的 IP 是 192.168.0.1,在 VFP 下运行“RUN Net Time \\192.168.0.1 /Set /Yes”即可将本地终端的时间与服务器同步。

直接取服务器的当前日期,需要借助 SQL Server,最好是定义一个取当前日期的自定义函数 GetDate(),如下所示(其中的 GetHandle()是建立一个连接到SQL Server的连接句柄并保存到全局变量 gnHandle):
程序代码:
FUNCTION GetDate()
    LOCAL nSelect,dDate
    nSelect = SELECT()
    IF GetHandle()<0 OR SQLEXEC(gnHandle,'SELECT getdate()','curRet')<0
        dDate = DATE()              && 取服务器时间失败时,取本机时间
    ELSE
        dDate = TTOD(curRet.exp)    && 由日期时间型转换为日期型
        USE IN curRet
    ENDIF
    SELECT (nSelect)
    RETURN dDate
ENDFUNC

FUNCTION GetHandle()
    * 检测连接状态
    LOCAL nSqlState
    IF TYPE('gnHandle') = 'U'
        PUBLIC gnHandle
    ENDIF
    TRY
        nSqlState = SQLEXEC(gnHandle,"")
    CATCH
        nSqlState = -1
    ENDTRY
    * 连接无效时,重建连接
    IF nSqlState < 1
        gnHandle = SQLSTRINGCONNECT("DRIVER=SQL Server;SERVER=192.168.0.1;UID=sa;PWD=12345;DATABASE=mis")
    ENDIF
    * 重建连接失败时给出提示
    IF gnHandle < 0
        MESSAGEBOX('与 SQL Server 数据库连接失败!',16,'提示')
    ENDIF
    * 返回连接句柄
    RETURN gnHandle
ENDFUNC


[ 本帖最后由 liuxingang28 于 2014-7-3 09:18 编辑 ]
收到的鲜花
  • tlliqi2014-02-25 11:39 送鲜花  20朵   附言:加分
  • qjbzjp2014-02-26 10:56 送鲜花  10朵   附言:很精彩!
  • hu9jj2014-02-26 10:58 送鲜花  40朵   附言:好文章
搜索更多相关主题的帖子: 中国人 年月日 开发 2014 影响 
2014-02-25 11:20
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
得分:0 
学习
2014-02-25 11:25
wengjl
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:108
帖 子:2175
专家分:3785
注 册:2007-4-27
得分:0 
学习了,受益非浅

只求每天有一丁点儿的进步就可以了
2014-02-25 13:01
cymjx
Rank: 2
等 级:论坛游民
帖 子:74
专家分:29
注 册:2010-11-9
得分:0 
值得认真学习!
2014-02-25 14:28
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
大开眼界!我将日期数据转换成YYYY年MM月DD日时还是使用最原始的分别提取方法,没想到还有现成的函数,真是学无止境啊。

活到老,学到老! http://www. E-mail:hu-jj@
2014-02-26 10:52
qjbzjp
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:尧的故乡
等 级:贵宾
威 望:48
帖 子:1914
专家分:4397
注 册:2007-3-14
得分:0 
非常精妙的体会,值得认真学习。

相互学习,互相交流,共同提高。
2014-02-26 10:55
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:323
帖 子:9621
专家分:26174
注 册:2012-2-5
得分:10 
TRANSFORM()函数的用途很广,抛砖引玉,下面举几个示例:
1.
?TRANSFORM(VAL(DTOS(DATE())),'@ 9999年99月99日')
结果:
2014年02月26日

2.
?TRANSFORM(VAL(CHRTRAN(TIME(),":","")),'@ 99时99分99秒')
结果:
22时22分22秒

3.身份证字符型日期转换为日期型数据
NL=[19780324]
?CTOD(TRANSFORM(VAL(NL),[@ 9999-99-99]))

坚守VFP最后的阵地
2014-02-26 11:19
flash7914
Rank: 2
等 级:论坛游民
帖 子:40
专家分:14
注 册:2013-4-7
得分:0 
很实用,谢谢,继续支持。
2014-02-26 12:25
flash7914
Rank: 2
等 级:论坛游民
帖 子:40
专家分:14
注 册:2013-4-7
得分:0 
回复 7楼 sdta
谢谢。这个补充很有用。论坛的强大之处就是看回复也能得到帮助。
2014-02-26 16:26
asdf_123000
Rank: 4
等 级:业余侠客
威 望:1
帖 子:262
专家分:203
注 册:2012-12-20
得分:0 
学习
2014-02-27 13:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-427644-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.721511 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved