返回列表 发帖

[Zend权威认证试题讲解]第七章 - 管理日期与时间

从某一点上来看,几乎所有的网站都需要处理日期与时间。假如你需要收集用户的生日,或者记录某个特定事件的发生时间,PHP的日期函数将很好的帮助你完成任务。6 R: Y5 h9 n. F# }0 x9 N
但是PHP的日期/时间管理功能并不完美。它基于UNIX时间戳运行,容易受到攻击,作为开发者,你必须谨慎处理可能遇到的恶意数据。
5 y/ }% r! F+ w同时,在Web上进行日期管理是一件国际性的事务。你必须能依据时区、地区的不同来显示对应的日期信息。
# ?, ^5 Z  D# L0 h3 I本章测试题将考察以上所述的全部内容。
& q) i! i' N, V7 B' y& H8 p9 D! _% i  p
. r' {" l8 e3 U! V1 O5 ]
问题
5 v: B$ B: b1 q# I7 n% S6 U' V( w  y4 n) l# P# L, P5 s
1.以下脚本在Windows系统上输出什么?

  1. <?php
  2. echo strtotime ("November 11, 1952");
  3. ?>
复制代码
A.-14462: f9 R# f1 Q2 J8 d$ R2 ^
B.14462
2 w8 B; G' }1 h5 W+ w$ [1 `8 nC.-1
1 ~% i+ i2 Q$ @% {D.0' w- y+ k& _6 P
E.一个错误6 F) I* `3 H; P( h; P2 s
7 L$ Z2 X" j! p/ S3 M, t! K

  k$ h5 @, y$ U# @  U2.哪个函数能根据区域设置来格式化输出一个时间戳?
* R8 @: j2 N" k. k( E
6 M3 b7 U5 G0 e答案:__________
3 T4 z! `' l, F( U* p2 V. G5 I- z- z3 I+ s8 l% W* Q

/ z7 b  ]' y( S/ h8 @4 {" c1 L3.以下脚本是做什么的?

  1. <?php
  2. $a = array_sum (explode (' ', microtime()));
  3. for ($i = 0; $i < 10000; $i++);
  4. $b = array_sum (explode (' ', microtime()));
  5. echo $b - $a;
  6. ?>
复制代码
A.测算for循环的执行时间; J) B- [9 z3 m' M: I
B.测定服务器的时钟频率9 s! y+ W# r4 Y8 n2 J2 c
C.计算操作系统的硬件时钟频率与软件时钟频率的差# s: X4 W9 s, _, H& q
D.测算for循环、一个array_sum()函数与一个microtime()的总执行时间3 t" f2 ?4 ~, l1 ~4 I( _' Z: P9 V  A0 E
E.测算for循环、两个array_sum()函数与两个microtime()的总执行时间
5 E/ R( L5 j6 ?2 u; B3 z$ v" P( U+ h- ]) I, b# _& \) l
# A5 B8 p2 ~- A
4.以下脚本的标记处应该填入什么函数?

  1. <?php
  2. for ($i = 0; $i < 100; $i++) {
  3.          $day = rand (1, 31);
  4.     $month = rand (1, 12);
  5.     $year = rand (1000, 2500);
  6.     if (????????? ($month, $day, $year)) {
  7.         echo "$month/$day/$year is a valid date\n";
  8.     } else {
  9.         echo "$month/$day/$year is not a valid date\n";
  10.     }
  11. }
  12. ?>
复制代码
A.date()
" O  G+ U! C& o% B  i( |1 [6 f8 hB.strftime()' x! u$ b& s* c
C.microtime()
# }2 O% N( D5 ^- {- cD.checkdate()
( a! [; [# M8 o/ S$ V6 |% \# k1 eE.mktime()+ p: _' v% d' I
: a) L. b$ {: W' i! P4 s

5 o0 [5 E& O" Y) U5.以下脚本在Windows系统中输出什么?

  1. <?php
  2. echo mktime (0, 0, 0, 11, 11, 1952); // November 11, 1952
  3. ?>
复制代码
A.一个警告
7 n8 F4 Z# Z7 R( n  c; \B.一个错误
/ q8 r: t8 |$ z- E: P, M* NC.-1和一个警告/ l: U, X6 m6 G
D.-14462
6 z' Z, R# G3 @3 N. UE.一个提示,指出mktime不支持种输入# f, A  q7 t0 |5 i
$ [. p  W; G8 e5 g

+ ]3 B& A& V1 [/ F" q6.EST是CST之前的一个时区(就是说任何时候EST都比CST晚一个小时)。那么以下脚本输出什么?

  1. <?php
  2. $a = strtotime ('00:00:00 Feb 23 1976 EST');
  3. $b = strtotime ('00:00:00 Feb 23 1976 CST');
  4. echo $a - $b;
  5. ?>
复制代码
A.-3600
1 J; g3 J) r( K' F# Y1 F3 a# o- sB.36000 R- |( W/ H! N$ P% Q
C.0
+ T1 k- R6 w( a6 c; S2 k  _" ]D.-1& I! Y9 W/ H3 x
E.1. N) x) q6 s9 H5 e, W. W
3 A% f4 o4 Y' q. ~

9 D/ H3 B. @  P5 ~* P7.处理数据库中读取的日期数据时,以下那种方法有助于避免bug?(三选)
6 ]' ~% W2 G; b4 X: g' P" u
, g; Z/ w7 X( ]A.确保日期数据与服务器使用相同的时区# \3 V/ d2 r9 p5 n
B.如果日期需要被转换成UNIX时间戳进行操作,要确保结果不会溢出
4 G) q! C& y; M& L. xC.用数据库功能测试日期的合法性- [9 e( z- ]9 O4 G
D.如果可能,用数据库功能计算日期的值+ n0 e! l* z0 |) T# L' V/ y
E.用代码控制日期只能在PHP中进行处理
4 O) c6 v5 ^2 m: e
; Z: E8 v2 I# n% u' b! s6 Z5 ^( x
8.在时区设置为Moscow, Russia的Windows操作系统上运行以下脚本,将输出什么?

  1. <?php
  2. echo gmmktime(0, 0, 0, 1, 1, 1970);
  3. ?>
复制代码
A.输出数字0! U) O/ }4 e8 c1 V% @1 G( U
B.输出数字-1
/ _. y1 E) ~. B$ C! NC.输出数字17 u4 \7 G$ W! D: ]( {1 o' A4 o( f
D.报错
5 G/ d3 d# z* ?- NE.什么都不输出, X) Y/ L) R; B3 h4 |5 I% s

% ?/ g0 L; o7 f- {
6 H8 R; \" Y* V* p9.以下哪个选项对time函数的描述最准确?5 U7 z4 a3 ~4 l/ I' ^- w% F
/ z7 H2 S, t) _5 s, R9 I
A.返回从UNIX纪元开始到现在经过的秒数
. e# E8 e/ a/ Z6 x- mB.以GMT时区为基准,返回从UNIX纪元开始到现在经过的秒数
8 V# {4 c; D, q6 U9 A& cC.以本地时区为基准,返回从UNIX纪元开始到现在经过的秒数3 H: D: T& d% B
D.计算从UNIX纪元开始经过的时间,并以整型数字表示
$ v, @, U7 A0 U, F8 IE.以上都对* m; l/ H- _( _. ^( e+ E4 Y
: N4 n9 v' t) j: C5 A" w
, b/ I$ O( o2 \" _, ~  n: S0 ~
10.以下脚本输出什么?

  1. <?php
  2. $time = strtotime ('2004/01/01');
  3. echo date ('H:\i:s', $time);
  4. ?>
复制代码
A.00:00:00! L5 O+ O) x9 I
B.12:00:00
6 J* [0 s) @9 {8 S  W! S9 aC.00:i:00
# j! f! p; b# D! S8 d. \2 d/ p; xD.12:i:000 w/ @: [# g# n  G5 A  g2 ]$ u$ K3 q
E.-1, n8 c5 @% g- O8 z) g0 j+ X9 n! m
0 W9 s3 @: O8 [; v' f( P* m! a. i

# p" a2 w- _3 x/ r- Z; u3 `11.以下哪个表达式能让cookie在一小时后过期(假设客户端的时间和时区设置都正确,并且客户端与服务器不在同一个时区)?
5 M$ \  [7 o2 u9 e2 r  `, ]! e) {, i! `+ X/ n3 g+ z  ?  _1 v
A.time() + 3600" @- D1 X2 n* M3 E3 z
B.time(3600)
) V. l; R+ M: p% k, d% lC.gmtime() + 3600
9 x  d  a6 Z1 F3 U2 WD.gmtime(3600)7 R  U5 |) g( I# v8 S3 X2 a; X$ \
E.A和C都对
3 s8 b" Z4 |! r- h: Q" _
' U2 x% ~6 d  X# a" F8 y+ J& O' |! Z
12.getdate()函数返回______。
6 c8 ?, n2 D- @
% B9 x9 v  L  n4 P0 mA.一个整数5 [3 k2 @1 K3 p3 x
B.一个浮点数
6 n+ M% p# G2 X- c% ?9 k1 kC.一个数组
; l) b: V$ H$ J7 lD.一个字符串3 r8 X9 O( p; {# y
E.一个布尔值- G$ ^5 W& C) F+ ~+ |( G
5 o  r# \# q' y8 D$ ?, F3 q

! N2 x- t% }! q4 g13.要把microtime()的输出转化成一个数字值,以下那种方法最简便?
! C8 J, k4 P" g% Z" z/ `! E( V  B# D: s
A.$time = implode (' ', microtime());
6 W. ]1 r" o2 E. [% LB.$time = explode (' ', microtime()); $time = $time[0] + $time[1];* v# q) C: v0 X8 p! T% g
C.$time = microtime() + microtime();! X" |4 ]1 W# o, C/ v- e
D.$time = array_sum (explode (' ', microtime()));
) w+ N: {' k. c: AE.以上都不对
% n2 _! R, D" q5 c4 q  m' M
5 l! h+ N1 Z1 w' T6 T  F3 Q) N1 q+ @, S9 l
14.以下哪个函数返回的不是时间戳?(双选)
' d. U8 O0 L0 b3 y; ^9 `, h+ N7 P
A.time()
/ ^( y; v3 f* EB.date()
0 H4 g9 P% h. l% @( YC.strtotime()+ i3 P) N$ v; j9 l/ g+ w
D.localtime()1 F& t+ R: x0 O5 V8 U% A9 q4 V0 ~
E.gmmktime()
" o6 H' {7 m+ `! U+ t+ i) L1 d& V3 B) b, j" H# r2 e+ v
7 K4 v$ |2 f0 F. n3 n! U$ [8 T
15.GMT时区下的时间戳与你所在时区下的时间戳的秒数差距有多大?! |; H. X. E0 ]! I

! p( S* a8 K6 {) pA.取决于你所在时区与GMT时区的时间差
# S$ A- e1 x9 v: N! E) i6 _% JB.没有差别" K, l2 o+ Z1 H# E" h. t) G
C.只当你也在GMT时区时才会相同2 _1 L" z/ M  `& I1 v
D.永远不会相同
, {$ C5 ?- u) ?E.以上都不对 9 U$ T, O* g4 m1 {

5 S- Z. b; Q7 U) S6 m0 d
, B9 `1 I8 F" l( A( w1 Q5 w3 j2 O6 y5 e8 c* D. S
答案速查
( U7 Z5 i! {3 b2 U  w) O4 z! k1:C1 G% v* M! v/ I8 M
2:strftime()
" x( `( D2 |6 }# B3 u* Q7 e9 z3:D
5 M3 h& ^5 m& O4 Y' t( G& [$ _7 G4 ]4:D
1 C. H( Y0 Z$ p0 r7 W: M5:C6 K6 G: b1 r; L
6:A0 l2 y  L2 j" j. z; q0 z
7:BCD" ^0 Y$ D0 h" }* C8 `: X
8:B7 f* Z" f4 N1 h* u8 P
9:E2 }; \. B5 k1 y) S- \
10:C
8 H+ g. {- l9 \11:A
8 ^8 B3 Y6 H7 e2 I0 e12:C
& w7 J3 `* u5 [: G' O9 S13:D  u5 ?5 D) Z' L5 |# Z* W
14:BD5 h* c8 U3 Y* a& B- u
15:B
+ a3 p% p1 d0 D0 K3 t( S
7 k$ @; ?& J" o; q+ G1 z8 N0 d8 d* u7 E
- d% K9 z/ \9 @9 z
答案
$ ]& P7 ]  w( q. e, q
5 {# }: u8 R2 [% b& D- H' j% p  z1.本题实际上很容易回答。特别指出操作系统平台其实是为了迷惑你,事实上,无论是在Windows、Linux或其他类UNIX等使用旧版glibc的平台上,strtotime函数都不能识别UNIX纪元之前的日期(译者注:PHP5里修正了这个问题),因此脚本输出-1,答案是C。
8 P1 B, r+ I& \- C+ x% s5 D) `' g. I3 k" O2 F7 O0 ?
2.正确答案是strftime()。date函数只能格式化输出英文表示的日期,而strftime()则能根据脚本中的地区设置(可以通过stlocale()来改变)来决定在输出中使用的语言。
. B: ]5 b. b% \* M( Z  B. P7 v; d" Y
3.答案是D。脚本中两次调用microtime()都能够获得当前时间,然而只有第二次执行该函数的时间会被算进时间段中。同样,第一次调用array_sum()函数被算进时间段,而第二次不会,因为第二次array_sum()是在microtime()后执行的。) Y6 E( G; r9 y2 N
1 R- E! M. Z  F% \; u
4.checkdate函数能检查格里高利日期(Gregorian date)的合法性(这个函数有一些局限性,比如October 5-14, 1582,尽管日历上并没有这个日期,但函数仍然认为它合法)。这个脚本实质上是创建了一个随机日期并验证它的合法性,答案是D。9 M" b1 L% f  _, r
( i$ ^3 E& U0 i5 A2 r; V( D
5.和第一题不同,本题中脚本执行的平台会影响结果。在Windows下,mktime函数不支持负值(UNIX纪元之前的时间),函数将返回-1(和一个警告)。正确答案是C。
& G) g; Q4 a) o6 ?, ]8 ?# Z5 O
6.由于两个时区有一小时的时差,而strtotime()能把文本表示的日期转换成时间戳,因此结果只能是3600或者-3600(答案A或者B,即一小时相当于的秒数)。现在,最重要的是紧记,CST比EST晚一个小时,也就是当CST是午夜12点时,EST已经是次日了。因此$b比$a大,结果是负数,答案是A。7 ]/ a6 g/ E, I$ D' l* r

$ r5 X" @/ {1 v- E7.数据库存储日期/时间的能力比PHP强。大多数DBMS能够处理格里高利日历上所有的日期,而基于UNIX时间戳的PHP只能处理较短的一个时间段里的日期。因此在脚本中处理日期时,必须确保在它转换成时间戳后不会溢出(答案B)。此外,在处理日期时,无论是验证一个日期的合法性(答案C)还是进行计算(答案D),都最好尽量让数据库来完成。
$ `# n% `) I; g6 D. R6 x" Y! ^9 B7 N2 o
8.这是个很迷惑人的问题,但其实很简单。传给gmmktime()的值其实就是UNIX纪元,转化成时间戳后是0。gmmktime()的内部用到mktime(),后者基于当前地区工作。这里的问题是,UNIX纪元不能被用在本初子午线以东的时区——比如莫斯科。这将产生一个负值,Windows操作系统不支持。因此脚本输出-1,答案是B。也可能会输出一个警告,取决于你的设置(但绝对不是答案D说的“一个错误”)。  ^' V; {  r, A

: ]; ]' r% }( K7 d  M0 L7 W  \9.答案是E。很显然,time()计算从UNIX纪元开始至今经过的秒数,答案A和D都表述了这一点,它们都是正确的。答案B和C说的不是那么直接,但其实也表达了相同的意思。UNIX纪元是一个确定的时间点,因此无论你使用GMT时区或其他你所在的时区,从UNIX纪元至今经过的秒数都是一样的。只有在你把时间戳转换成人们能够理解的表达形式时才需要考虑时区。所以答案B和C也是正确的。这题似乎有点戏弄人的意思,但实际上它考验你对绝对时间与相对时间二者不同之处的认识,这个概念在处理日期时相当重要。0 v* K1 H/ O* u! U) S1 f# g
& k7 s8 F- ]2 P6 l
10.传递给date()的参数H和s代表24小时制的时间与秒数。i被一个反斜线转义,因此它将被当作字母直接输出。调用strtotime()时没有给出参数,它将返回当天午夜的时间。因此最终的输出是00:i:00,答案是C。
1 w6 `4 O8 I% R" ?% p' f8 y5 U+ H8 N7 t9 v) K( ]" f# f
11.正确答案是A,当前时间加3600秒(1小时*60分钟*60秒)。其他选项都会产生错误的时间戳。
+ J1 f3 K- r! ?0 W  C' ^
* P% D. K! F: v# V3 |6 f12.getdate函数返回记录指定时间戳相关信息的数组(如果没有指定时间戳,就改用当前日期)。答案是C。
: |/ z6 l/ {# G' o9 ~' q
9 F5 u' y/ }1 q  f# {; d13.答案是D。microtime函数返回一个由时间戳和小数两部分组成的字符串,两部分由空格分开。因此explode()将字符串分割并放入数组,array_sum()把它们相加,转换成数字。" Y0 l( F1 R, S7 r& R

  f9 z8 b$ g- J0 p) L14.答案是B和D。date函数返回字符串,localtime()返回数组。
' w2 Q# C! [1 E' k' j; x9 C& E$ P  ^
15.任何时区下的当前时间都是相同的——当前时间是一个绝对的时间点。答案是B。

返回列表
【捌玖网络】已经运行: