Rails:获取时区中的#beginning_of_day

发布于 2024-10-27 03:31:29 字数 424 浏览 14 评论 0原文

我为 Rails 应用程序设置了默认时区。 以及 Date 对象的实例。

我怎样才能让 Date#beginning_of_day 返回指定时区的一天的开始,而不是我的本地时区。

是否有其他方法可以获取给定日期的指定时区的一天时间的开始时间?

date = Date.new(2014,10,29)

zone = ActiveSupport::TimeZone.new('CET')
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 CET +01:00"

zone = ActiveSupport::TimeZone.new('UTC')
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 UTC +00:00"

I have a default time zone setup for the rails application.
And an instance of the Date object.

How can I get make Date#beginning_of_day to return the beginning of the day in the specified time zone, but not my local timezone.

Is there any other method to get beginning of the day time in the specified timezone for the given date?

date = Date.new(2014,10,29)

zone = ActiveSupport::TimeZone.new('CET')
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 CET +01:00"

zone = ActiveSupport::TimeZone.new('UTC')
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 UTC +00:00"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

甜味拾荒者 2024-11-03 03:31:29
DateTime.now.in_time_zone(Time.zone).beginning_of_day
DateTime.now.in_time_zone(Time.zone).beginning_of_day
挽你眉间 2024-11-03 03:31:29

Date#beginning_of_day 将始终返回 00:00。

但据我了解,您想知道其他时区的时间,而当前时区的时间是一天的开始。

所以。让我们看看您当前所在的地方一天的开始时间。想象一下这是法国巴黎:

bd = DateTime.now.in_time_zone('Paris').beginning_of_day
# or just
bd = DateTime.now.in_time_zone(1).beginning_of_day
#=> Thu, 24 Mar 2011 00:00:00 WET +01:00

现在让我们找出莫斯科的时间:

moscow_time = bd.in_time_zone("Moscow") # or in_time_zone(3)
#=> Thu, 24 Mar 2011 02:00:00 AST +03:00
london_time = bd.in_time_zone("London")
#=> Wed, 23 Mar 2011 23:00:00 GMT +00:00
kyiv_time = bd.in_time_zone("Kyiv")
#=> Thu, 24 Mar 2011 01:00:00 EET +02:00 

对于不同的形式now日:

# You even shouldn't call now, because it by default will be 00:00
date = DateTime(2011, 1, 3).in_time_zone("-10")
# or
date = DateTime.new(2011,1,3,0,0,0,"-10")
# and same way as above
moscow_time = date.in_time_zone("Moscow") # or in_time_zone(3)

并将Date转换为DateTime

date = Date.new(2011,1,3).to_datetime.change(:offset => "EST")

Date#beginning_of_day will always return 00:00.

But as I understand you want to know time in other time zone while in current time zone is beginning of the day.

So. Let's find out beginning of the day in your current place. Imagine it is Paris, France:

bd = DateTime.now.in_time_zone('Paris').beginning_of_day
# or just
bd = DateTime.now.in_time_zone(1).beginning_of_day
#=> Thu, 24 Mar 2011 00:00:00 WET +01:00

Now lets found out what time is in Moscow:

moscow_time = bd.in_time_zone("Moscow") # or in_time_zone(3)
#=> Thu, 24 Mar 2011 02:00:00 AST +03:00
london_time = bd.in_time_zone("London")
#=> Wed, 23 Mar 2011 23:00:00 GMT +00:00
kyiv_time = bd.in_time_zone("Kyiv")
#=> Thu, 24 Mar 2011 01:00:00 EET +02:00 

For different form now day:

# You even shouldn't call now, because it by default will be 00:00
date = DateTime(2011, 1, 3).in_time_zone("-10")
# or
date = DateTime.new(2011,1,3,0,0,0,"-10")
# and same way as above
moscow_time = date.in_time_zone("Moscow") # or in_time_zone(3)

and converting Date to DateTime

date = Date.new(2011,1,3).to_datetime.change(:offset => "EST")
Oo萌小芽oO 2024-11-03 03:31:29

离开佩德的回答,这是我对 PST 时区所做的事情:

DateTime.now.in_time_zone("Pacific Time (US & Canada)").beginning_of_day

Going off Peder's answer, here's what I did for the PST time zone:

DateTime.now.in_time_zone("Pacific Time (US & Canada)").beginning_of_day
唯憾梦倾城 2024-11-03 03:31:29

我知道这篇文章很旧,但是:

Time.zone.parse("12am")

I know this post is old, but what about:

Time.zone.parse("12am")
堇年纸鸢 2024-11-03 03:31:29
may2 = Date.new(2012,5,2)
midnight = Time.zone.local(may2.year,may2.month,may2.day).beginning_of_day

2012 年 5 月 2 日星期三 00:00:00 UTC +00:00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Moscow").beginning_of_day

=> 2012 年 5 月 2 日星期三 00:00:00 MSK +04:00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Alaska").beginning_of_day

=> 2012 年 5 月 1 日星期二 00:00:00 AKDT -08:00

注意,今天是错误的一天。

需要的是一种在正确时区构造 TimeWithZone 的方法。

Time.zone="Alaska"
midnight = Time.zone.local(may2.year,may2.month,may2.day)

我真的不喜欢这个,因为据我所知,我刚刚更改了我所在区域的系统概念。这个想法是更改我的数据库搜索以匹配该区域的区域客户...
所以,我必须保存区域并恢复它:

foo = Time.zone; Time.zone="Alaska"; midnight = Time.zone.local(may2.year,may2.month,may2.day); Time.zone = foo

看起来我应该能够调用 TimeWithZone.new(),但我不知道如何调用。

may2 = Date.new(2012,5,2)
midnight = Time.zone.local(may2.year,may2.month,may2.day).beginning_of_day

Wed, 02 May 2012 00:00:00 UTC +00:00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Moscow").beginning_of_day

=> Wed, 02 May 2012 00:00:00 MSK +04:00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Alaska").beginning_of_day

=> Tue, 01 May 2012 00:00:00 AKDT -08:00

NOTICE, it's the WRONG DAY.

What is needed is a way to construct a TimeWithZone in the correct timezone.

Time.zone="Alaska"
midnight = Time.zone.local(may2.year,may2.month,may2.day)

I really dislike this, because as far as I can see, I've just changed the system notion of what zone I'm in. The idea is to change my database searches to match the zone of the client...
So, I have to save zone and restore it:

foo = Time.zone; Time.zone="Alaska"; midnight = Time.zone.local(may2.year,may2.month,may2.day); Time.zone = foo

It seems like I ought be able to call TimeWithZone.new(), but I didn't figure out how.

も让我眼熟你 2024-11-03 03:31:29
ActiveSupport::TimeZone['Europe/London'].parse('30.07.2013') # 2013-07-29 23:00:00 UTC 
ActiveSupport::TimeZone['Asia/Magadan'].parse('30.07.2013') # 2013-07-29 12:00:00 UTC
ActiveSupport::TimeZone['Europe/London'].parse('30.07.2013') # 2013-07-29 23:00:00 UTC 
ActiveSupport::TimeZone['Asia/Magadan'].parse('30.07.2013') # 2013-07-29 12:00:00 UTC
够运 2024-11-03 03:31:29

正如 Leonid Shevtsov 提到的,Date.beginning_of_day 不支持 ActiveSupport 2.3 中的 Time.zone

我使用的替代方案,如果您卡住使用 Rails 4.0 或 ActiveSupport 2.3,并且您需要使用自定义日期:

date = Date.new(2014,10,29)
date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone  #.beginning_of_day
date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone #.end_of_day

结果:

2.0.0-p247 :001 > date = Date.new(2014,10,29)
 => Wed, 29 Oct 2014 

2.0.0-p247 :002 > date.to_time.change(hour: 0, min: 0, sec: 0)
 => 2014-10-29 00:00:00 -0500 

2.0.0-p247 :003 > date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone
 => Wed, 29 Oct 2014 05:00:00 UTC +00:00 

2.0.0-p247 :004 > date.to_time.change(hour: 23, min: 59, sec: 59)
 => 2014-10-29 23:59:59 -0500 

2.0.0-p247 :005 > date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone
 => Thu, 30 Oct 2014 04:59:59 UTC +00:00 

我原来使用 .beginning_of_day 到 .end_of_day 的失败模型范围无法工作:

scope :on_day, ->(date) { where( created_at: date.beginning_of_day..date.end_of_day ) }

而且,这就是修复它的原因,因为我无法升级到 Rails 4.0

scope :on_day, ->(date) { where( created_at: date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone..date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone ) }

As Leonid Shevtsov mentioned, Date.beginning_of_day does not honor Time.zone in ActiveSupport 2.3

An alternative I used, if your stuck using Rails 4.0 or ActiveSupport 2.3, and you need to use a custom date:

date = Date.new(2014,10,29)
date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone  #.beginning_of_day
date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone #.end_of_day

Results:

2.0.0-p247 :001 > date = Date.new(2014,10,29)
 => Wed, 29 Oct 2014 

2.0.0-p247 :002 > date.to_time.change(hour: 0, min: 0, sec: 0)
 => 2014-10-29 00:00:00 -0500 

2.0.0-p247 :003 > date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone
 => Wed, 29 Oct 2014 05:00:00 UTC +00:00 

2.0.0-p247 :004 > date.to_time.change(hour: 23, min: 59, sec: 59)
 => 2014-10-29 23:59:59 -0500 

2.0.0-p247 :005 > date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone
 => Thu, 30 Oct 2014 04:59:59 UTC +00:00 

My original failed model scope using .beginning_of_day to .end_of_day failed to work:

scope :on_day, ->(date) { where( created_at: date.beginning_of_day..date.end_of_day ) }

And, this is what fixed it, since I could not upgrade to Rails 4.0

scope :on_day, ->(date) { where( created_at: date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone..date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone ) }
抠脚大汉 2024-11-03 03:31:29

在特定时区生成新日期

如果您想获取特定日期的一天开始时间(并且您知道确切的日期),那么您必须使用:

Time.use_zone('London'){ Time.zone.local(2022, 1, 1) }
# => Sat, 01 Jan 2022 00:00:00.000000000 GMT +00:00

它尊重季节时间变化:

Time.use_zone('London'){ Time.zone.local(2022, 6, 1) }
# => Wed, 01 Jun 2022 00:00:00.000000000 BST +01:00

尽管它已经由接受的引用我想补充一点,我个人更喜欢块符号

转换现有日期并找出另一个时区的日期

如果您想知道已有的特定时间戳/纪元/日期是哪一天,您需要将现有日期转换为正确的时区, Peder 和 Tim 的答案已经提到了这一点:

Time.current.in_time_zone('London').beginning_of_day

请注意,在转换现有日期时,您可能会得到另一个日期天(第 1 日变为第 2 日)

Time.use_zone('London'){ Time.zone.local(2022, 6, 1, 23, 0, 0) }.in_time_zone('Tokyo').beginning_of_day
# => Thu, 02 Jun 2022 00:00:00.000000000 JST +09:00

如果您要转换时间,则 Time.nowTime.current 无关紧要,但我更喜欢使用 Time.current 作为规则:

Time.now
# => 2022-09-30 15:29:16 +0000

Time.current
=> Fri, 30 Sep 2022 16:29:36.006315710 BST +01:00

Generate new date in a specific time zone

If you would like to get beginning of the day for a specific date (and you know the exact date), then you have to use:

Time.use_zone('London'){ Time.zone.local(2022, 1, 1) }
# => Sat, 01 Jan 2022 00:00:00.000000000 GMT +00:00

It respects seasonal time change:

Time.use_zone('London'){ Time.zone.local(2022, 6, 1) }
# => Wed, 01 Jun 2022 00:00:00.000000000 BST +01:00

Although it is already referred by accepted answer I'd like to add that personally I prefer block notation.

Convert existing and find out what the day it is in another time zone

If you would like to know what day that would be for a specific timestamp/epoch/date that you already have you need to convert your existing date to the proper time zone, which is already referred by Peder's and Tim's answers:

Time.current.in_time_zone('London').beginning_of_day

Be aware, when converting existing date you may end up in another day (1st became 2nd):

Time.use_zone('London'){ Time.zone.local(2022, 6, 1, 23, 0, 0) }.in_time_zone('Tokyo').beginning_of_day
# => Thu, 02 Jun 2022 00:00:00.000000000 JST +09:00

If you are going to convert time, then Time.now or Time.current is indifferent, but I prefer using Time.current as a rule:

Time.now
# => 2022-09-30 15:29:16 +0000

Time.current
=> Fri, 30 Sep 2022 16:29:36.006315710 BST +01:00
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文