弃VBScript而选Jscript的八大理由
理由7:JScript日期处理功能可以避免本地时间问题
在VBScript中,一个日期的值总是“本地”的。根据时间的来源不同,当计算日期的时候,这可能导致协调世界时(UTC)和夏令时间的错误。让我们来看一个实际的例子。
pwdLastSet活动目录(AD)用户属性被存储为自12:00am January 1, 1601, UTC以来的一个间隔数字。以下是一个如何转换pwdLastSet值到一个VBScript日期的示例代码。
这个结果得出来的值是在UTC中的,VBScript没有提供方法来转换这个日期为本地时间。我曾经看到一些示例代码通过从注册表中阅读本地时间偏移来调整到本地时间的日期。但是这是一个非常麻烦而且脆弱的解决方案,首先,它假定运行这个脚本的帐号具有权限可以阅读注册表的值,其次它假定注册表的值从来没有被改变,第三,它不能适应夏令时的调整,不知道返回的结果是不是在经过一个DST改变后的。举个例子来说,假若我们要计算将来一个用户的密码在将来要失效的日期和时间,当前的本地时间偏移可能会在将来因为经过了DST修改,从而变得不准确。
在JScript中,日期被Date对象来处理。JScript的Date对象可用来表示任意日期和时间,获取当前系统日期,以及计算日期差。它有几种预定义的属性和方法。Date对象存储一周的某一天;月、日、年;以及以小时、分钟、秒、毫秒计的时间。此信息建立在自从协调通用时间(UTC)1970年1月1日00:00:00.000以来的毫秒数的基础上。以下是在JScript中的等效代码:
我使用我自己域上的一个帐号来完成了这个实验。VBScript返回的时间是16 May 2007 15:12,而JScript返回的时间是16 May 2007 09:12。注意,JScript的答案是正确的,本地时间是9:12而不是15:12,因为我的本地时区比UTC早6个小时。
在VBScript中,一个日期的值总是“本地”的。根据时间的来源不同,当计算日期的时候,这可能导致协调世界时(UTC)和夏令时间的错误。让我们来看一个实际的例子。
pwdLastSet活动目录(AD)用户属性被存储为自12:00am January 1, 1601, UTC以来的一个间隔数字。以下是一个如何转换pwdLastSet值到一个VBScript日期的示例代码。
这个脚本片段连接到活动目录中的John Smith的用户帐号对象,并返回帐号的pwdLastSet属性。(Set声明是需要的,因为pwdLastSet值是作为一个对象返回的。)接下来,代码通过读它的HighPat和LowPart属性,将pwdLastSet的值转换为一个单个32位值。(这个转换只是一个近似值,但是我们现在忽略这个微小的差别。)最后,代码增加这个天数到12:00am January 1, 1601,从而获得最终的结果。Dim UserDN, ADsUser, LastSet, NanoSecs, VBTime UserDN = "CN=John Smith,OU=Sales,DC=wascorp,DC=net" Set ADsUser = GetObject("LDAP://" & UserDN) Set LastSet = ADsUser.pwdLastSet NanoSecs = (LastSet.HighPart * (2 ^ 32)) + LastSet.LowPart VBTime = CDate(#1/1/1601# + (NanoSecs / 600000000 / 1440)) ' Returns UTC time
这个结果得出来的值是在UTC中的,VBScript没有提供方法来转换这个日期为本地时间。我曾经看到一些示例代码通过从注册表中阅读本地时间偏移来调整到本地时间的日期。但是这是一个非常麻烦而且脆弱的解决方案,首先,它假定运行这个脚本的帐号具有权限可以阅读注册表的值,其次它假定注册表的值从来没有被改变,第三,它不能适应夏令时的调整,不知道返回的结果是不是在经过一个DST改变后的。举个例子来说,假若我们要计算将来一个用户的密码在将来要失效的日期和时间,当前的本地时间偏移可能会在将来因为经过了DST修改,从而变得不准确。
在JScript中,日期被Date对象来处理。JScript的Date对象可用来表示任意日期和时间,获取当前系统日期,以及计算日期差。它有几种预定义的属性和方法。Date对象存储一周的某一天;月、日、年;以及以小时、分钟、秒、毫秒计的时间。此信息建立在自从协调通用时间(UTC)1970年1月1日00:00:00.000以来的毫秒数的基础上。以下是在JScript中的等效代码:
这个代码与上面VBScript代码完成同样的事情,它拷贝pwdLastSet的值到一个32位数值中。但是,注意代码的最后一行使用了Date对象的UTC方法来建造一个UTC日期。最漂亮的是,当你取回这个值的时候,JScript知道如何将它转换成本地时间。var userDN, aDsUser, lastSet, nanoSecs, jsTime; userdn = "CN=John Smith,OU=Sales,DC=wascorp,DC=net"; aDsUser = GetObject("LDAP://" + userDN); lastSet = aDsUser.pwdLastSet; nanoSecs = ((lastSet.HighPart * (Math.pow(2, 32))) + lastSet.LowPart); jsTime = new Date(Date.UTC(1601, 0, 1, 0, 0, 0, nanoSecs / 10000)); // Natively stored as UTC
我使用我自己域上的一个帐号来完成了这个实验。VBScript返回的时间是16 May 2007 15:12,而JScript返回的时间是16 May 2007 09:12。注意,JScript的答案是正确的,本地时间是9:12而不是15:12,因为我的本地时区比UTC早6个小时。
0
相关文章