代码之家  ›  专栏  ›  技术社区  ›  tcurdt

从时间对象获取下个月/上个月

  •  30
  • tcurdt  · 技术社区  · 14 年前

    我有时间对象,想查找下个/上个月。加减天数不起作用,因为每个月的天数不同。

    time = Time.parse('21-12-2008 10:51 UTC')
    next_month = time + 31 * 24 * 60 * 60
    

    月数的增加也会减少,因为你必须照顾滚动。

    time = Time.parse('21-12-2008 10:51 UTC')
    next_month = Time.utc(time.year, time.month+1)
    
    time = Time.parse('01-12-2008 10:51 UTC')
    previous_month = Time.utc(time.year, time.month-1)
    

    我唯一能做的就是

    time = Time.parse('21-12-2008 10:51 UTC')
    d = Date.new(time.year, time.month, time.day)
    d >>= 1
    next_month = Time.utc(d.year, d.month, d.day, time.hour, time.min, time.sec, time.usec)
    

    有没有比这更优雅的方式,我看不见? 你会怎么做?

    12 回复  |  直到 6 年前
        1
  •  10
  •   Steve Madsen    14 年前

    上没有内置方法 Time 在Ruby中做你想做的。我建议您在一个模块中编写完成这项工作的方法,并扩展 时间 类,以便在其余代码中简化它们的使用。

    你可以使用 DateTime 但是方法( << >> )它们的命名方式不足以让以前没有使用过它们的人明白它们的目的。

        2
  •  76
  •   Joshua Pinter    9 年前

    红宝石钢轨

    注:此 仅在轨道上工作 (谢谢史蒂夫!)但我将它保存在这里,以防其他人使用Rails,并希望使用这些更直观的方法。

    非常简单-谢谢你的Ruby on Rails!

    Time.now + 1.month
    
    Time.now - 1.month  
    

    或者,如果与 当前时间 (仅限3+轨)。

    1.month.from_now
    
    1.month.ago
    

    日本药典

        3
  •  21
  •   Konstantin Rudy    11 年前

    我个人更喜欢使用:

    Time.now.beginning_of_month - 1.day      # previous month
    Time.now.end_of_month + 1.day            # next month
    

    它总是有效的,并且独立于一个月的天数。

    查找更多信息 in this API doc

        4
  •  12
  •   andrykonchin    14 年前

    可以使用标准类日期时间

    require 'date'
    
    dt = Time.new().to_datetime
    => #<DateTime: 2010-04-23T22:31:39+03:00 (424277622199937/172800000,1/8,2299161)>
    
    dt2 = dt >> 1
    => #<DateTime: 2010-05-23T22:31:39+03:00 (424282806199937/172800000,1/8,2299161)>
    
    t = dt2.to_time
    => 2010-05-23 22:31:39 +0200
    
        5
  •  6
  •   Richie Min    12 年前

    下面的作品

    上个月:

    Time.now.months_since(-1)
    

    下个月:

    Time.now.months_since(1)
    
        6
  •  6
  •   gmcnaughton    9 年前

    如果您不想加载和依赖其他库,可以使用如下内容:

    module MonthRotator
      def current_month
        self.month
      end
    
      def month_away
        new_month, new_year = current_month == 12 ? [1, year+1] : [(current_month + 1), year]
        Time.local(new_year, new_month, day, hour, sec)
      end
    
      def month_ago
        new_month, new_year = current_month == 1 ? [12, year-1] : [(current_month - 1), year]
        Time.local(new_year, new_month, day, hour, sec)
      end
    end
    
    class Time
      include MonthRotator
    end
    
    
    require 'minitest/autorun'
    
    class MonthRotatorTest < MiniTest::Unit::TestCase
      describe "A month rotator Time extension" do
        it 'should return a next month' do
          next_month_date = Time.local(2010, 12).month_away
          assert_equal next_month_date.month, 1
          assert_equal next_month_date.year, 2011
        end
    
        it 'should return previous month' do
          previous_month_date = Time.local(2011, 1).month_ago
          assert_equal previous_month_date.month, 12
          assert_equal previous_month_date.year, 2010
        end
      end
    end
    
        7
  •  2
  •   Volker Schmitt    6 年前

    为了完整性,我只想添加我的纯Ruby解决方案 将strftime中的格式替换为所需的输出

    DateTime.now.prev_month.strftime("%Y-%m-%d")
    DateTime.now.next_month.strftime("%Y-%m-%d")
    
        8
  •  1
  •   MIGUEL ANGEL ALONSO PEREZ    9 年前

    您可以尝试转换为日期时间。

    时间为您提供当前日期,日期时间允许您操作。

    看看这个:

    irb(main):041:0> Time.new.strftime("%d/%m/%Y")
            => "21/05/2015"
    
    irb(main):040:0> Time.new.to_datetime.prev_month.strftime("%d/%m/%Y")
        => "21/04/2015"
    
        9
  •  1
  •   Dmitry Perfilyev    7 年前

    下面是一个不带ror的纯Ruby解决方案,适用于旧Ruby版本。

    t=Time.local(2000,"jan",1,20,15,1,0);
    curmon=t.mon;
    prevmon=(Time.local(t.year,t.mon,1,0,0,0,0)-1).mon ;
    puts "#{curmon} #{prevmon}"
    
        10
  •  0
  •   Krishna Vedula    10 年前

    有些解决方案假定为Rails。但是,在纯红宝石中,您可以执行以下操作

    require 'date'    
    
    d = Date.now
    last_month = d<<1
    
    last_month.strftime("%Y-%m-%d")
    
        11
  •  0
  •   Lomefin    10 年前

    在本例中,我使用的是ActiveSupport::TimeZone,但在您使用Rails或ActiveSupport的情况下,它可能会派上用场。

    如果你想要上个月,你可以减去1个月

    time = Time.zone.parse('21-12-2008 10:51 UTC')
    time.ago(1.month)
    
        12
  •  -1
  •   KLaw    8 年前
    $ irb
    irb(main):001:0> time = Time.now
    => 2016-11-21 10:16:31 -0800
    irb(main):002:0> year = time.year
    => 2016
    irb(main):003:0> month = time.month
    => 11
    irb(main):004:0> last_month = month - 1
    => 10
    irb(main):005:0> puts time
    2016-11-21 10:16:31 -0800
    => nil
    irb(main):006:0> puts year
    2016
    => nil
    irb(main):007:0> puts month
    11
    => nil
    irb(main):008:0> puts last_month
    10
    => nil