For demonstration purposes: say I am including in the module TodayDynamicDate into the model Foo below:
# app/models/concerns/today_dynamic_date.rb
module TodayDynamicDate
extend ActiveSupport::Concern
def todays_date
Date.today
end
end
#app/models/foo.rb
class Foo < ApplicationRecord
include TodayDynamicDate
end
I am wondering if using that mixed in method of #todays_date will work how I want it to.
I want the method #todays_date to dynamically return the date that the method was run. I do not want it to return the static date that the rails server was booted up.
Example:
Say I boot up the server today, Friday, July 1st, 2016. Here is what I expect the method to return today:
Foo.new.todays_date
=> Fri, 01, Jul 2016
The server continues running and it is now Tuesday, July 5th, 2016. That same method is called in the app and here is what I expect it to return:
# dynamically returning the date that the method was called
Foo.new.todays_date
=> Tues, 05, July 2016
I want to ensure that it will not return this:
# returning a static date
Foo.new.todays_date
=> Fri, 01, Jul 2016
Question: Will my implementation return a dynamic date? If it will not return a dynamic date: how would I do that with that mixed-in method todays_date?
Answer is yes. Each call to Date.today will return current date.
todays_date is not a class (what you are referring as static) variable, its a method.
I have an alarm clock app, I want when the user enter's "5:00 PM", the system store it as datetime.
How do I convert '5:00 pm' to a datetime.
If it is already past 5:00 pm and the user enters '5:00 pm', the system should assume the user means tomorrow's '5:00 pm' and return the appropriate datetime.
Thanks to a previous answer, I figure out.
time_string = '5:00 pm' # mock of user input
date_time = DateTime.parse time_string
date_time += 1.day if Time.now > date_time
return date_time
I am trying to create an object which has both a date field and a time field. I'd like the time field to be generated based on the date in the date field. For example:
SampleObject.new(
date = Date.today #Sat, 28 Dec 2013
time = Date.today.at(5:00pm EST) #Sat, 28 Dec 2013 2013-12-28 17:00:00 -0500 Not valid ruby syntax)
)
How can I make time = line work as intended?
I'd do something like:
DateTime.parse Date.today.to_s + ' 5pm'
#<DateTime: 2013-12-28T17:00:00+00:00 ((2456655j,61200s,0n),+0s,2299161j)>
I am interpreting this question as "a way to set the time of the day on a given date to a given time".
One way you could do it is as follows:
def set_date_and_time(date = Date.today, time = Time.now)
this_day = [date.year, date.month, date.day]
this_time = [time.hour, time.min, time.sec]
Time.new(*this_day, *this_time)
end
Hope this helps.
How do I get DateTime to parse a custom date format(i.e. 'x-%Y')?
I've set the format within an initializer with (as per the RoR API):
Time::DATE_FORMATS[:x_year] = 'x-%Y'
Date::DATE_FORMATS[:x_year] = 'x-%Y'
and when I call:
DateTime.strptime('x-2011', 'x-%Y')
The correct result is returned, but
DateTime.parse('x-2011')
Throws an
ArgumentError: invalid date
never heard of such a possibility. However, you could still do something like:
class DateTime
class << self
alias orig_parse parse
end
def self.parse(string, format = nil)
return DateTime.orig_parse(string) unless format
DateTime.strptime(string, Date::DATE_FORMATS[format])
end
end
in your example it might look like that:
Date::DATE_FORMATS.merge!({:xform => "x-%Y"})
DateTime.parse('x-2011', :xform) #=> Sat, 01 Jan 2011 00:00:00 +0000
You could get rid of 'format' attribute and iterate && validate/rescue through DATE_FORMATS instead
What is the best way to generate a random DateTime in Ruby/Rails? Trying to create a nice seeds.rb file. Going to use it like so:
Foo.create(name: Faker::Lorem.words, description: Faker::Lorem.sentence, start_date: Random.date)
Here is how to create a date in the last 10 years:
rand(10.years).ago
You can also get a date in the future:
rand(10.years).from_now
Update – Rails 4.1+
Rails 4.1 has deprecated the implicit conversion from Numeric => seconds when you call .ago, which the above code depends on. See Rails PR #12389 for more information about this. To avoid a deprecation warning in Rails 4.1 you need to do an explicit conversion to seconds, like so:
rand(10.years).seconds.ago
Here are set of methods for generating a random integer, amount, time/datetime within a range.
def rand_int(from, to)
rand_in_range(from, to).to_i
end
def rand_price(from, to)
rand_in_range(from, to).round(2)
end
def rand_time(from, to=Time.now)
Time.at(rand_in_range(from.to_f, to.to_f))
end
def rand_in_range(from, to)
rand * (to - from) + from
end
Now you can make the following calls.
rand_int(60, 75)
# => 61
rand_price(10, 100)
# => 43.84
rand_time(2.days.ago)
# => Mon Mar 08 21:11:56 -0800 2010
I prefer use (1..500).to_a.rand.days.ago
You are using Faker; why not use one of the methods provided by Faker::Date?
# Random date between dates
# Keyword arguments: from, to
Faker::Date.between(from: 2.days.ago, to: Date.today) #=> "Wed, 24 Sep 2014"
# Random date between dates except for certain date
# Keyword arguments: from, to, excepted
Faker::Date.between_except(from: 1.year.ago, to: 1.year.from_now, excepted: Date.today) #=> "Wed, 24 Sep 2014"
# Random date in the future (up to maximum of N days)
# Keyword arguments: days
Faker::Date.forward(days: 23) # => "Fri, 03 Oct 2014"
# Random date in the past (up to maximum of N days)
# Keyword arguments: days
Faker::Date.backward(days: 14) #=> "Fri, 19 Sep 2014"
# Random birthday date (maximum age between 18 and 65)
# Keyword arguments: min_age, max_age
Faker::Date.birthday(min_age: 18, max_age: 65) #=> "Mar, 28 Mar 1986"
# Random date in current year
Faker::Date.in_date_period #=> #<Date: 2019-09-01>
# Random date for range of year 2018 and month 2
# Keyword arguments: year, month
Faker::Date.in_date_period(year: 2018, month: 2) #=> #<Date: 2018-02-26>
# Random date for range of current year and month 2
# Keyword arguments: month
Faker::Date.in_date_period(month: 2) #=> #<Date: 2019-02-26>
current Faker version: 2.11.0
Here is how to create a date in this month:
day = 1.times.map{ 0+Random.rand(30) }.join.to_i
rand(day.days).ago
Another approach using DateTime's advance
def rand_date
# return a random date within 100 days of today in both past and future directions.
n = rand(-100..100)
Date.today.advance(days: n)
end
This is what I use:
# get random DateTime in last 3 weeks
DateTime.now - (rand * 21)
other way:
(10..20).to_a.sample.years.ago
I haven't tried this myself but you could create a random integer between two dates using the number of seconds since epoch. For example, to get a random date for the last week.
end = Time.now
start = (end - 1.week).to_i
random_date = Time.at(rand(end.to_i - start)) + start
Of course you end up with a Time object instead of a DateTime but I'm sure you can covert from here.
As I already mentioned in another question I think the following code-snippet is more consisent regarding the data-types of the parameters and of the value to be returned. Stackoverflow: How to generate a random date in Ruby?
Anyway this uses the rand() method's internal logic what is the random Date or random Time within a span. Maybe someone has a more efficient way to set the default-parameter to (Time.now.to_date) of the method random_date, so it doesn't need this typecasting.
def random_time from = Time.at(0.0), to = Time.now
rand(from..to)
end
# works quite similar to date :)
def random_date from = Date.new(1970), to = Time.now.to_date
rand(from..to)
end
Edit: this code won't work before ruby v1.9.3
You can pass Time Range to rand
rand(10.weeks.ago..1.day.ago)
Output Example:
=> Fri, 10 Jan 2020 10:28:52 WIB +07:00
Without user faker (cause I'm using an old version of ruby):
Time.zone.now - rand(16..35.years) - rand(1..31).days
My 'ish' gem provides a nice way of handling this:
# plus/minus 5 min of input date
Time.now.ish
# override that time range like this
Time.now.ish(:offset => 1.year)
https://github.com/spilliton/ish