Posted over 10 years ago by Philip Ingram
This will be a quick one.
If a client of yours signed up for your service on jan 30th, and you bill monthly, there are a couple ways you can handle the dreaded ‘end of February’ problem you could find yourself in.
I use two billing dates in my Model that handles the, well, billing dates for a shop.
The following code seems to be the most concise way I’ve found to handle both leap years and Feb. 28th.
billing_date = shop.shop_billing_date #Is today the end of Feb? or a leap year? if Date.today == Date.new(Date.today.year, 2, 28) || Date.today.leap? && Date.today == Date.new(Date.today.year, 2, 29) #if it is update the next_billing_date by creating a new Date object #using a database column that has just the actual numerical Date of the month they should be charged on. billing_date.update_attributes(:last_billing_date => Date.today, :next_billing_date => Date.new(Date.today.year, 3, billing_date.bill_day)) else #Else, just bill them and update the normal way that the next billing date is next month at this time. billing_date.update_attributes(:last_billing_date => Date.today, :next_billing_date => Date.today >> 1) end
Again, i use a last_billing_date column and a next_billing_date. Just in case something happens, i also store a bill_day in the database which is the Day of the Created_at.
The first line just checks for today’s date and makes sure it is one of the two end of Feb dates. If it is, it will update the next billing date with the correct Day for March, by adding the bill_date to the Date.new object it is creating.
If it isn’t the end of Feb, then it just uses today’s date.
Note: I run this every day, so that is why I am using Date.today, although i may change it to bill date, just incase i change the formula to catch ‘past due’ shops…. Even in the middle of a blog post, you can always learn, eh!