summaryrefslogtreecommitdiff
path: root/spec/ruby/core/time/localtime_spec.rb
blob: 609b6532a16c5f9719abf12dcc93a16628ca5dd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
require_relative '../../spec_helper'

describe "Time#localtime" do
  it "converts self to local time, modifying the receiver" do
    # Testing with America/Regina here because it doesn't have DST.
    with_timezone("CST", -6) do
      t = Time.gm(2007, 1, 9, 12, 0, 0)
      t.localtime
      t.should == Time.local(2007, 1, 9, 6, 0, 0)
    end
  end

  it "returns self" do
    t = Time.gm(2007, 1, 9, 12, 0, 0)
    t.localtime.should equal(t)
  end

  it "converts time to the UTC offset specified as an Integer number of seconds" do
    t = Time.gm(2007, 1, 9, 12, 0, 0)
    t.localtime(3630)
    t.should == Time.new(2007, 1, 9, 13, 0, 30, 3630)
    t.utc_offset.should == 3630
  end

  describe "on a frozen time" do
    it "does not raise an error if already in the right time zone" do
      time = Time.now
      time.freeze
      time.localtime.should equal(time)
    end

    it "raises a FrozenError if the time has a different time zone" do
      time = Time.gm(2007, 1, 9, 12, 0, 0)
      time.freeze
      -> { time.localtime }.should raise_error(FrozenError)
    end
  end

  describe "with an argument that responds to #to_int" do
    it "coerces using #to_int" do
      o = mock('integer')
      o.should_receive(:to_int).and_return(3630)
      t = Time.gm(2007, 1, 9, 12, 0, 0)
      t.localtime(o)
      t.should == Time.new(2007, 1, 9, 13, 0, 30, 3630)
      t.utc_offset.should == 3630
    end
  end

  it "returns a Time with a UTC offset of the specified number of Rational seconds" do
    t = Time.gm(2007, 1, 9, 12, 0, 0)
    t.localtime(Rational(7201, 2))
    t.should == Time.new(2007, 1, 9, 13, 0, Rational(1, 2), Rational(7201, 2))
    t.utc_offset.should eql(Rational(7201, 2))
  end

  describe "with an argument that responds to #to_r" do
    it "coerces using #to_r" do
      o = mock_numeric('rational')
      o.should_receive(:to_r).and_return(Rational(7201, 2))
      t = Time.gm(2007, 1, 9, 12, 0, 0)
      t.localtime(o)
      t.should == Time.new(2007, 1, 9, 13, 0, Rational(1, 2), Rational(7201, 2))
      t.utc_offset.should eql(Rational(7201, 2))
    end
  end

  it "returns a Time with a UTC offset specified as +HH:MM" do
    t = Time.gm(2007, 1, 9, 12, 0, 0)
    t.localtime("+01:00")
    t.should == Time.new(2007, 1, 9, 13, 0, 0, 3600)
    t.utc_offset.should == 3600
  end

  it "returns a Time with a UTC offset specified as -HH:MM" do
    t = Time.gm(2007, 1, 9, 12, 0, 0)
    t.localtime("-01:00")
    t.should == Time.new(2007, 1, 9, 11, 0, 0, -3600)
    t.utc_offset.should == -3600
  end

  it "returns a Time with a UTC offset specified as UTC" do
    t = Time.new(2007, 1, 9, 12, 0, 0, 3600)
    t.localtime("UTC")
    t.utc_offset.should == 0
  end

  it "returns a Time with a UTC offset specified as A-Z military zone" do
    t = Time.new(2007, 1, 9, 12, 0, 0, 3600)
    t.localtime("B")
    t.utc_offset.should == 3600 * 2
  end

  platform_is_not :windows do
    it "changes the timezone according to the set one" do
      t = Time.new(2005, 2, 27, 22, 50, 0, -3600)
      t.utc_offset.should == -3600

      with_timezone("America/New_York") do
        t.localtime
      end

      t.utc_offset.should == -18000
    end

    it "does nothing if already in a local time zone" do
      time = with_timezone("America/New_York") do
        Time.new(2005, 2, 27, 22, 50, 0)
      end
      zone = time.zone

      with_timezone("Europe/Amsterdam") do
        time.localtime
      end

      time.zone.should == zone
    end
  end

  describe "with an argument that responds to #to_str" do
    it "coerces using #to_str" do
      o = mock('string')
      o.should_receive(:to_str).and_return("+01:00")
      t = Time.gm(2007, 1, 9, 12, 0, 0)
      t.localtime(o)
      t.should == Time.new(2007, 1, 9, 13, 0, 0, 3600)
      t.utc_offset.should == 3600
    end
  end

  it "raises ArgumentError if the String argument is not of the form (+|-)HH:MM" do
    t = Time.now
    -> { t.localtime("3600") }.should raise_error(ArgumentError)
  end

  it "raises ArgumentError if the String argument is not in an ASCII-compatible encoding" do
    t = Time.now
    -> { t.localtime("-01:00".encode("UTF-16LE")) }.should raise_error(ArgumentError)
  end

  it "raises ArgumentError if the argument represents a value less than or equal to -86400 seconds" do
    t = Time.new
    t.localtime(-86400 + 1).utc_offset.should == (-86400 + 1)
    -> { t.localtime(-86400) }.should raise_error(ArgumentError)
  end

  it "raises ArgumentError if the argument represents a value greater than or equal to 86400 seconds" do
    t = Time.new
    t.localtime(86400 - 1).utc_offset.should == (86400 - 1)
    -> { t.localtime(86400) }.should raise_error(ArgumentError)
  end
end