Which one of these is correct? - ruby

Among the following formats which is correct not just syntax but as a practice as well ?
DateTime.strptime((date[:month]+date[:year]),'%B %Y')
or
DateTime.strptime((date[:month]+' '+date[:year]),'%B %Y')
or
DateTime.strptime((date[:month]+date[:year]),'%B%Y')

Ref strptime
They both are correct as long as you giving correct values
of 'date[:month]' & 'date[:year]'
1.9.3p327 :015 > DateTime.strptime("Mar 2010",'%B %Y')
=> Mon, 01 Mar 2010 00:00:00 +0000
1.9.3p327 :016 > DateTime.strptime("Mar2010",'%B %Y')
=> Mon, 01 Mar 2010 00:00:00 +0000

Syntactically, both DateTime.strptime((date[:month]+' '+date[:year]),'%B %Y') and DateTime.strptime((date[:month]+date[:year]),'%B%Y') are correct.
As a practice, the 2nd one is better as there is no point adding a ' ' and then parsing it out. Anyway, both will give the same output.

Related

Split string and put in variables with ruby

I got the following input from user
'Wed, 02 Nov 2016 19:00:00'.
How can I split this string for date and time and place in variables with ruby?
How can I get the same string from the variables then?
I look throw regexp and date docs on ruby.tried to write smth:
require 'date'
puts DateTime.strftime('Wed, 02 Nov 2016 19:00:00', '%a, %d %b %y %H:%M:%S')
got the error
test-2.rb:17:in `<main>': undefined method `strftime' for DateTime:Class (NoMethodError)
Did you mean? strptime
_strptime
Parse a time object
This code extracts a Time object and converts it back to a date, time and date_time string.
require 'time'
time = Time.parse("Wed, 02 Nov 2016 19:00:00")
date_str = time.strftime('%a, %d %b %Y') #=> "Wed, 02 Nov 2016"
time_str = time.strftime('%T') #=> "19:00:00"
datetime_str = time.strftime('%a, %d %b %Y %T') #=> "Wed, 02 Nov 2016 19:00:00"
Split the string directly
If you don't need a Time object, you can just split the string around the last space :
date, time = "Wed, 02 Nov 2016 19:00:00".split(/ (?=\S+$)/)
date # => "Wed, 02 Nov 2016"
time # => "19:00:00"
irb(main):001:0> require 'time'
=> true
irb(main):002:0> dt = DateTime.parse('Wed, 02 Nov 2016 19:00:00')
=> #<DateTime: 2016-11-02T19:00:00+00:00 ((2457695j,68400s,0n),+0s,2299161j)>
irb(main):003:0> dt_date = dt.strftime('%Y/%m/%d')
=> "2016/11/02"
irb(main):004:0> dt_time = dt.strftime('%H:%M:%S')
=> "19:00:00"
irb(main):005:0>
require 'time'
time = Time.parse("Wed, 02 Nov 2016 19:00:00")
p time #2016-11-02 19:00:00 +0000
p time.day #2
p time.month #11
p time.year #2016
You can parse the time like so by requiring the module time. It will take the string date provided by the user, and convert it to an actual date and time recognized by ruby. Then you can use the built in methods provided by the time module and store that data in to variables. I hope that answers your question.

`DateTime.strptime` returns invalid date for weekday/time string

Why won't Ruby's strptime convert this to a DateTime object:
DateTime.strptime('Monday 10:20:20', '%A %H:%M:%S')
# => ArgumentError: invalid date
While these work?
DateTime.strptime('Wednesday', '%A')
# => #<DateTime: 2015-11-18T00:00:00+00:00 ((2457345j,0s,0n),+0s,2299161j)>
DateTime.strptime('10:20:20', '%H:%M:%S')
# => #<DateTime: 2015-11-18T10:20:20+00:00 ((2457345j,37220s,0n),+0s,2299161j)>
This looks like a bug - minitech's comment is spot on. For now, though, a workaround (because you probably want this to work now):
You can split it on the space, get the date from the weekday, then get the time component from the other string (using the _strptime method minitech mentioned). Then you can set the time on the first date to the time component from the second string:
def datetime_from_weekday_time_string(string)
components = string.split(" ")
date = DateTime.strptime(components[0], '%A')
time = Date._strptime(components[1], '%H:%M:%S') # returns a hash like {:hour=>10, :min=>20, :sec=>20}
return date.change(time)
end
2.2.2 :021 > datetime_from_weekday_time_string("Monday 10:20:20")
=> Mon, 16 Nov 2015 10:20:20 +0000
2.2.2 :022 > datetime_from_weekday_time_string("Saturday 11:45:21")
=> Sat, 21 Nov 2015 11:45:21 +0000
2.2.2 :023 > datetime_from_weekday_time_string("Thursday 23:59:59")
=> Thu, 19 Nov 2015 23:59:59 +0000

How to use to_date in rails?

Ruby 2.0
controller action
#date = "2013-12-21"
#new_date = #date.to_date
p #new_date
o/p: Sat, 21 Dec 2013
at view
<%= #new_date %>
o/p: 2013-12-21
i want on view "Sat, 21 Dec 2013"
Rails is so intelligent that it automatically calls all objects in a view that are not already a string via the method .to_s, which always converts the content of the object to a string.
Lets first dig me into the root cause, why such unexpected output :
kirti#kirti-Aspire-5733Z:~/workspace/testproject$ rvm use 1.9.3
Using /home/kirti/.rvm/gems/ruby-1.9.3-p484
kirti#kirti-Aspire-5733Z:~/workspace/testproject$ rails c
Loading development environment (Rails 3.2.16)
1.9.3p484 :001 > d = "2013-12-21".to_date
=> Sat, 21 Dec 2013
1.9.3p484 :002 > d.to_s
=> "2013-12-21"
1.9.3p484 :003 > d
=> Sat, 21 Dec 2013
1.9.3p484 :004 > d.class
=> Date
1.9.3p484 :005 > d.strftime('%a, %e %b %Y')
=> "Sat, 21 Dec 2013"
1.9.3p484 :006 >
"2013-12-21".to_date giving you a Date instance, not a String instance.d.class proved that. d is a Date instance, on which in view again to_s method is called as I told in the begining, so Sat, 21 Dec 2013 is again set back into the "2013-12-21". So your solution will be :
#date = "2013-12-21".to_date.strftime('%a, %e %b %Y')
"2013-12-21".to_date.strftime('%a, %e %b %Y') will give you the desired result as an String instance.So on string instance(receiver) if you apply to_s,you will get the same receiver back. Now you can use this #date variable in your view.
in Ruby 2.0 in a controller's action:
#date = "2013-12-21"
#new_date = #date.to_date
# => Sat, 21 Dec 2013
And use the #new_date on your view.
#new_date.strftime('%a, %e %b %Y')
Use it directly on the view.
From what I understand, you are getting
2013-12-21
but want
Sat, 21 Dec 2013
The reason it is outputted in the console nicely is because the console will auto format it for you. This can be verified by printing #new_date.to_s in the console, it'll be the unformatted version. To print it out on a screen in the way you want, you have to format it yourself.
You should use strftime like this:
#new_date = #new_date.strftime('%a, %e %b %Y')
or
#date.to_date.strftime('%a, %e %b %Y')
This will output Sat, 21 Dec 2013 correctly.
The best way to format a date object in Rails is by using the available I18n formatters.
<%= l # new_date, format: :long %>
As described in the guide, you can also create additional formats. For example, if none of the defaults matches your desired format, simply define
# config/locales/en.yml
en:
time:
formats:
custom: "%a, %e %b %Y"
then use
<%= l # new_date, format: :custom %>

ruby DateTime parsing from 'mm/dd/yyyy' format

I am using ruby 1.9.3 and want to get Date or Time object from 'mm/dd/yyyy' date format string
Time.zone.parse("12/22/2011")
this is giving me *** ArgumentError Exception: argument out of range
require 'date'
my_date = Date.strptime("12/22/2011", "%m/%d/%Y")
As above, use the strptime method, but note the differences below
Date.strptime("12/22/2011", "%m/%d/%Y") => Thu, 22 Dec 2011
DateTime.strptime("12/22/2011", "%m/%d/%Y") => Thu, 22 Dec 2011 00:00:00 +0000
Time.strptime("12/22/2011", "%m/%d/%Y") => 2011-12-22 00:00:00 +0000
(the +0000 is the timezone info, and I'm now in GMT - hence +0000. Last week, before the clocks went back, I was in BST +0100. My application.rb contains the line config.time_zone = 'London')
Try Time.strptime("12/22/2011", "%m/%d/%Y")
Would it be an option for you to use Time.strptime("01/28/2012", "%m/%d/%Y") in place of Time.parse? That way you have better control over how Ruby is going to parse the date.
If not there are gems: (e.g. ruby-american_date) to make the Ruby 1.9 Time.parse behave like Ruby 1.8.7, but only use it if it's absolutely necessary.
1.9.3-p0 :002 > Time.parse '01/28/2012'
ArgumentError: argument out of range
1.9.3-p0 :003 > require 'american_date'
1.9.3-p0 :004 > Time.parse '01/28/2012'
=> 2012-01-28 00:00:00 +0000

Rails 2.3.2, wrong date, system date is correct

ruby-1.8.6-p399 :005 > Date.today
=> Wed, 24393 Dec 2135
ruby-1.8.6-p399 :006 > DateTime.now
=> Wed, 24393 Dec 2135 17:07:09 +0100
wopi#wopi-desktop:~/work/trunk$ date
Mi 2. Feb 17:08:46 CET 2011
What's wrong ?
https://gist.github.com/807916
What do you get with: Time.at(0) ?
Should be 1969...
What do you get with Time.now?
The date objects come from the date class, which inherits from the time class:
http://corelib.rubyonrails.org/classes/Time.html
Other helpful methods to test could be there. Try doing straight ruby to see if it's a problem with your rails setup or with ruby. You should be able to trace the specific place where this goes wrong.

Resources