I have a problem related to timezone behaviour of a Rails 3.1.1 application. Here is, what I did on my console:
(rdb:1) Time.zone = "Amsterdam"
"Amsterdam"
(rdb:1) Time.zone.parse("Sun, 06 Nov 2011 13:05:18 +0000")
Sun, 06 Nov 2011 14:05:18 CET +01:00
(rdb:1) Time.zone = "Atlantic Time (Canada)"
"Atlantic Time (Canada)"
(rdb:1) Time.zone.parse("Sun, 06 Nov 2011 13:05:18 +0000")
Sun, 06 Nov 2011 09:05:18 AST -04:00
My object's timestamp is UTC. In my timezone Amsterdam it was 14:05 when I created it. In New York City the timezone is "Atlantic Time (Canada)". Parsing the timestamp in that zone results in 09:05. But thats wrong, it should be 08:05.
Besides that the time difference between both zones seems to be -4 -1 = -5 but is in fact -6 hours.
That behaviour completely destroy's my apps behaviour. What am I doing wrong here?
Regards
Felix.
You are not doing anything wrong. The DST changed today, Nov 6, at 2 AM. So the time is 9:05, and not 8:05. Also, New York is in Eastern time, not Atlantic time.
Related
I am trying to convert a date/time string "06/14/2016 07:00 PM" to a Time object under the PST time zone. I want the result to be Tue, 14 Jun 2016 19:00:00 PDT -07:00.
I tried the following:
t = "06/14/2016 07:00 PM"
r = Time.strptime(t, "%m/%d/%Y %I:%M %p").in_time_zone("Pacific Time (US & Canada)")
The time comes back as Tue, 14 Jun 2016 17:00:00 PDT -07:00. Any ideas?
This code to me works properly, but there are two possible issues that are giving you the wrong result:
You are not in the pacific time zone (or at least not according to your computer): You can test this by running r = Time.strptime(t, "%m/%d/%Y %I:%M %p"), and then printing the result of r. I'm willing to wager that it outputs
Tue, 14 Jun 2016 19:00:00 CDT -05:00
You are using ruby and not rails, in_time_zone is a method only in rails. If you try to use it in ruby it will not work.
I need to use .next_week not +1.week. Because the .next_week make the date next week and Monday at the same time. It's so comfortable. And then I subtract some hours. But nothing has been changed. Here's my code.
newDate = DateTime.now
newDate = newDate.next_week - 3.hours
=> Sun, 30 Aug 2015 21:00:00 +0900
newDate = newDate.next_week - 3.hours
=> Sun, 30 Aug 2015 21:00:00 +0900
newDate = newDate.next_week - 3.hours
=> Sun, 30 Aug 2015 21:00:00 +0900
Why they can't be used same time? Please explain to me. Thanks.
This has nothing to do with #next_week and - 3.hours working at the same time. It is a misunderstanding about how #next_week works.
#next_week assumes by default a week is Monday-Sunday. This means when calling just #next_week it will return the next Monday at 00:00:00:00.
Example:
DateTime.now.next_week
#=> Mon, 03 Aug 2015 00:00:00 -0400
Okay so that make sense. Now you are substracting 3.hours making it Sunday again
DateTime.now.next_week - 3.hours
#=> Sun, 02 Aug 2015 21:00:00 -0400
Still makes perfect sense. Now here is where the confusion is. Since you rolled back to Sunday by subtracting 3.hours the #next_week is the following Monday again so
(DateTime.now.next_week - 3.hours).next_week
#=> Mon, 03 Aug 2015 00:00:00 -0400
I hope this helps you understand the situation a bit better.
If you use + 1.week this will take you to the same exact point in time the following week
DateTime.now + 1.week
#=> Fri, 07 Aug 2015 09:01:17 -0400
This does not rely on a weekly calendar but rather the basic math of adding 7 days to the referenced Date object.
In conclusion while #next_week might be comfortable you need to understand what it actually implies and I think I would prefer + 1.week in this case for its flexibility and its lack of assumption.
There are also many other methods for traversing time through ActiveSupport such as #advance, #days_since, weeks_since, etc.
Final note next_week can accept a day parameter as well e.g
DateTime.now.next_week(:tuesday)
#=> Tue, 04 Aug 2015 00:00:00 -0400
DateTime.now.next_week(:thursday)
#=> Thu, 06 Aug 2015 00:00:00 -0400
I know it is common error but I could not resolve it even after trying those answers.
Through the rest api I am sending some parameters inculdes dates. I am recieving all the data in the method where I want but when I am trying to parse Date it throws error of invalid date.
Here are my parameters that I am recieving
{"uid"=>"1", "user"=>"abc.a#abc.com", "from"=>"Mon Nov 3 24:59:12 CET 2014", "to"=>"Tue Nov 11 24:59:12 CET 2014"}
and Date format is
Mon Nov 3 24:59:12 CET 2014
but it is throwing error on parsing on line below
fr = DateTime.parse(params[:from]) unless params[:from].empty?
I tried strptime as well but did not work.
Imp points is I need hour also for later processing. Thanks
what you are doing wrong is parsing DateTime while it is just date and should be parsed as one of the following ways:
1.
>> fr = params[:from].to_date unless params[:from].empty?
=> Mon, 03 Nov 2014
2.
>> fr = Date.parse(params[:from]) unless params[:from].empty?
=> Mon, 03 Nov 2014
You have 24:59 which is invalid time. Anyway, use strptime:
DateTime.strptime("Mon Nov 3 22:59:12 CET 2014", "%a %b %e %T %Z %Y")
#=> Mon, 03 Nov 2014 22:59:12 +0100
Look at this code:
[4, 5, 6, 7].each do |x|
start_at = Time.zone.parse("2014.10.2#{x} 08:00")
puts "#{start_at.inspect} / #{start_at.seconds_since_midnight/60}"
end
Output:
Fri, 24 Oct 2014 08:00:00 CEST +02:00 / 480.0
Sat, 25 Oct 2014 08:00:00 CEST +02:00 / 480.0
Sun, 26 Oct 2014 08:00:00 CET +01:00 / 480.0
Mon, 27 Oct 2014 08:00:00 CET +01:00 / 480.0
We are in Germany, and on October 26 the DST is reset so 08:00 is not actually 8*60 minutes since midnight but 9*60.
IMHO, this should be respected by the seconds_since_midnight method. Am I missing something or is this actually a Ruby bug?
Using Ruby 1.9.3, Rails 3.0.20 on Mac OS X 10.9.5 (MacPorts).
(Yes, Rails 3.0.20 is old. Legacy project. If it's fixed in Rails 4, all the better.)
According to the Rails docs, it's implemented as such:
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 14
def seconds_since_midnight
sec + (min * 60) + (hour * 3600)
end
Thus, this function is not time zone aware. It simply looks at the local time value. It does not consider that the offset of midnight might not be the same as the offset of the value you provided. Nor does it consider that midnight might not exist in the local time zone (such as with Brazil's spring-forward transition).
Is this a bug? Perhaps. But one might also say the method is just poorly named. Either way, it's an issue with Rails, not with Ruby.
So right now it is 2:54 PM PST in San Francisco. For some reason, this code block is not returning 12:54 PM HST in Hawaii. Am I missing something here? I would expect this code to return me the current time in Hawaii
Time.use_zone('Hawaii') do
Time.now
end
# => 2012-01-03 14:54:54 -0800
This should work ok:
Time.use_zone('Hawaii') do
p Time.zone.now
end
Try using Time.now.in_time_zone inside your block instead.
> Time.use_zone('Hawaii') do
> Time.now.in_time_zone
> end
=> Tue, 03 Jan 2012 13:07:06 HST -10:00
Use Time.current if you want now with timezone support. Time.now is dangerous when working in a timezone aware application, as a rule of thumb I never use Time.now, only Time.current. Rails time helpers like 2.hours.ago and 4.days.from_now are based off of Time.current as well.
# Time.current will use Time.zone when needed (when Time.zone is present)
def current
::Time.zone ? ::Time.zone.now : ::Time.now
end
Also, this is a great article with a great cheat sheet at the bottom: https://www.varvet.com/blog/working-with-time-zones-in-ruby-on-rails/
DOs
code
result
2.hours.ago
Thu, 27 Aug 2015 14:39:36 AFT +04:30
1.day.from_now
Fri, 28 Aug 2015 16:39:36 AFT +04:30
Time.zone.parse("2015-08-27T12:09:36Z")
Thu, 27 Aug 2015 16:39:36 AFT +04:30
Time.current
Thu, 27 Aug 2015 16:39:36 AFT +04:30
When supliyng an API
Time.current.utc.iso8601
2015-08-27T12:09:36Z
If you can’t use Time.zone.parse
Time.strptime("2015-08-27T12:09:36Z", "%Y-%m-%dT%H:%M:%S%z").in_time_zone
Thu, 27 Aug 2015 16:39:36 AFT +04:30
If you really can’t have a Time or DateTime for some reason
Date.current
Thu, 27 Aug 2015
If you have a date and want to make the best out of it
Date.current.in_time_zone
Thu, 27 Aug 2015 00:00:00 AFT +04:30
DON’Ts
code
result
Returns system time and ignores your configured time zone.
Time.now
2015-08-27 14:09:36 +0200
Will assume time string given is in the system’s time zone.
Time.parse("2015-08-27T12:09:36Z")
2015-08-27 12:09:36 UTC
Same problem as with Time.parse.
Time.strptime("2015-08-27T12:09:36Z", "%Y-%m-%dT%H:%M:%S%z")
2015-08-27 12:09:36 UTC
This could be yesterday or tomorrow depending on the machine’s time zone, see issue 1 for more info.
Date.today
Thu, 27 Aug 2015
Time.now - using server time
Time.zone.now - using rails application time (in config: config.time_zone)
Time.use_zone - using 'your' timezone for given block
This example is wrong, because Time.now get time in your server timezone and with method in_time_zone translate time into an equivalent time in Hawaii timezone. But it's no current Time in Hawaii! It's your server time with utc offset for Hawaii.
Time.use_zone('Hawaii') do
Time.now.in_time_zone
end
=> Wed, 14 Aug 2013 10:33:18 HST -10:00
Time.now.in_time_zone
=> Thu, 15 Aug 2013 00:32:30 MSK +04:00
For getting time in Hawaii timezone you must use
Time.use_zone('Hawaii') do
Time.zone.now
end
Don't use Time.now this is using your local time zone instead use Time.current
Time.use_zone('Hawaii') do
p Time.current
end