Playing With Time in Ruby and Javascript

The final project for module 2 at Turing was building an e-commerce app in Rails. My group took it one step further and built a rental site, which of course required tracking reservations, due dates, availability, etc. As our app is a Rails App, most of the date logic is written in Ruby, but when visiting the cart, the total price of the cart updates dynamically based on selected reservation dates, which is done using JavaScript and JQuery — so I had some fun teaching myself about time in JavaScript as well, and note some differences here.

This actually applies to things other than time, but I found it’s first application here. When checking to see if an item in our shop was reserved on a date another customer was trying to make a reservation, we looked at all the other reservations already connected to that item, and checked whether the proposed new reservation’s start date was included in any of them. This required the === operator, which I’d never used in Ruby before — it checks inclusion within a range. Here’s how it looks in pry, and how we applied it:

def range 
  start_date.to_datetime..end_date.to_datetime 
end 

def self.reserved?(order) 
  any? { |existing_order| existing_order.range === order.start_date } 
end

When users request the start and end dates for their reservation, they are returned as strings that look something like “10 March, 2016”, which is not useful in creating Time objects. Fortunately, Ruby has a built in module that will convert date strings into their index, which can then be used to create Time objects. Here’s how:

Date::MONTHNAMES.index("November") 
  # => 11 
Date::MONTHNAMES[11] 
  # => "November" 
Date::ABBR_MONTHNAMES.index("Nov") 
  # => 11 
Date::ABBR_MONTHNAMES[11] 
  # => "Nov"

A similar module exists for DAYNAMES also. Days are zero-indexed (Sunday is 0), while months follow the more traditional Western month format, where their index is the number of the month as we use them in dates (i.e. March is 3).

Javascript note: Unlike in Ruby, months are zero-indexed in Javascript (January is 0, etc.). This is confusing after being so used to the index of months, but as everything in programming is zero-indexed, it does have the benefit of consistency.

In order to know the length of a reservation, we subtracted the start date from the end date. In Ruby, this returns a fraction like 10/1 for a 10-day reservation. JavaScript, on the other hand, returns the difference in milliseconds. In order to get the number of days, we did this joyful bit of math: returnValue / 24 / 60 / 60 / 1000 to get the number of days.

All in all, I didn’t find time as daunting as I thought I might. Both Ruby and JavaScript have time objects that do most of the heavy lifting for you, as long as you make sure to create them as you need them from the get-go. That being said, I didn’t have to worry about time zones or other things that complicate the matter, and the stakes of getting it wrong were quite low.