get one month ago but always 15th of month - ruby-on-rails

I need to get the month before today, but always to get the date with 15th.
i.e if today is March 11th 2014, I need => Feb 15th 2014.
or if the date is March 28th 2014, I need => Feb 15th 2014.
How can I achieve that?

Since you're using rails:
(DateTime.now - 1.month).beginning_of_month + 14.days
Refer to the DateTime documentation for more info.
Edit: Updated to reflect the previous month's 15th day.

(Date.today - 1.month).beginning_of_month + 14
or another way
(Date.today - 1.month).change(day: 15)

You can just create a new date object with last month's year and month numbers and 15 as the day:
today = Date.today
one_month_ago = (today - 1.month)
Date.civil(one_month_ago.year, one_month_ago.month, 15)

Do it like this:
Date.today.prev_month.beginning_of_month + 14 # => Sat, 15 Feb 2014

Use
(Date.today<<1).beginning_of_month + 14 ## => Sat, 15 Feb 2014
Or
Date.today.last_month.beginning_of_month + 14 ## => Sat, 15 Feb 2014

Related

How to get the date of "this Wednesday", "this Thursday" etc. in Rails

I know that Rails has an elegant way of getting dates for a certain day of the week for next week, or for last week (docs).
today = Time.zone.today
=> Fri, 24 Jan 2020
today.next_week
=> Mon, 27 Jan 2020 # Gets Monday by default
today.next_week(:thursday)
=> Thu, 30 Jan 2020 # You can get a certain day of the week by passing it in as an argument
Is there a way to do the same for this week? For example, getting the date of this Thursday, Friday, etc.? Right now, my workaround is to get the date of beginning_of_week (Monday) and calculate from there. Ideally, I wanted to do something similar to above, like Time.zone.today.this_week(:thursday).
this_monday = Time.zone.today.beginning_of_week
=> Mon, 20 Jan 2020
this_friday = this_monday.since(4.days).to_date
=> Fri, 24 Jan 2020
You could use #next_occurring
pry(main)> Time.zone.today.beginning_of_week
Mon, 20 Jan 2020
pry(main)> Time.zone.today.beginning_of_week.next_occurring(:thursday)
Thu, 23 Jan 2020

Why does adding and subtracting 2 months to a date not give back the same date?

I'm a bit confused about this outcome, taking today's date minus 2 months, and then taking that date again and adding two months, does not give me today's date when assign the dates to a variable.
Time.zone
"Eastern Time (US & Canada)"
> today = Date.today.in_time_zone
=> Thu, 31 Aug 2017 00:00:00 EDT -04:00
> a = today - 2.months # This is persisted to the db
=> Fri, 30 Jun 2017 00:00:00 EDT -04:00
> b = a + 2.months
=> Wed, 30 Aug 2017 00:00:00 EDT -04:00
If I however, just use the same object, it moves back and forth properly:
> today = Date.today.in_time_zone
=> Thu, 31 Aug 2017 00:00:00 EDT -04:00
> today - 2.months
=> Fri, 30 Jun 2017 00:00:00 EDT -04:00
> today + 2.months
=> Tue, 31 Oct 2017 00:00:00 EDT -04:00
The problem is obviously when "a" gets saved to a database, and then retrieved later on, and calculated plus 2 months..., it should match today's date.
TL;DR
A month is not a fixed duration. Adding or taking a month does not give the same "time shift" depending on which day you are.
The usual algorithm
to add or take months is the following :
try to land on the same day number (4th, 30th, 31st) as you started, just by changing the month
if you would land on an impossible date (like 31th September, 30th February, 29th February for some years) then just go the maximum allowed day number of this month
This implies that adding some months then taking out the same number of months will not necessarily give you back the same date.
Examples :
31st of some month + 1 month --> One would want to get to the 31th of next month
But if there is no 31st of next month (like for 31th of August, no 31st of September), then what to do ?
Usual interpretation would say that you want to go to the end of the month, this is 30th September (for rent or other monthly subscription, for instance)
But usually, 30th of some month - 1 month --> One would want to get to the 30th of the previous month.
That would lead to .... 30th of August. Not 31th of August.
Hence: some date + 1 month - 1 month does not necessarily give the original date !
Another example :
Start at the 30th of August.
Take a month -> 30th of July
Add a month -> You want to get to 30th of August (same number, next month) or to the end of August ?
The default algorithm will try to give the same day number -> 30th of August (which is more logical now)
Also with days...
Note that the same problem happens with days,but much less often ! When some days don't have the same number of hours, for daylight saving days, when adding and taking same number of days you might not get back to the original date and time as you started from.

How to get time x days ago from a specific date in Rails?

I am looking for a rails solution to calculate the time ago from a particulat time. For example , 2 days ago 15th May 2016 22:00 UTC should return 13th May 2016 22::00 UTC .
My requirement is something like this
2.days.ago.from(yesterday)
Which will be a more specific version of
2.days.from_now
Try this:
> DateTime.now-2.days
=> Wed, 18 May 2016 21:40:31 -0700
how about this:
# 2 days before a specific date
specific_date.days_ago(2)
Example:
specific_date = DateTime.now
two_days_ago_from_specific_date = specific_date.days_ago(2)
My personal favorite syntax for this with rails would be
x.days.ago
For example, if you wanted 10 days ago you would call
10.days.ago
=> Sat, 12 Feb 2022 01:36:58 UTC +00:00
Easy to read and defaults to UTC.
example:
Time.now.ago(10.year)
Time.now.ago(1.minutes)
Time.now.ago(10.day)

Traverse through a certain month in Date with just a given integer

Would it be possible to go to a certain month of the year with just a given integer. For example
date = Date.today
=> Wed, 30 Dec 2015
What if I want to go back to a certain month based on that date and I am just given a number let's say 7 which is July in the Date::MONTHNAMES so would it be possible to do something like
date = Date.today
=> Wed, 30 Dec 2015
date.go_to_month_of(7) # which will bring me back to July 30, 2015
Okay I found it. It's:
date = Date.today
date.change(:month => x)
Hope this helps you!

Rails, day of year to date

I have day of the year. For example 15th day of 2014, or 210th day of 2014. I need to get the Date on the particular day. Is there any library function in Rails/Ruby that I can use, or any other elegant way?
Something like:
15th day of 2014 = 15-Jan-2014
210th day of 2014 = 29-Jul-2014
You can use Date.ordinal for that:
require 'date'
Date.ordinal(2014, 210)
# => #<Date: 2014-07-29 ((2456868j,0s,0n),+0s,2299161j)>
Date.new(2014, 1, 1) + 210
=> Wed, 30 Jul 2014
Edit - you'd need to subtract 1 day. I prefer #wonderb0lt's suggestion.

Resources