红宝石日期差异整合

时间:2017-05-01 03:19:17

标签: ruby ruby-on-rails-4 rubygems

我正在开展一个项目,我必须计算员工之前的总体经费。所以,让我们说一名员工工作

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

我希望能够对这三行的日期进行差异,这将使我在开始日期和结束日期中有所不同,然后将这三个日期加在一起以获得总工作天数。但我遇到的问题是我希望能够显示类似

的总体验

7年,3个月和14天。在时间差异的文字格式。

关于如何实现这一目标的任何想法。

由于

1 个答案:

答案 0 :(得分:1)

这是一个纯粹的Ruby答案。

<强>代码

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

示例

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

<强>解释

请参阅Date::strptime和(日期格式代码)DateTime#strftime

步骤如下。

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"] 

块变量tot设置为reduce的参数(0),生成a的第一个元素并传递给块,成为块变量str的值:

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

现在执行块计算

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)>]

在计算d时,传递给块的c的第一个元素是

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

并且该字符串的块计算是

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

继续,

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是该人在第一份工作中工作的天数。最后一个值是块变量tot的新值,即到目前为止处理的所有作业的累计工作天数。