14.4.3 获取时间

Date对象还包括了当前时间,因此,我们可以在Web页面上显示当前时间,或者使用时间来判断访问者是在上午还是下午浏览页面。然后,我们可以根据该信息做些事情,例如,显示太阳当空或月亮当空的一幅背景图像。

高级用户诊断室

幕后的Date对象

JavaScript允许我们访问Date对象的特定元素,例如,年份或者日期。然而,JavaScript解释器实际上认为日期是一个数字,表示从1970年1月1日开始所经过的毫秒数。例如,2012年2月1日,对于JavaScript解释器来说,实际上是131328083200000。

这不是一个笑话:对JavaScript来说,时间的开始就是1970年1月1日。这个日期是由创建UNIX操作系统的程序员在20世纪70年代随意选取的(叫做Unix epoch),因为他们都同意以一种方式来记录时间。从那时候起,这种记录日期的方式在很多编程语言和平台中变得通用起来。无论何时,当你使用诸如getFullYear()的一个Date方法,JavaScript解释器执行数学计算来搞清楚它是哪一年(根据它从1970年1月1日算起经过了多少毫秒)。如果你想要看到一个特定日期的毫秒数字,可以使用getTime()方法:


var sometime=new Date();

var msElapsed=sometime.getTime();


以毫秒记录日期和时间,使得很容易计算日期之间的差距。例如,我们可以这样确定到下一个元旦的时间,首先获取从1/1/1970到下一个元旦的毫秒数,再减去从1/1/1970到今天的毫秒数:


//milliseconds from 1/1/1970 to today var today=new Date();

//milliseconds from 1/1/1970 to next new year

var nextYear=new Date(2013,0,1);

//calculate milliseconds from today to next year

var timeDiff=nextYear-today;


将两个日期相减,得到的结果是二者之间相差的毫秒数。如果你想要将其转换为有用的内容,只需要用这个数字除以一天中的毫秒数(来确定有多少天),或者除以一个小时的毫秒数(来确定有多少个小时),依次类推:


var second=1000;//1000 milliseconds in

a second

var minute=60*second;//60 seconds in

a minute

number of days

var hour=60*minute;//60 minutes in an

hour

var day=24*hour;//24 hours in a day


在这个例子中,你可能注意到了一种创建日期的不同方法:new Date(2009,0,1)。可以从14.4.4节了解这种方法的更多内容。


var totalDays=timeDiff/day;//total


我们可以使用getHours()、getMinutes()和getSeconds()方法来获取小时、分钟和秒。因此,要在Web页面上显示时间,可以在想要让时间出现的位置的HTML中添加如下代码:


var now=new Date();

var hours=now.getHours();

var minutes=now.getMinutes();

var seconds=now.getSeconds();

document.write(hours+":"+minutes+":"+seconds);


这段代码产生6:35:56这样的输出,表示上午6点35分56秒。然而,它也可能会产生你可能不喜欢的输出,例如,18:4:9表示下午6点4分9秒。一个问题是,对于阅读本书的大多数人来说,除非是军人,他们是不使用24小时时钟的。他们不知道18表示下午6点。甚至一个更大的问题是,时间使用以两位数表示分钟和秒钟的格式(即便分钟和秒钟都少于10),例如,6:04:09。幸运的是,调整上面的脚本来满足这些需求并不难。

将时间更改为a.m.和p.m.

要将时间从24小时时钟修改为12小时时钟,我们需要做几件事情。首先,我们需要确定时间是在上午(这样,我们可以在时间的后面添加'am')还是在下午(添加'pm')。其次,我们需要将大于12的任何小时数都转换为等值的12小时时钟(例如,将14改为2.p.m)。

下面的代码完成这一任务:


1 var now=new Date();

2 var hour=now.getHours();

3 if(hour<12){

meridiem='am';

5}else{

4

6

meridiem='pm';

7}

8 hour=hour%12;

9 if(hour==0){

10

hour=12;

11}

12 hour=hour+’’+meridiem;


注意:左边的那列数字只是为了方便你阅读下面的讨论而为行添加的编号。在自己的代码中,不要输入这些行号。

第1行和第2行获取当前的日期和时间,并且将当前的小时数存储在一个名为hour的变量中。第3~7行确定这个小时数是在下午还是上午,如果hour小于12(午夜以后的hour为0),那么,是在上午(a.m.),否则是在下午(p.m.)。

第8行引入了一种叫做模除的数学运算,它用一个百分号表示(%)。它返回除法运算的余数。例如,5除以2,得到结果为2,还有1个余数。换句话说,5%2得1。因此,在这个例子中,如果hour是18,18%12得到6(18除以12,商为1,余数为6)。18就是6 p.m.,这是我们想要的时间。如果第一个数字小于除数(例如,8除以12),那么,结果是最初的数字。例如,8%12返回8。换句话说,模除操作不会改变中午之前的小时数。

第9~11行考虑到模除操作输出的两种可能。如果hour是12(正午)或0(午夜),那么模除操作返回0。在这种情况下,hour只要设置为12,表示12 p.m.或12 a.m.。最后,第12行将重新格式化的hour和一个空格以及“am”或“pm”组合起来,这样,结果就显示为“6 am”或“6 pm”。

填充一位数

正如前面所讨论的,当分钟数或秒钟值小于10的时候,我们最终可能得到较为奇怪的输出,例如,7:3:2 p.m。要将这种输出修改为更为常见的7:03:02 p.m.,我们需要在单个数位的前面添加一个0。使用基本的条件语句,这很容易做到:


1 var minutes=now.getMinutes();

2 if(minutes<10){

3 minutes=’0’+minutes;

4}


第1行获取当前时间的minutes,在这个例子中可能是33或3。第2行直接检查这个数值是否小于10,如果是,意味着分钟数是一个一位数,在其前面需要一个0。第3行有点技巧,因为你通常不会在一个数字前面加一个0,0+2等于2,而不是等于02。然而,我们可以以这种方式组合字符串,因此,’0’+minutes意味着将字符串’0’和变量minutes中的值组合起来。正如14.3.1节所介绍的,当我们将一个字符串和一个数字相加的时候,JavaScript解释器会将数字转换为一个字符串,因此,我们最终得到了诸如’08’的一个字符串。

我们可以将这些部分组合到一起,以创建一个简单的函数,来按照类似7:32:04 p.m.或4:02:34 a.m.,甚至是7:23 p.m.这样省略掉秒钟的时间格式,来输出时间:


function printTime(secs){

var sep=’:’;//seperator character

var hours, minutes, seconds, time;

var now=new Date();

hours=now.getHours();

if(hours<12){

meridiem='am';

}else{

meridiem='pm';

}

hours=hours%12;

if(hours==0){

hours=12;

}

time=hours;

minutes=now.getMinutes();

if(minutes<10){

minutes=’0’+minutes;

}

time+=sep+minutes;

if(secs){

seconds=now.getSeconds();

if(seconds<10){

seconds=’0’+seconds;

}

time+=sep+seconds;

}

return time+’’+meridiem;

}


你将会发现,这个函数位于教程chapter14文件夹中的printTime.js文件中。你可以通过在浏览器中打开文件time.html(同一文件夹下),来看看这个函数的应用。要使用这个函数,要么将printTime.js文件添加到一个Web页面,或者将函数复制到一个Web页面或另一个外部JavaScript文件。要获取时间,只要像这样调用该函数:printTime(),或者,如果你想要秒钟也显示出来,这样调用printTime(true)。该函数将以相应的格式返回包含了当前时间的一个字符串。