ROR + TodayDate in Different Format - ruby-on-rails

If I have #today = Date.today.to_s, how do I convert #today into UTC (with the appropriate date only)? But the format should be like this : 2011-03-08 00:00:00
Acutally I am looking for Yesterday date also ??

This worked for me to get yesterday at time 00hr
Date.yesterday.to_time.utc.at_beginning_of_day
=> Sun Mar 06 00:00:00 UTC 2011

I don't know if its the correct way to do it but it works
ruby-1.9.2-p0 > Date.today.to_time.utc
=> 2011-03-07 18:15:00 UTC
and for yesterday, you can subtract a day form today
(Date.today-1.day).to_time.utc
=> 2011-03-06 18:15:00 UTC

For Yesterday Date.
#date = Date.yesterday
=> Mon, 07 Mar 2011
#date.to_time.utc.strftime("%Y-%m-%d %H:%M:%S")
=> "2011-03-06 18:30:00"

This will do(%F - %Y-%m-%d and %T - %H:%M:%S)
Date.today.strftime("%F %T")
Date.yesterday.strftime("%F %T")
If you are particular about UTC time, you should do like this
(Time.now.utc).to_date.strftime("%F %T")
(Time.now.utc - 1.day).to_date.strftime("%F %T")

Related

Rails - A better way to parse the time with a timezone?

Time.parse returns a Time object that does not have a timezone. I would like to keep the timezone information. Is there a better way to do this then the following code?
def parse_with_timezone( string_input)
/(.*)([+-]\d\d):?(\d\d)$/.match( string_input) do |match|
tz = ActiveSupport::TimeZone[match[2].to_i.hours + match[3].to_i.minutes]
tz.parse( match[1])
end
end
The input is a string like this "2012-12-25T00:00:00+09:00". This function outputs a TimeWithZone object.
Were you looking for a specific timezone of the current local one?
# Current zone
1.9.3p194> Time.zone.parse('2012-12-25T00:00:00+09:00')
=> Mon, 24 Dec 2012 15:00:00 UTC +00:00
Console was set at UTC for above but will work for whatever you have configured
# Specific timezone
1.9.3p194> Time.find_zone('Wellington').parse('2012-12-25T00:00:00+09:00')
=> Tue, 25 Dec 2012 04:00:00 NZDT +13:00
I notice you're trying to pass +9 so as an example
1.9.3p194> Time.zone = 'Tokyo'
=> "Tokyo"
1.9.3p194> Time.zone.parse('2012-12-25T00:00:00+09:00')
=> Tue, 25 Dec 2012 00:00:00 JST +09:00
Gives you the right result.
What about the Rails Timezone API: http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
I prefer to use Chronic for all my date/time parsing needs.

Rails DateTime.now without Time

I need to use DateTime.now to grab the current date, and "strip off" the time.
For example, this shows what I don't want: DateTime.now => Sat, 19 Nov 2011 18:54:13 UTC +00:00
This shows what I do want: DateTime.now.some_operation => 2011-11-06 00:00:00 UTC
You can use one of the following:
DateTime.current.midnight
DateTime.current.beginning_of_day
DateTime.current.to_date
What you need is the function strftime:
Time.now.strftime("%Y-%d-%m %H:%M:%S %Z")
You can use just:
Date.current
What about Date.today.to_time?
If you're happy to require 'active_support/core_ext', then you can use
DateTime.now.midnight # => Sat, 19 Nov 2011 00:00:00 -0800
If you want today's date without the time, just use Date.today
Figured it out. This works:
DateTime.now.in_time_zone.midnight

Given a DateTime, how do I get the range of times with the same date in a particular time zone?

I have a DateTime object representing a particular date, as in "2011-01-15 00:00:00 UTC" to represent January 15th. I would like to produce the range of times in a particular time zone that have the same date.
The method signature would probably be something like
def day_range_for(date, tz)
# ...
end
For example, if I have range_for(DateTime.parse('2011-01-15'), 'CST'), then I want the result to be a range like 2011-01-15 00:00:00 -0600 .. 2011-01-15 23:59:59 -0600.
Can you take the input string instead of the object? If you pass in a DateTime object, its a tad counter intuitive because the time the object represents isn't the actual time you are looking for. It would conform to my expectations if you either passed in the correct, absolute DateTime, or the string itself. The actual meat of the problem is entirely handled by ActiveSupport, which I think you are using since you tagged this question with Rails. How does this look?
def range_for(input, tz=nil)
if tz.is_a?(String)
tz = ActiveSupport::TimeZone.new(tz)
else
tz = Time.zone
end
if input.acts_like?(:date) || input.acts_like?(:time)
d = input.in_time_zone(tz)
else
d = tz.parse(input)
end
return d.beginning_of_day..d.end_of_day
end
Have a look:
ruby-1.9.2-p0 > range_for('2011-01-15', 'Alaska')
=> Sat, 15 Jan 2011 00:00:00 AKST -09:00..Sat, 15 Jan 2011 23:59:59 AKST -09:00
ruby-1.9.2-p0 > range_for(Time.zone.now)
=> Mon, 10 Jan 2011 00:00:00 EST -05:00..Mon, 10 Jan 2011 23:59:59 EST -05:00
ruby-1.9.2-p0 > range_for('2011-01-15', 'EST')
=> Sat, 15 Jan 2011 00:00:00 EST -05:00..Sat, 15 Jan 2011 23:59:59 EST -05:00
How about:
def day_range_for date, zone
(DateTime.new(date.year,date.month,date.day,0,0,0,zone)..DateTime.new(date.year,date.month,date.day,23,59,59,zone))
end
day_range_for(DateTime.parse('2011-01-15'), 'CST')
#=> #<DateTime: 2011-01-15T00:00:00-06:00 (9822307/4,-1/4,2299161)>..#<DateTime: 2011-01-15T23:59:59-06:00 (212161917599/86400,-1/4,2299161)>

Daylight Savings Time not calculated properly in Rails 2.3.5?

I have a very strange issue with Daylight Savings Time (DST) in my app. For some reason, whenever I receive a time from the table, it doesn't adjust itself for DST. For example, if I create a new Time in the console, in the appropriate time zone, write it to the database, and then try to retrieve it from the database, it comes back as one hour earlier.
Here's an example:
Here, we can see that using the console, creating a new Time at 15:00 EST is equal to 19:00 UTC (since adjusted for DST, which makes it -0400 instead of the usual -0500):
ruby-1.8.6-p114 > Time.zone
=> #<ActiveSupport::TimeZone:0x12b1b68 #name="UTC", #tzinfo=nil, #utc_offset=0>
ruby-1.8.6-p114 > Time.zone = "Eastern Time (US & Canada)"
=> "Eastern Time (US & Canada)"
ruby-1.8.6-p114 > Time.zone.parse("15:00")
=> Thu, 09 Sep 2010 15:00:00 EDT -04:00
ruby-1.8.6-p114 > Time.zone.parse("15:00").utc
=> Thu Sep 09 19:00:00 UTC 2010
ruby-1.8.6-p114 > Time.zone.parse("15:00").dst?
=> true
Now, I try to write that same time to the database, and retrieve it back:
ruby-1.8.6-p114 > b = Book.new
=> #<Book id: nil, return_time: nil, created_at: nil, updated_at: nil>
ruby-1.8.6-p114 > b.return_time = Time.zone.parse("15:00")
=> Thu, 09 Sep 2010 15:00:00 EDT -04:00
ruby-1.8.6-p114 > b.save
=> true
ruby-1.8.6-p114 > result = Book.find(:last).return_time
=> Sat Jan 01 19:00:00 UTC 2000
ruby-1.8.6-p114 > result.zone
=> "UTC"
ruby-1.8.6-p114 > result.in_time_zone
=> Sat, 01 Jan 2000 14:00:00 EST -05:00
ruby-1.8.6-p114 > result.dst?
=> false
My environment.rb has this:
config.time_zone = 'UTC'
And application_controller.rb has this:
before_filter :set_user_time_zone
def set_user_time_zone
if current_user
Time.zone = current_user.time_zone
else
Rails.logger.error '[Time.zone.now.to_s][ERROR]: Missing current_user from in set_user_time_zone!'
end
end
Any ideas as to what could be happening here and how to fix it? I've been at this for days now, so really, any help would be greatly appreciated!
Thank you very much.
It looks like you're only saving the time portion; note how the date part goes from Thu, 09 Sep 2010 to Sat, 01 Jan 2000. Since the DST calculation depends on the date, this is probably where you're losing the information. (January 1st is not in DST, so assuming that date, the DST calculation is correct). You probably need to save a DATETIME in the database, not just TIME.
I'm not sure what version of Rails you're using, but I had the same problem in 2.1.2. It seems the time zone library included just doesn't work half the year, but the developers didn't think it was worth switching; hopefully they've rethought that decision by now.
In any case, we ended up using the tzinfo_timezone plugin, which computes UTC offsets correctly during daylight savings time.

Rails ActiveSupport Time Parsing?

Rails' ActiveSupport module extends the builtin ruby Time class with a number of methods.
Notably, there is the to_formatted_s method, which lets you write Time.now.to_formatted_s(:db) to get a string in Database format, rather than having to write ugly strftime format-strings everywhere.
My question is, is there a way to go backwards?
Something like Time.parse_formatted_s(:db) which would parse a string in Database format, returning a new Time object. This seems like something that rails should be providing, but if it is, I can't find it.
Am I just not able to find it, or do I need to write it myself?
Thanks
It looks like ActiveSupport does provide the parsing methods you are looking for (and I was looking for too), after all! — at least if the string you are trying to parse is a standard, ISO-8601-formatted (:db format) date.
If the date you're trying to parse is already in your local time zone, it's really easy!
> Time.zone.parse('2009-09-24 08:28:43')
=> Thu, 24 Sep 2009 08:28:43 PDT -07:00
> Time.zone.parse('2009-09-24 08:28:43').class
=> ActiveSupport::TimeWithZone
and that time-zone-aware time can then easily be converted to UTC
> Time.zone.parse('2009-09-24 08:28:43').utc
=> 2009-09-24 15:28:43 UTC
or to other time zones:
> ActiveSupport::TimeZone.us_zones.map(&:name)
=> ["Hawaii", "Alaska", "Pacific Time (US & Canada)", "Arizona", "Mountain Time (US & Canada)", "Central Time (US & Canada)", "Eastern Time (US & Canada)", "Indiana (East)"]
> Time.zone.parse('2009-09-24 08:28:43').utc.in_time_zone('Eastern Time (US & Canada)')
=> Thu, 24 Sep 2009 11:28:43 EDT -04:00
If the date string you're trying to parse is in UTC, on the other hand, it doesn't look like there's any method to parse it directly into a TimeWithZone, but I was able to work around that be first using DateTime.strptime...
If the date you're trying to parse is in UTC and you want it to stay as UTC, you can use:
> DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time
=> 2009-09-24 08:28:43 UTC
If the date you're trying to parse is in UTC and you want it converted to your default time zone, you can use:
> DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time.in_time_zone
=> Thu, 24 Sep 2009 01:28:43 PDT -07:00
It looks like it can even parse other formats, such as the strange format that Time#to_s produces:
irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08').to_s(:db)
=> "2009-09-23 09:18:08"
irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08 EDT').to_s(:db)
=> "2009-09-23 06:18:08"
I'm quite impressed.
Here are some more examples from [http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html][1]:
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45 EST -05:00
Time.zone.at(1170361845) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
Time.zone.now # => Sun, 18 May 2008 13:07:55 EDT -04:00
Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45 EST -05:00
More documentation links for reference:
http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08')
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00
Rails 5 finally provides strptime!
value = '1999-12-31 14:00:00'
format = '%Y-%m-%d %H:%M:%S'
Time.zone.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 HST -10:00
ActiveSupport::TimeZone.all.sample.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 GST +04:00
I just ran into this as well and none of the above answers were satisfactory to me. Ideally one could use ActiveSupport::TimeZone just like Time and call .strptime on it with any arbitrary format and get back the correct TimeZone object. ActiveSupport::TimeZone.strptime doesn't exist so I created this monkeypatch:
class ActiveSupport::TimeZone
def strptime(str, fmt, now = self.now)
date_parts = Date._strptime(str, fmt)
return if date_parts.blank?
time = Time.strptime(str, fmt, now) rescue DateTime.strptime(str, fmt, now)
if date_parts[:offset].nil?
ActiveSupport::TimeWithZone.new(nil, self, time)
else
time.in_time_zone(self)
end
end
end
>> "2009-09-24".to_date
=> Thu, 24 Sep 2009
>> "9/24/2009".to_date
=> Thu, 24 Sep 2009
Works great unless your date is in some weird format.

Resources