How to check time left until a specific date? - ruby

How do I check how many days left until a specific date?
For example, I want to start executing some logic after 3 days from today? I will be hard coding today's date, and subtract now from it, but how?
EDIT
What I want to do is to disable devise confirmation email at model for the next three days,
if Rails.env== 'production' && (three days left sense 1/7/2013)
devise :confirmable
end

why bother?
if Rails.env== 'production' && Time.now.strftime("%Y%m%d").to_i >= 20130110
devise :confirmable
end

If im getting it right ,
you just store the start time in a variable
then check it against the current time (you'll get the diff in seconds )
and if its larger then 72(3 days) the if statement will be done.
require 'time'
start_time=Time.now
if Rails.env== 'production' && ( (Time.new - start_time)/3600 >72 )
devise :confirmable
end

Use the time_diff gem to get the difference in terms of year, month, week, day, hour, minute and second that can be easily achieved as I did so.
Check this -
Rails calculate time difference
You will get your answer there.

in your class first you have to set date
e.g:
in your case you need to do something like this:
("object name".date.to_time<=time.now+3)
(do something)if x.date.to_time<=today
the technique to_time make`s you able to choose time (day,weeks,month,year)
ENV.all.each do|env|
where (env.date.to_time<= Time.now+3)
if Rails.env== 'production' && (env.date.to_time== today)
devise :confirmable
end

try
if Time.now >= <your_time_object> + 3.days
# start executing some logic
end

Related

cucumber capybara testing date picker selects wrong day

I am trying to write a cucumber test for a page that includes a datepicker. I swear this was working yesterday, but not so much today.
Then(/^select date (\d+) day(?:s|) prior to today$/) do |n|
day=Date.today-(n.to_i)
target = Date.strptime("#{day}",'%Y-%m-%d')
target_month_year = target.strftime('%B %Y')
selected_month_year = (find('.datepicker-switch').native.text)
unless target_month_year == selected_month_year
find('.prev').click
sleep 1
end
find('.day', :text => "#{day.day}", match: :prefer_exact).click
sleep 2
end
Then I have a separate test that checks that the correct date is presented after selection. I have verified that day.day is giving me the correct result by including a puts(day.day), as well as all the other variables. I think the problem is a matching issue, today's date is 04/24/2015 and I selecting 15 days prior. So the datepicker that displays the month and year above and allows you to select previous or next, then the days shown are according to how many days in that particular month. and a few day before and after. the days for the previous month are class="old day" and the ones for the month displayed are class="day" and for the next month class="new day". so the month I want is april and the day is the ninth. it keeps selecting the 29th of march. which is the first day listed on the page that contains a "9". but the class is wrong, since I want "day" not "old day" and the day is wrong because I want "9" not "29" I even put in a :prefer_exact because that has fixed matching the wrong element in the past for me.
Not sure what to try next. Any advice greatly appreciated.
cucumber 1.3.10
capybara 2.4.1
ruby 1.9.3p551
Ideally, don't select by text if you can avoid it.
But in this case try using a regex instead of just plain text.
find('.day', :text => Regexp.new("^#{day.day}$"), match: :prefer_exact).click
There's a little related reading at the end of this (currently unimplemented) issue: https://github.com/jnicklas/capybara/issues/1256

How do I get a file's age in days in Ruby?

How would I get the age of a file in days in Ruby?
NOTE that I need a way to accurately get the age of a given file; this means that leap years need to be taken into account.
I need this for a program that removes files after they reach a certain age in days, such as files that are 20 days or older.
And by age, I mean the last access time of a given file, so if a file hasn't been accessed in the past 20 days or more, it gets deleted.
In Perl, I know that you can use date::calc to calculate a date in terms of days since 1 AD, and I used to have a Common-Lisp program that used the Common-Lisp implementation of date::calc, but I don't have that anymore, so I've been looking for an alternative and Ruby seems to have the required capability.
path = '/path/to/file'
(Time.now - File.stat(path).mtime).to_i / 86400.0
#=> 1.001232
Here is the implementation of my above comment, it returns a floating point number expressing the number of days passed.
I know it is an old question, but I needed the same and came up with this solution that might be helpful for others.
As the difference is in days, there is not need to directly deal with seconds.
require 'date'
age_in_days = (Date.today - File.mtime(path).to_date).to_i
if age_in_days > 20
# delete logs
end
If using Rails, you can take advantage of ActiveSupport:
if File.mtime(path) < 20.days.ago
# delete logs
end
If you aren't using Rails, Eduardo's solution above would be my pick.

Time manipulation in ruby

I want to create a DateTime instance that lies 20 minutes and 10 seconds in the future.
I tried around with Time and DateTime in irb, but can't seem to figure out a way that really makes sense. I can only add days to DateTime objects and only add seconds to the Time objects.
Isn't there a better way than to always convert the time I want to add into seconds?
A Time is a number of seconds since an epoch whereas a DateTime is a number of days since an epoch which is why adding 1 to a DateTime adds a whole day. You can however add fractions of a day, for example
d = DateTime.now
d + Rational(10, 86400)
Will add 10 seconds to d (since there are 86400 seconds in a day).
If you are using Rails, Active Support adds some helper methods and you can do
d + 20.minutes + 10.seconds
Which will do the right thing is d is a DateTime or a Time. You can use Active Support on its own, and these days you can pull in just the bits you need. I seem to recall that this stuff is in activesupport/duration. I believe there are a few other gems that offer help with time handling too.
Assuming you have required Active Support or you're working in a Rails project. A very simple and readable way to do this in Ruby is:
DateTime + 5.minutes
Time + 5.minutes
Also works with seconds, hours, days, weeks, months, years.
Just use the Active Support Time extensions. They are very convenient and less error prone than trying to do this by hand. You can import just the module you need:
# gem 'activesupport'
require 'active_support/core_ext/numeric/time.rb'
DateTime.now + 20.minutes
N.B: Yes, this goes against the StackOverflow party line of staying away from 3rd party libraries, but you shouldn't avoid using libraries when they are practically standard, reduce your risk significantly, and provide better code clarity.
Pure Ruby (no Rails)
class Numeric
def minutes; self/1440.0 end
alias :minute :minutes
def seconds; self/86400.0 end
alias :second :seconds
end
Where 1440 is the number of minutes and 86400 is the number of seconds in a day.
Based on how Rails does.
Then you can just let the magic happen:
d + 20.minutes + 10.seconds
Source: https://github.com/rails/rails/blob/v6.0.3.1/activesupport/lib/active_support/core_ext/numeric/time.rb
As noted above, you can add seconds to a Time object, so if you call to_time on a DateTime object, you can add seconds to it:
DateTime.strptime("11/19/2019 18:50","%m/%d/%Y %H:%M") + 1 => adds a day
(DateTime.strptime("11/19/2019 18:50","%m/%d/%Y %H:%M").to_time) +1 => adds a second
This doesn't require adding gems.

Representing time differences in Ruby

Does Ruby stdlib have any objects that represent difference between two timestamps? Subtracting two Time object from each other returns a float number of seconds - is there any object for that, with methods like hours, minutes etc., and most of all decent to_s?
I've coded half-assed methods for that far too many time, am I doing it wrong?
Not in the stdlib, but there is a Gem that you can use for the job - the duration gem.
sudo gem install duration
Which you can use like this:
require "duration"
a = Time.now
sleep(5)
b = Time.now
duration = Duration.new(b - a)
# => #<Duration: 5 seconds>
duration.seconds
# => 5
duration.minutes
# => 0
And days, hours, weeks and a bunch of other useful methods.
You can also then monkey-patch Time, Date and other date-time classes to return Duration objects.
perhaps duration does help? Here is an announcement for it.
There is a gem called time_diff which return a hash of difference in year, month, week, day, hour, minute, second

What's the most efficient way get the first day of the current month?

With ruby I'm trying to get format a date as such: 2009-10-01
Where I take the current date (2009-10-26) and then change the day to "01".
I know of ways to do this, but was curious what the shortest way is, code wise, to pull this off.
If you don't mind including ActiveSupport in your application, you can simply do this:
require 'active_support'
date = Date.today.beginning_of_month
Time.parse("2009-10-26").strftime("%Y-%m-01")
require 'date'
now = Date.today
Date.new(now.year, now.month, 1)
Most efficient to get start and end date of current month
#date = DateTime.now
#date.beginning_of_month
#date.end_of_month
If you need the date object without ActiveSupport, you can go back to the last day of the last month and sum 1.
Date.today - Date.today.mday + 1
Like
Date.today.beginning_of_day
Date.today.end_of_day
And
Date.today.beginning_of_week
Date.today.end_of_week
There also is
Date.today.beginning_of_year
Date.today.end_of_year
This works...
Not terribly clever :/
require 'date'
Date.parse(Date.parse("2009-10-26").to_s[0,8] << "01")
require 'active_support/core_ext'
Date.today.beginning_of_month

Resources