-1

I am working on a project where I have to calculate the total previous expereince of an employee. So lets say an employee worked

Company 1 - 11th Feb 2008 to 23rd Feb 2010
Company 2 - 14 May 2010 to 17 Oct 2014
Company 3 - 22 Dec 2014 to 14 Jan 2017

I want to be able to Diff the dates for these three rows that will give me the difference in start and end dates in days, then add the three together to get the total number of days worked. But the problem I am running into is that I want to be able to show the total experience something like

7 years, 3 months and 14 days. In the Difference of time in words kind of format.

Any ideas on how this can be achieved.

Thanks

deepinder
  • 131
  • 2
  • 8
  • Hint: [`Date.parse`](http://stackoverflow.com/questions/17563048/parse-a-date-in-rails) can handle those date formats as-is. – tadman May 01 '17 at 04:00
  • Your question isn't a good fit for Stack Overflow. Where did you search, and what did you find and why didn't that help? Did you write code? If not, why? If so, where is the minimum code that demonstrates a specific problem you encountered? Please read "[ask]" and "[How much research effort is expected of Stack Overflow users?](http://meta.stackoverflow.com/questions/261592)" – the Tin Man May 01 '17 at 20:12

1 Answers1

1

Here is a pure-Ruby answer.

Code

require 'date'

R1 = /
     \s*-\s*   # match a hypen optionally surrounded by whitespace
     |         # or
     \s*to\s*  # match 'to' optionally surrounded by whitespace
     /x        # free-spacing regex definition mode

R2 = /st|nd|rd|th # match one of the four pairs of letters
     /x

def total_days(data)    
  data.lines.reduce(0) do |tot, str|
    start_date, end_date = str.
      chomp.
      split(R1).
      drop(1).
      map { |s| Date.strptime(s.sub(R2, ''), '%d %b %Y') }
    tot + (end_date - start_date).to_i
  end
end

Example

data =<<-_
Company 1 - 11th Feb 2008 to 23rd Feb 2010
Company 2 - 14 May 2010 to 17 Oct 2014
Company 3 - 22 Dec 2014 to 14 Jan 2017
_

total_days(data)
  #=> 3114

Explanation

See Date::strptime and (for date format codes) DateTime#strftime.

The steps are as follows.

a = data.lines
  #=> ["Company 1 - 11th Feb 2008 to 23rd Feb 2010\n",
  #    "Company 2 - 14 May 2010 to 17 Oct 2014\n",
  #    "Company 3 - 22 Dec 2014 to 14 Jan 2017\n"] 

The block variable tot is set to reduce's argument (0) and the first element of a is generated and passed to the block, becoming the value of the block variable str:

tot = 0
str = a.first
  #=> "Company 1 - 11th Feb 2008 to 23rd Feb 2010\n"

The block calculation is now performed

a = str.chomp
  #=> "Company 1 - 11th Feb 2008 to 23rd Feb 2010" 
b = a.split(R1)
  #=> ["Company 1", "11th Feb 2008", "23rd Feb 2010"] 
c = b.drop(1)
  #=> ["11th Feb 2008", "23rd Feb 2010"] 
d = c.map { |s| Date.strptime(s.sub(R2, ''), '%d %b %Y') }
  #=> [#<Date: 2008-02-11 ((2454508j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2010-02-23 ((2455251j,0s,0n),+0s,2299161j)>]

In calculating d, the first element of c passed to the block is

s = c.first
  # => "11th Feb 2008"

and the block calculation for that string is

g = s.sub(R2, '')
  #=> "11 Feb 2008" 
Date.strptime(g, '%d %b %Y')
  #=> #<Date: 2008-02-11 ((2454508j,0s,0n),+0s,2299161j)> 

Continuing,

start_date, end_date = d
  #=> [#<Date: 2008-02-11 ((2454508j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2010-02-23 ((2455251j,0s,0n),+0s,2299161j)>] 
start_date 
  #=> #<Date: 2008-02-11 ((2454508j,0s,0n),+0s,2299161j)> 
end_date
  #=> #<Date: 2010-02-23 ((2455251j,0s,0n),+0s,2299161j)> 
e = end_date - start_date
  #=> (743/1) <rational> 
f = e.to_i
  #=> 743 
tot + 743
  #=> 743

f is number of days the person worked in the first job. The last value is the new value of the block variable tot, the cumulative number of days worked in all jobs processed so far.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100