时间永远是人生的一大问题,但在`Ruby的世界中,却不是什麽问题。只要我们熟悉一些时间上的技巧,基本上都难不倒我们。
Time.now
与 Time.current
的区别是Ruby
中非常重要的概念:
Time.now
使用当前机器作业系统的时区Time.current
使用 Rails 中设定的时区 (ActiveSupport
的方法)接着,我们再来看下列例子来观察不同电脑,因时区设定的不同,而导致的不同结果。
⭐️ 自己的电脑时区(Mac)
Time.now
#=> 电脑的时区
#=> 2019-11-05 10:44:09 +0800
Time.current
#=> Rails的时区
#=> Tue, 05 Nov 2019 18:44:16 CST +08:00
Time.parse("2019-11-04 16:20:23")
#=> 2019-11-04 16:20:23 +0800
Time.zone.parse("2019-11-04 16:20:23")
#=> Mon, 04 Nov 2019 16:20:23 CST +08:00
Time.zone.parse("2019-11-04 16:20:23").to_i
#=> 1572855623
Time.parse("2019-11-04 16:20:23").to_i
#=> 1572855623
⭐️ 测试站的时区
Time.now
#=> 电脑的时区
#=> 2019-11-05 10:44:09 +0000
Time.current
#=> Rails的时区
#=> Tue, 05 Nov 2019 18:44:16 CST +08:00
Time.parse("2019-11-04 16:20:23")
#=> 2019-11-04 16:20:23 +0000
Time.zone.parse("2019-11-04 16:20:23")
#=> Mon, 04 Nov 2019 16:20:23 CST +08:00
Time.parse("2019-11-04 16:20:23").to_i
#=> 1572884423
Time.zone.parse("2019-11-04 16:20:23").to_i
#=> 1572855623
不过云端服务中,我们可以将电脑的时区设定自己想要的时区。譬如,我们就可以将测试站的时区设定+8:00
Datetime 是一种可以表现时间的类别,为Ruby
的方法
> DateTime.tomorrow
#=> Sat, 28 Aug 2021
> DateTime.now.tomorrow
#=> Sat, 28 Aug 2021 10:51:58 +0800
在Ruby
& Rails
中,有很多物件都可以拿来处理时间。我们必须知道哪些方法是哪种Object
,会比较方便使用。
由於ActiveSupport::TimeWithZone
是Rails
的库,无法在irb
里面执行,可以应证Time.current
使用的是Rails
中设定的时区,才会需要使用Rails
提供的物件。
DateTime.now.class
#=> DateTime
DateTime.new.class
#=> DateTime
DateTime.strptime("1571393643",'%s').class
#=> DateTime
Time.now.class
#=> Time
Time.new.class
#=> Time
Time.at(1571393643).class
#=> Time
Time.current.class
#=> ActiveSupport::TimeWithZone
1.day.from_now.class
#=> ActiveSupport::TimeWithZone
2.days.ago.class
#=> ActiveSupport::TimeWithZone
Time.zone.class
#=> ActiveSupport::TimeZone
互动式irb
内看不懂 Time.current
Time.current
# Traceback (most recent call last):
# NoMethodError (undefined method `current' for Time:Class)
Time.now
#=> 2021-09-07 09:29:53.888093 +0800
下列介绍时间戳转换成时间物件的方法
# 时间戳转 Datetime
DateTime.strptime("1571393643",'%s')
#=> Fri, 18 Oct 2019 10:14:03 +0000
# 时间戳转 Time
Time.at(1571393643)
#=> 2019-10-18 18:14:03 +0800
# 时间戳转 Time
Time.zone.at(1571393643)
#=> Fri, 18 Oct 2019 18:14:03 CST +08:00
# 时间戳转 Time
Time.zone.at(1571393643).strftime("%Y-%m-%d %H:%M:%S")
#=> => "2019-10-18 18:14:03"
# 时间字串转为时间戳
#=== *1000 为13码
Time.zone.parse('2019.12.25 17:00:00').to_i*1000
Ruby
也有提供特别的方法转换时间
Time.now.localtime("+05:30")
#=> 2019-11-06 07:17:41 +0530
Time.now.localtime("+05:30")
#=> 2019-11-06 07:17:46 +0530
Time.now.localtime("+00:30")
#=> 2019-11-06 02:17:54 +0030
Time.now.localtime("+00:00")
#=> 2019-11-06 01:47:58 +0000
Time.now.localtime("+08:00")
#=> 2019-11-06 09:48:08 +0800
下列方法指的是明天的同一个时间
Date.tomorrow
Date.current.tomorrow
Date.now.tomorrow
DateTime.now.tomorrow.to_date
Time.now.tomorrow.to_date
Date.current + 1
Ruby
提供的这些方法,可以使我们能够轻松应付复杂的问题,譬如说要将某一笔资料的红利点数设定结束时间为今年的最後一天,或者下年的同月月底结束的话,可以用以下的方法写
# 该年最後一天
Date.today.end_of_year
# 该年最後一月
Date.today.end_of_month
# 某日隔天最开头 (00:00)
DateTime.tomorrow.beginning_of_day
# 某日隔天最结尾时间 (23:59)
DateTime.tomorrow.end_of_day
# 从今天算起一年後的该月最後一天
1.year.from_now.end_of_month
几天後
1.day.from_now # 一天後
2.days.from_now # 两天後
3.days.from_now # 三天後
指定日期的几天後
#======= start_time 可填入任意时间
1.day.from_now(start_time)
# 明天
1.day.from_now(Time.current)
#=> Wed, 08 Sep 2021 15:35:47 CST +08:00
# 昨天的明天
1.day.from_now(1.day.ago)
#=> Tue, 07 Sep 2021 15:33:17 CST +08:00
# 昨天的明天
1.day.from_now(DateTime.now.yesterday)
#=> Tue, 07 Sep 2021 15:33:28 +0800
strftime
跟正规表达式一样,都是每次用的时候,都要重新查询的用法,以下例举自己常用的几种方法。
# 下列两者意思等同
Time.current.strftime("%Y-%m-%d %H:%M:%S") #=> "2021-09-06 22:49:05"
Time.current.strftime("%F %T") #=> "2021-09-06 22:49:05"
DateTime.now.strftime('%Q')
#=> "1630999913620"
DateTime.now.strftime("%FT%T.%5N")
#=> "2021-09-07T15:32:28.76346""
Time.current
#=> Tue, 07 Sep 2021 09:14:01 CST +08:00
Time.current.to_time
#=> 2021-09-07 09:14:03 +0800
DateTime.now.to_time
#=> 2021-09-07 09:15:00 +0800
'2019.12.18 11:10:00'.to_datetime
#=> Wed, 18 Dec 2019 11:10:00 +0000
首先我们先讲send_time
回传的第一值为boolean
,其中true
代表意义为立即,相对来说,false
代表的意义为排程。在这里,回传的第一个值并不是重点,重点是在回传的第二个值。
下列为Tool
的使用情境:
推播时间
电商平台实作推播,必须要顾及顾客在合理的时间收到手机通知,要不然在半夜或清晨让顾客收到的话,顾客会有不好的观感,甚至有可能会想要删除App
,因此9-17点为当下推播,其余时间设定排程推播
物流取货时间:
实作物流方面,我们也必须顾及店家营业时间,在营业时间以外我们没有办法让物流进店取货,因此我们必须将营业时间以外的时间排到其他天的营业时间,以供顺丰物流取货。11点到17点可以请物流到府取货,当天11点以前的物流单排在11点,而当天17点以後的物流单则排在隔天的11点。
我们会在 Day11详细的介绍类别方法的使用,这边只会提到如何使用。
class Tool
class << self
# 推播时间: 9点到17点
def notification_sent_at
send_time(9, 17)
end
# 物流取货时间: 11点到17点
def sf_sent_at
send_time(11, 17).last.strftime("%F %T")
end
def send_time(start_hour, end_hour)
zero_am = DateTime.now.beginning_of_day
started_at = DateTime.now.beginning_of_day.change(hour: start_hour)
ended_at = DateTime.now.beginning_of_day.change(hour: end_hour)
if Time.current.between?(zero_am, started_at)
[false, started_at]
elsif Time.current.between?(ended_at, DateTime.now.tomorrow.beginning_of_day)
[false, DateTime.now.tomorrow.beginning_of_day.change(hour: start_hour)]
else
[true, Time.current]
end
end
end
end
⭐️ 寻找指定开始和结束时间的订单
Order.where(created_at: params[:startedAt]..params[:endedAt])
SELECT `orders`.* FROM `orders` WHERE `orders`.`created_at` >= '2021-08-19 03:10:25.041651' AND `orders`.`created_at` < '2021-08-20 03:10:25.042367' LIMIT 11
下列问题留给大家想,以下也是解时间问题时,工程师常常思考的问题。
Day2-Day7 主要介绍的内容为基本Ruby
使用
Day8-10 会介绍区块Block
<<: Day7 资料储存 - object storage优缺点及场景
最近想记录一下繁体转换简体,是因为网站或是在写blog的时候,未来会加入简体版,这样内容就可以迅速转...
大家好,我是Sean,一位Rails初心者,第一次发文请大大们手下留情XD 受一位朋友RS启发,决定...
若你有用过 github 的话,对於仓库 Repository 的概念想必是不陌生。它就是一个存放各...
前言 昨天知道一些背景的属性後,是不是觉得有点单调呀,所以我们今天就来谈谈渐层 基本语法 backg...
先去MYSQL官网下载:https://dev.mysql.com/downloads/ 然後按 这...