Ruby 关于时间处理的代码,求指导**怎么都不屑一顾啊~**

lionzixuanyuan · 2012年12月07日 · 最后由 AlphaLiu 回复于 2012年12月07日 · 3546 次阅读

下面的代码是关于一些时间处理的,感觉判断写的好挫啊,能不能改得漂亮点? 本人新手,勿喷啊~求指导

if self.start_time == nil
  s_time = Time.now
  s_hour = s_time.strftime('%H').to_i
  s_minute = s_time.strftime('%M').to_i
  if ((s_hour == 11 && s_minute >= 30) || s_hour > 11) && ((s_hour == 13 && s_minute == 0) || s_hour < 13)
    puts "11:30-13:00"
    self.start_time = Time.mktime(s_time.strftime('%Y'),s_time.strftime('%m'),s_time.strftime('%d'),13)
  elsif ((s_hour == 17&& s_minute >= 30) || s_hour > 17) && ((s_hour == 18 && s_minute <= 30) || s_hour < 18)
    puts "17:30-18:30"
    self.start_time = Time.mktime(s_time.strftime('%Y'),s_time.strftime('%m'),s_time.strftime('%d'),18,30)
  elsif ((s_hour == 21 && s_minute >= 30) || s_hour > 21) || ((s_hour == 8 && s_minute <= 30) || s_hour < 8)
    if (s_hour == 21 && s_minute >= 30) || s_hour > 21
      day = s_time.strftime('%d').to_i + 1
    else
      day = s_time.strftime('%d')
    end
    puts "21:30-08:30"
    self.start_time = Time.mktime(s_time.strftime('%Y'),s_time.strftime('%m'),day,8,30)
  else
    puts "工作时段"
    self.start_time = s_time
  end
end
#开始时间处理,当处于休息时间段时,将开始时间设置为该时间段的结束时间```
共收到 16 条回复

Time.now.hour就可以直接获取小时吧

#1楼 @woaigithub 光有小时不够啊,也要判断分钟啊

#1楼 @woaigithub 你的意思是这两行代码可以写优美点? s_hour = s_time.strftime('%H').to_i改成s_hour = s_time.hour s_minute = s_time.strftime('%M').to_i改成s_minute = s_time.minute 那你对判断的方法有没有好的意见啊?

尝试写了一下

# encoding: utf-8
require 'active_support/core_ext'

class Whatever 

  attr_accessor :start_time

  def update_start_time
    self.start_time ||= start_of(DateTime.current)[:end]
  end

  def start_of(t=DateTime.current)

    groups = [{
      desc:  '11:30-13:00',
      start: t.change(hour:11, min:30, sec:0),
      end:   t.change(hour:13, min:0, sec:0)
    },{
      desc:  '17:30-18:30',
      start: t.change(hour:17, min:30, sec:0),
      end:   t.change(hour:18, min:30, sec:0)
    }, {
      desc:  '21:30-08:30',
      start: t.change(hour:21, min:30, sec:0),
      end:   t.change(hour:8, min:30, sec:0).tomorrow
    }, {
      desc:  '21:30-08:30',
      start: t.beginning_of_day,
      end:   t.change(hour:8, min:30, sec:0)
    }]

    grp = groups.find do |grp|
      t >= grp[:start] && t < grp[:end]
    end

    grp ||= { desc: '工作时段', start: t, end: t }

  end

end

if __FILE__ == $0
  require 'test/unit'

  Time.current..Time.current

  class StartTimeTest < Test::Unit::TestCase

    def setup
      @obj = Whatever.new
    end

    def test_groups
      assert_equal '11:30-13:00', @obj.start_of(today(hour: 11, min:40))[:desc]
      assert_equal '17:30-18:30', @obj.start_of(today(hour: 17, min:40))[:desc]
      assert_equal '21:30-08:30', @obj.start_of(today(hour: 21, min:40))[:desc]
      assert_equal '21:30-08:30', @obj.start_of(today(hour: 04, min:40))[:desc]
    end

    def test_edge
      assert_equal '11:30-13:00', @obj.start_of(today(hour: 11, min:30, sec:0))[:desc]
      assert_equal '工作时段', @obj.start_of(today(hour: 13, min:0, sec:0))[:desc]
    end

    def test_normal
      assert_equal '工作时段', @obj.start_of(today(hour: 14, min:0, sec:0))[:desc]
      assert_equal '工作时段', @obj.start_of(today(hour: 19, min:0, sec:0))[:desc]
    end

    private
    def today(opt)
      DateTime.current.change(opt)
    end
  end
end

想法是:

  1. 尽量少写if, 把需求(时间段)用数据结构表达
  2. 这里的逻辑适合用单元测试
6楼 已删除

提问要把意图描述清楚。

#5楼 @qhwa 不错的思路

if少一些,看着舒服一些,维护更舒服一些

#5楼 @qhwa 写法好高级啊,学习了

#7楼 @Rei 额,下次一定注意

随手写了一个, 大概意思是你想要的

class ExerciseTime
  def contains?(time)
    (time.beginning_of_day..time.beginning_of_day + 8.hours).cover?(time)
  end 

  def say 
    "00:00 - 08:00"
  end 
end

class WorkTime
  def contains?(time)
    ((time.beginning_of_day + 8.hours)..(time.beginning_of_day + 17.hours)).cover?(time)
  end 

  def say 
    "08:00 - 17:00"
  end 
end

class FamilyTime
  def contains?(time)
    ((time.beginning_of_day+17.hours)..(time.end_of_day)).cover?(time)
  end 

  def say 
    "17:00 - 24:00"
  end 
end


[ExerciseTime.new, WorkTime.new, FamilyTime.new].select {|period| period.contains?(Time.now)}.say

你在给每个加个 start_time 就行了

#13楼 @knwang 拆分,太好了,好好消化消化。

#13楼 @knwang 感觉更高级了,我要去翻翻书再来看你给指导的代码了

#12楼 @knwang 这段代码不错啊。学习了! 不过 time.beginning_of_day 需要 require 'active_support/core_ext' 。 当然 在 rails 里面就不用了..

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册