Ruby - Convert Day Of Week To Integer - ruby-on-rails

How would you convert a day string (i.e. "Monday" or "Wednesday"), into the corresponding wday integer (1 or 3)?
I've come up with this convoluted way
Date.today.beginning_of_week("Monday".downcase.to_sym).wday

You can parse it using strptime:
Date.strptime('Monday', '%A').wday
#=> 1
Date.strptime('Wednesday', '%A').wday
#=> 3
The intermediate date object refers to the weekday in the current week:
Date.today
#=> #<Date: 2018-11-20 ...>
Date.strptime('Monday', '%A')
#=> #<Date: 2018-11-19 ...>
You can also use _strptime (prefixed with an underscore) to extract the date elements which happen to be :wday for a single weekday:
Date._strptime('Monday', '%A')
#=> {:wday=>1}

You can use the CHRONIC gem.
Chronic is a Ruby natural language date/time parser written by Tom
Preston-Werner (#mojombo) which takes surprisingly human readable text
and converts it to dates. (http://robdodson.me/playing-with-ruby-dates/)
You can use like this:
require 'chronic'
Chronic.parse('Monday').wday
=> 1
I hope help you!

Related

Rails 4: m/d/yy will not successfully format

I am pretty familiar with strptime in Rails, but I cannot get this date to format. The date is coming from a long .csv file so it would be a pain to pre-format the dates differently.
date = "2/9/17"
Date.strptime(date, "%-m/%-d/%y")
ArgumentError: invalid date
From the strptime documentation:
strptime does not support specification of flags and width unlike strftime
So you need a slightly simplified pattern:
date = "2/9/17"
Date.strptime(date, "%m/%d/%y")
# => #<Date: 2017-02-09 ((2457794j,0s,0n),+0s,2299161j)>
Date.strptime(date, "%m/%d/%y")?

Proper way to get next year from now

How I can get the next year in Rails?
I need to get only the year, without the date.
When I do 1.year.from_now it returns a full date, not just the year.
There are several options to do this. But using your format, we can do it like this:
1.year.from_now.year
Try these
Time.now.year + 1
output will be
2019
As suggest by #sschmeck you can try these also to get only next year
Time.now.year.succ
today's date:
require 'date'
Date.today
#=> #<Date: 2018-01-02 ...>
This day next_year:
Date.today.next_year
#=> #<Date: 2019-01-02 ...>
And finally its year:
Date.today.next_year.year
#=> 2019
You can use this,
d = Time.now.year.next

Ruby - I need to convert string into a timestamp

I need to convert a string that represents a date to a timestamp object in Ruby.
For example:
date_string = "18-Feb-2016 09:01:04"
convert to a timestamp like so
2016-02-18 14:01:04
I need to save this to a mysql database were the column is type timestamp.
I have researched this for most of the day and can not find a solution. I know you can use Time.parse but that includes timezone and DateTime.parse().to_time includes the timezone. Since it has to be a timestamp i can not use strftime method.
I need the time to be included because it will be used for calculation purposes.
Any help would be greatly appreciated.
Thank you
TL;DR
datetime = DateTime.parse("18-Feb-2016 09:01:04").to_s(:db)
returns
"2016-02-18 09:01:04"
Here's a quick explanation...
1. Convert your string to a Date object with DateTime.parse
You can use the .parse method from the Date or DateTime class in order to parse a string. The parse method will return a Date object like this:
$ DateTime.parse("18-Feb-2016 09:01:04")
$ => #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
.parse is a method provided by Ruby.
2. Format the string with DateTime.parse.to_s
Ruby on Rails gives you access to the DateTime.to_formatted_s method to change the formatting of the Date object prior to storing it in your database.
To match the format that you specified:
$ datetime = DateTime.parse("18-Feb-2016 09:01:04").to_formatted_s
Note: to_s is aliased from to_formatted_s and to_formatted_s is a method provided by Rails, not Ruby.
Use to_datetime method in Rails.
"12-10-2015".to_datetime
=> Mon, 12 Oct 2015 10:36:00 +0000
http://apidock.com/rails/String/to_datetime
Edited to add precise answer.
You can use .to_time or .to_datetime, the .to_time returns the date and time with timezone but the .to_datetime returns full date with week name but it shows +0000 as timezone, you will see the difference in both the formats, see the following example.
# used .to_time
"18-Feb-2016 09:01:04".to_time
## Output
2016-02-18 09:01:04 +0530
# used .to_datetime
"18-Feb-2016 09:01:04".to_datetime
## Output
Thu, 18 Feb 2016 09:01:04 +0000
I've interpreted the question to be that you wish to convert the string "18-Feb-2016 09:01:04" to the string "2016-02-18 14:01:04" (generalized to arbitrary date-time strings, of course).
Let:
str = "18-Feb-2016 09:01:04"
What you want is done in two steps. The first is to convert this string to a DateTime object, that is, an instance of the class DateTime. The second step is to construct the desired string from the DateTime object.
One way to create the DateTime object is to use the method DateTime::parse:
require 'date'
DateTime.parse(str)
#=> #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
That works fine for the string format you gave, but can be problematic with other formats. For example:
DateTime.parse "4-5-16 09:01:04"
#=> #<DateTime: 2004-05-16T09:01:04+00:00 ((2453142j,32464s,0n),+0s,2299161j)>
As long as you know the format that will be used, it's generally better to use DateTime#strptime with the appropriate pattern comprised of format directives:
pattern = "%d-%m-%y %H:%M:%S"
DateTime.strptime("4-5-16 09:01:04", pattern)
#=> #<DateTime: 2016-05-04T09:01:04+00:00((2457513j,32464s,0n),+0s,2299161j)>
See DateTime#strftime for the format directives.
For the problem at hand:
dt = DateTime.strptime(str, "%d-%b-%Y %H:%M:%S")
#=> #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
The second step is to construct the desired string with the above-referenced strftime method:
dt.strftime("%Y-%m-%d %H:%M:%S")
#=> "2016-02-18 09:01:04"

Date conversion in rails

I am importing data from CSV inside Rails 3.2 and saving it to mongodb collection and everything works fine except the date field. The imported date format is DD/MM/YYY. Please how can I convert the imported date to YYYY-MM-DD?
Thanks
You could use date parsing like this:
Date.strptime('01/02/2003', '%d/%m/%Y').to_s #=> "2003-02-01"
Date.strptime creates a Date object from a string in the given format
Date#to_s returns it in the ISO 8601 format (i.e. YYYY-MM-DD)
But it depends on how big your CSV is - this would create a bunch of intermediate Date objects which would be a bit slower than a (slightly ugly) string indexing approach:
def reformat_date(date)
"#{date[6..9]}-#{date[3..4]}-#{date[0..1]}"
end
reformat_date('01/02/2003') #=> "2003-02-01"
Update
I was curious so I ran some quick benchmarks - the date parsing method was about 2.7 times slower than the string method (5.289s vs 1.981s for a million conversions, Ruby 1.9.3/Windows). YMMV.
You may need
require 'date'
Then use the following statement to parse the date:
d = Date.strptime('09/10/2012', '%d/%m/%Y')
Using the following examples will return the right format:
d.year #=> 2012
d.mon #=> 10
d.day #=> 9
d.strftime('%Y/%m/%d') #=> "2012/10/09"
Then save it to the database. I'm not familiar with mongodb, though, but I'm sure you know what to do.
For more information on date parsing you should visit http://www.ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/DateTime.html.

Ruby Regex extract parameters

I have a date in this format
11/28/2011 2:39:00 PM
I cant seem to get a way to extract to each element out of this format (like take out day, month, year, hour, minute, second, AM/PM) separately to work with them. I need help here, so i can use this to rearrange the time manually and work with it how i want. I cant find a solution for this. (but im pretty sure i would need to use regex)
require 'date'
str = '11/28/2011 2:39:00 PM'
date = DateTime.strptime(str, '%m/%d/%Y %I:%M:%S %p')
puts date.year # etc
Though I'm sure regex isn't the best way to do it, here are some regex's that I tested on rubular.com!
Month:
(\d){2}(?=\/\d\d\/)
Day:
(\d){2}(?=\/\d\d\d\d)
Year:
(\d){4}(?=\s)
Hour:
(\d){1,2}(?=:\d\d:\d\d\s)
Minute:
(\d){2}(?=:\d\d\s)
Second:
(\d){2}(?=\s\w\w\b)
AM/PM:
\b[PA]M\b
I've found it easiest to use the Chronic gem to do this kind of parsing. Chronic handles these a lot better than the default DateTime stuff:
gem install chronic
And then:
require 'chronic'
date = Chronic.parse(my_date)
puts "year, month, day, hour: #{date.year}, #{date.month}, #{date.day}, #{date.hour}"
Etc.
You don't have to parse it with regular expression, you can simply convert into DateTime:
require 'date'
my_time = DateTime.parse('11/28/2011 2:39:00 PM')
puts my_time.day # and so on
You can use DateTime.strptime http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/DateTime.html#method-c-strptime to create a DateTime object and use that.
You can use this naive regex:
/(\d+)/(\d+)/(\d+)\s(\d+):(\d+):(\d+)\s(\w+)/
If your format never changes, ever, at all...

Resources