27.md 8.4 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4
## 18.日期和时间

Ruby 提供了从计算机时钟中提取时间和日期的方法。 当今所有的个人计算机都有一个称为 RTC(实时时钟)的东西,它由电池供电,即使机器关闭也可以保持时间。 许多编程语言都允许我们访问此时钟并使用日期和时间进行操作。 让我们看看如何使用 Ruby。 让我们在 irb 中执行此操作,而不是将程序写入文件中。

W
wizardforcel 已提交
5
我们要做的第一件事是发现现在几点钟了? 为此,只需在 irb 中键入`Time.now`就可以了。 你将获得当前时间。
W
init  
wizardforcel 已提交
6

W
wizardforcel 已提交
7
```rb
W
init  
wizardforcel 已提交
8 9 10 11
>> Time.now
=> Thu Feb 25 16:54:45 +0530 2010
```

W
wizardforcel 已提交
12
Time.now 是`Time.new`的同义词,它创建一个新的`Time`对象。 你可以使用`Time.now``Time.new`,两者将产生相同的结果。
W
init  
wizardforcel 已提交
13

W
wizardforcel 已提交
14
```rb
W
init  
wizardforcel 已提交
15 16 17 18 19 20
>> Time.new
=> Thu Feb 25 16:54:48 +0530 2010
```

在以下命令中,我们创建一个新的时间对象/实例,并将其分配给变量`t`

W
wizardforcel 已提交
21
```rb
W
init  
wizardforcel 已提交
22 23 24 25 26 27
>> t = Time.new
=> Thu Feb 25 16:55:02 +0530 2010
```

现在已经分配了,如何查看`t`的值? 我们将使用检查方法。 因此,通过键入`t.inspect`,我们可以检查 t 中的内容。

W
wizardforcel 已提交
28
```rb
W
init  
wizardforcel 已提交
29 30 31 32 33 34
>> t.inspect
=> "Thu Feb 25 16:55:02 +0530 2010"
```

`t.inspect`将时间对象转换为字符串并显示给我们。 可以通过`to_s`(到字符串)功能完成相同的操作,如下所示

W
wizardforcel 已提交
35
```rb
W
init  
wizardforcel 已提交
36 37 38 39 40 41
>> t.to_s
=> "Thu Feb 25 16:55:02 +0530 2010"
```

`t.year`检索时间对象

W
wizardforcel 已提交
42
```rb
W
init  
wizardforcel 已提交
43 44 45 46 47 48
>> t.year
=> 2010
```

`t.month`检索月份对象

W
wizardforcel 已提交
49
```rb
W
init  
wizardforcel 已提交
50 51 52 53 54 55
>> t.month
=> 2
```

`t.day`检索时间对象中的当天(该月)

W
wizardforcel 已提交
56
```rb
W
init  
wizardforcel 已提交
57 58 59 60 61 62
>> t.day
=> 25
```

`t.wday`检索当天的数字。 0 表示星期日,1→星期一,2→星期二,依此类推,直到 6 表示星期六

W
wizardforcel 已提交
63
```rb
W
init  
wizardforcel 已提交
64 65 66 67 68 69 70 71
>> t.wday
=> 4
```

在上面的代码段中,星期四是星期四。

`t.yday`检索该年中的日期。 例如,2 月 1 日是一年中的第 32 天。

W
wizardforcel 已提交
72
```rb
W
init  
wizardforcel 已提交
73 74 75 76 77 78
>> t.yday
=> 56
```

`t.hour`检索时间对象中的小时。 小时为 24 小时格式。

W
wizardforcel 已提交
79
```rb
W
init  
wizardforcel 已提交
80 81 82 83 84 85
>> t.hour
=> 16
```

`t.min`检索时间对象中的分钟值。

W
wizardforcel 已提交
86
```rb
W
init  
wizardforcel 已提交
87 88 89 90 91 92
>> t.min
=> 55
```

`t.sec`检索时间秒对象。

W
wizardforcel 已提交
93
```rb
W
init  
wizardforcel 已提交
94 95 96 97
>> t.sec
=> 2
```

W
wizardforcel 已提交
98
`t.usec`检索时间对象中的微秒。 如果你受命编写奥运会秒表应用程序,这将很有用。
W
init  
wizardforcel 已提交
99

W
wizardforcel 已提交
100
```rb
W
init  
wizardforcel 已提交
101 102 103 104 105 106
>> t.usec
=> 357606
```

`t.zone`检索区域。 我在印度,在这里遵循印度标准时间,简称为 IST。

W
wizardforcel 已提交
107
```rb
W
init  
wizardforcel 已提交
108 109 110 111
>> t.zone
=> "IST"
```

W
wizardforcel 已提交
112
有一个东西叫做 UTC 或世界时间坐标 <sup class="footnote">[ [44](#_footnotedef_44 "View footnote.") ]</sup> 。 经度为 0 度的时间。 `t.utc_offset`显示你的时间与 UTC 的时间相差的秒数。
W
init  
wizardforcel 已提交
113

W
wizardforcel 已提交
114
```rb
W
init  
wizardforcel 已提交
115 116 117 118 119 120
>> t.utc_offset
=> 19800
```

从上面的示例中,我知道住在格林威治的人将在我见过 19800 秒后看到日出。

W
wizardforcel 已提交
121
DST 表示夏令时 <sup class="footnote">[ [45](#_footnotedef_45 "View footnote.") ]</sup> 。 我不知道那是什么 如果你的时区具有夏令时,则此函数返回`true`,否则返回`false`
W
init  
wizardforcel 已提交
122

W
wizardforcel 已提交
123
```rb
W
init  
wizardforcel 已提交
124 125 126 127
>> t.isdst
=> false
```

W
wizardforcel 已提交
128
如果你的时区为`UTC`,则`t.utc`返回 true 或 false
W
init  
wizardforcel 已提交
129

W
wizardforcel 已提交
130
```rb
W
init  
wizardforcel 已提交
131 132 133 134 135 136
>> t.utc?
=> false
```

如果要获取本地时间,只需如图所示调用`localtime`函数。 在这种情况下,我们希望`t`保留本地时间值

W
wizardforcel 已提交
137
```rb
W
init  
wizardforcel 已提交
138 139 140 141 142 143
>> t.localtime
=> Thu Feb 25 16:55:02 +0530 2010
```

与本地时间相同,`gmtime`功能获取格林威治子午线时间。

W
wizardforcel 已提交
144
```rb
W
init  
wizardforcel 已提交
145 146 147 148 149 150
>> t.gmtime
=> Thu Feb 25 11:25:02 UTC 2010
```

`getlocal`功能是`local_time`的别名

W
wizardforcel 已提交
151
```rb
W
init  
wizardforcel 已提交
152 153 154 155 156 157
>> t.getlocal
=> Thu Feb 25 16:55:02 +0530 2010
```

`getutc`功能是`gmtime`的别名。 实际上,`gmtime``getutc`的别名

W
wizardforcel 已提交
158
```rb
W
init  
wizardforcel 已提交
159 160 161 162 163 164
>> t.getutc
=> Thu Feb 25 11:25:02 UTC 2010
```

`ctime`函数将时间格式化为易于阅读的格式。

W
wizardforcel 已提交
165
```rb
W
init  
wizardforcel 已提交
166 167 168 169 170 171
>> t.ctime
=> "Thu Feb 25 11:25:02 2010"
```

假设我们要从时间值 t 中减去几秒钟,我们可以如图所示。 下方,我们从时间值中减去 86400 秒(1 天)

W
wizardforcel 已提交
172
```rb
W
init  
wizardforcel 已提交
173 174 175 176 177 178 179 180
>> t - 86400
=> Wed Feb 24 11:25:02 UTC 2010
```

### 18.1。 两天之间的天数

现在,让我们编写一个代码片段,以查找 2010 年 2 月 25 日至 2010 年 5 月 1 日之间的天数,首先,我们声明一个变量`a`并将其分配给 2010 年 2 月 25 日,如图所示

W
wizardforcel 已提交
181
```rb
W
init  
wizardforcel 已提交
182 183 184 185 186 187
>> a = Time.local 2010, 2, 25
=> Thu Feb 25 00:00:00 +0530 2010
```

注意,我们在`Time`类中使用了一个名为`local`的函数,我们可以为其指定一个日期。 从输出中可以看到,我们知道变量`a`的值现在为 2 月 25 日。 我们以类似的方式创建了一个变量`b`,并将其分配给日期为 2010 年 5 月 1 日的日期

W
wizardforcel 已提交
188
```rb
W
init  
wizardforcel 已提交
189 190 191 192 193 194
>> b = Time.local 2010, 5, 1
=> Sat May 01 00:00:00 +0530 2010
```

我们现在要做的就是从 b 中减去 a

W
wizardforcel 已提交
195
```rb
W
init  
wizardforcel 已提交
196 197 198 199 200 201
>> b -a
=> 5616000.0
```

这给出了 a 和 b 之间的秒数。 我们将结果除以 86400(即一天中的秒数)

W
wizardforcel 已提交
202
```rb
W
init  
wizardforcel 已提交
203 204 205 206 207 208 209 210
>> days = _ / 86400
=> 65.0
```

我们得到的结果是 65。

### 18.2。 你住了几天?

W
wizardforcel 已提交
211
现在,让我们看一个程序,该程序以你的生日为准,并打印出你住了多少天。 在文本编辑器中输入程序并执行
W
init  
wizardforcel 已提交
212

W
wizardforcel 已提交
213
```rb
W
init  
wizardforcel 已提交
214 215 216 217 218 219 220 221 222 223 224 225 226 227
#!/usr/bin/ruby
# how_many_days.rb

print "Enter birthday (YYYY-MM-DD):"
bday = gets.chop
year, month, day = bday.split('-')
# puts " #{year}, #{month}, #{day}"
seconds =  Time.now - Time.local(year, month, day)
days = (seconds / 86400).round
puts "You have lived for #{days} days"
```

这是结果

W
wizardforcel 已提交
228
```rb
W
init  
wizardforcel 已提交
229 230 231 232
Enter birthday (YYYY-MM-DD):2000-5-23
You have lived for 3566 days
```

W
wizardforcel 已提交
233
好吧,这在你执行该程序时可能会有所不同。 现在让我们对其进行分析。 在第一行
W
init  
wizardforcel 已提交
234

W
wizardforcel 已提交
235
```rb
W
init  
wizardforcel 已提交
236 237 238 239 240
print "Enter birthday (YYYY-MM-DD):"
```

我们要求用户输入他或她的生日,完成后,我们将在此处进行提示。 我们要求用户在语句中以 YYYY-MM-DD 格式输入

W
wizardforcel 已提交
241
```rb
W
init  
wizardforcel 已提交
242 243 244
bday = gets.chop
```

W
wizardforcel 已提交
245
我们获取日期并将其存储在名为`bday`的变量中。 `gets.chop`获得生日,并砍掉我们随其输入的输入符号。 因此`bday`现在保存你输入的生日的字符串值。 在下一条语句中
W
init  
wizardforcel 已提交
246

W
wizardforcel 已提交
247
```rb
W
init  
wizardforcel 已提交
248 249 250 251 252
year, month, day = bday.split('-')
```

我们有一个多重分配,其中我有三个变量`year``month``day`。 我正在分割生日字符串并分配它。 真正发生的是,如果我们输入一个类似于 1994-6-24 的日期,它会被`–`分割并变成一个数组,如下面的代码片段所示,该数组在 irb 中执行

W
wizardforcel 已提交
253
```rb
W
init  
wizardforcel 已提交
254 255 256 257 258 259
>> "1994-6-24".split '-'
=> ["1994", "6", "24"]
```

让我们同时将此数组分配给变量`a``b``c`,如下所示

W
wizardforcel 已提交
260
```rb
W
init  
wizardforcel 已提交
261 262 263 264
>> a, b, c = _
=> ["1994", "6", "24"]
```

W
wizardforcel 已提交
265
如果你还记得`_`(下划线)表示 irb 中最后获得的结果。 因此,分配好之后,我们现在检查`a``b``c`的值,如图所示。
W
init  
wizardforcel 已提交
266

W
wizardforcel 已提交
267
```rb
W
init  
wizardforcel 已提交
268 269 270 271 272 273 274 275 276 277
>> a
=> "1994"
>> b
=> "6"
>> c
=> "24"
```

以类似的方式

W
wizardforcel 已提交
278
```rb
W
init  
wizardforcel 已提交
279 280 281 282 283
year, month, day = bday.split('-')
```

`year`变量获取年份部分,`month`获取月份,`day`获取日期。 确定已经获得了特定日期的参数,我们可以继续进行。 检查以下语句

W
wizardforcel 已提交
284
```rb
W
init  
wizardforcel 已提交
285 286 287 288 289 290 291
seconds =  Time.now - Time.local(year, month, day)
```

看到等号的右侧,首先我们有`Time.now`可以获取当前时间,从中减去使用`Time.local`创建的时间对象。 `Time.local`可用于创建固定在任何实例上的时间对象,该实例可以是过去,现在或将来。 我们将`year``month``day`传递给它以创建`Time`对象。 当我们将两者都减去时会发生什么,我们得到了以秒为单位的差异,该差异存储在等式左侧的`seconds`变量中。

我们现在要做的就是将第二个转换为几天,这是下面的语句完成的

W
wizardforcel 已提交
292
```rb
W
init  
wizardforcel 已提交
293 294 295 296 297
days = (seconds / 86400).round
```

在这里,我们将秒除以 86400,将秒转换为天。 我们可能会得到 378.567 天之类的值,要摆脱.567,我们使用舍入函数将其舍入,因此`(seconds / 86400).round`返回一个整齐的舍入值,人类安静下来可以轻松读取。 我们将值存储在名为`days`的变量中。 最后,我们使用以下语句打印出我们已经生活了很多天的事实

W
wizardforcel 已提交
298
```rb
W
init  
wizardforcel 已提交
299 300 301 302 303 304 305
puts "You have lived for #{days} days"
```

好吧,就是这样。

我想告诉我我使用`Time.local`函数发现的一件事,不是我们必须仅将数字传递给它,如图所示

W
wizardforcel 已提交
306
```rb
W
init  
wizardforcel 已提交
307 308 309 310 311 312
>> Time.local "2010", "5", "1"
=> Sat May 01 00:00:00 +0530 2010
```

我们可以传递一些人类友好的价值观,如下所示。 而不是每月放置 5,我们使用 May。

W
wizardforcel 已提交
313
```rb
W
init  
wizardforcel 已提交
314 315 316 317 318
>>Time.local "2010", "may", "1"
=> Sat May 01 00:00:00 +0530 2010
```

有时 Ruby 语言看起来像说英语一样容易。