Class: NSDate

Inherits:
Object show all
Defined in:
lib/sugarcube/nsdate.rb,
lib/sugarcube/nsdate_delta.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.newObject



3
4
5
# File 'lib/sugarcube/nsdate.rb', line 3

def self.new
  self.date
end

Instance Method Details

#date_arrayObject

(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [2012, 9, 27]



60
61
62
# File 'lib/sugarcube/nsdate.rb', line 60

def date_array
  return [self.year, self.month, self.day]
end

#datetime_arrayObject

(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [2012, 9, 12, 11, 29, 12]



76
77
78
# File 'lib/sugarcube/nsdate.rb', line 76

def datetime_array
  return [self.year, self.month, self.day, self.hour, self.min, self.sec]
end

#days_in_monthObject



98
99
100
# File 'lib/sugarcube/nsdate.rb', line 98

def days_in_month
  NSCalendar.currentCalendar.rangeOfUnit(NSDayCalendarUnit, inUnit:NSMonthCalendarUnit, forDate:self).length
end

#days_in_yearObject



102
103
104
# File 'lib/sugarcube/nsdate.rb', line 102

def days_in_year
  NSCalendar.currentCalendar.rangeOfUnit(NSDayCalendarUnit, inUnit:NSYearCalendarUnit, forDate:self).length
end

#delta(_components) ⇒ Object



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
# File 'lib/sugarcube/nsdate_delta.rb', line 3

def delta(_components)
  components = {}.update(_components)
  is_very_specific = components.has_key?(:seconds)
  is_very_specific ||= components.has_key?(:minutes)
  is_very_specific ||= components.has_key?(:hours)

  y = components.delete(:years) || 0
  mo = components.delete(:months) || 0
  d = components.delete(:days) || 0
  h = components.delete(:hours) || 0
  mi = components.delete(:minutes) || 0
  s = components.delete(:seconds) || 0
  w = components.delete(:weeks) || 0
  raise "Unknown arguments #{components.keys}" unless components.empty?

  is_dst = self.dst?

  delta = s
  # todo: leap second adjustment?  can leap seconds be detected?
  delta += mi.minutes
  delta += h.hours

  delta += d.days
  delta += w.weeks
  return_date = self + delta

  # using days_in_month, this is pretty easy.  12 mos per year IS a constant,
  # and then we just keep adding the number of days in the month (or last month
  # if we're going backwards).  The curve ball is that when we are in day
  # 29,30,31, we might jump forward a month and "fall off" to the next month.
  # In this case, we add a correction.  We will always move forwards or
  # backwards until the return_date.day is correct.
  mo += y * 12
  if mo != 0
    if return_date.day > 28
      # we will try and preserve this day
      correct_day_of_month = return_date.day
    else
      correct_day_of_month = nil
    end

    if mo > 0
      mo.times do
        delta = return_date.days_in_month
        return_date += delta.days

        # if the day_of_month is wrong, it must be because we either added PAST
        # the correct month (so roll back), or because we WERE rolled back and
        # when we moved forward a month, we were left back at the smaller day.
        if correct_day_of_month
          if return_date.day < 28
            return_date -= return_date.day.days
          elsif return_date.day < correct_day_of_month
            fix = correct_day_of_month > return_date.days_in_month ? return_date.days_in_month : correct_day_of_month
            return_date += (fix - return_date.day).days
          end
        end
      end
    elsif mo < 0
      (-mo).times do
        # subtract *last* months number of days.
        # there is a REALLY rare case where subtracting return_date.day is one
        # hour short of "last month" and so you end up with THIS month.  there
        # is NEVER a case when subtracting return_date.day+1 days is NOT
        # "previous month".  dates. :-|  f-em.
        delta = (return_date - (return_date.day+1).days).days_in_month
        return_date -= delta.days
        # same correction as above
        if correct_day_of_month
          if return_date.day < 28
            return_date -= return_date.day.days
          elsif return_date.day < correct_day_of_month
            fix = correct_day_of_month > return_date.days_in_month ? return_date.days_in_month : correct_day_of_month
            return_date += (fix - return_date.day).days
          end
        end
      end
    end
  end

  # DST adjustment, unless minutes, hours, or seconds were specified.
  #
  # the thinking here is that if they WERE specified, the delta should be
  # accurate to that granularity.  if they were omitted, the hour component
  # should not change, even though an off-by-one adjustment is needed
  #
  # for instance.  3/10/2012 is not in DST.  3/11/2012 IS.
  # Time.at(3/10/2012)  # => 2012-03-10 17:00:00 -0700
  # Time.at(3/10/2012).delta(days:1)  # => 2012-03-11 17:00:00 -0600
  #
  # notice the time is the SAME, even though the time zone is different.  BUT:
  # Time.at(3/10/2012).delta(hours:24)  # => 2012-03-11 17:00:00 -0600
  # Time.at(3/10/2012).delta(hours:25)  # => 2012-03-11 18:00:00 -0600
  unless return_date.dst? == is_dst or is_very_specific
    if is_dst
      return_date += 1.hour
    else
      return_date -= 1.hour
    end
  end

  return return_date
end

#end_of_dayObject

(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.end_of_day => 2012-09-28 00:00:00 +0900



93
94
95
96
# File 'lib/sugarcube/nsdate.rb', line 93

def end_of_day
  time_interval = (23 - self.hour).hours + (59 - self.min).minutes - self.sec + 60
  return self + time_interval
end

#eraObject



30
31
32
# File 'lib/sugarcube/nsdate.rb', line 30

def era
  return _calendar_components(NSEraCalendarUnit).era
end

#leap_year?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/sugarcube/nsdate.rb', line 52

def leap_year?
  self.year % 4 == 0 and self.year % 100 != 0 or self.year % 400 == 0
end

#same_day?(other) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
# File 'lib/sugarcube/nsdate.rb', line 39

def same_day?(other)
  return other.day == self.day &&
         other.month == self.month &&
         other.year == self.year &&
         other.era == self.era
end

#start_of_dayObject

(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.start_of_day => 2012-09-27 00:00:00 +0900



84
85
86
87
# File 'lib/sugarcube/nsdate.rb', line 84

def start_of_day
  time_interval = self.hour.hours + self.min.minutes + self.sec
  return self - time_interval
end

#string_with_format(format) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/sugarcube/nsdate.rb', line 17

def string_with_format(format)
  format_template = NSDateFormatter.dateFormatFromTemplate(format, options:0,
                                                    locale:NSLocale.currentLocale)
  date_formatter = NSDateFormatter.new
  date_formatter.setDateFormat(format_template)
  date_formatter.stringFromDate(self)
end

#string_with_style(style) ⇒ Object



7
8
9
10
11
12
13
14
# File 'lib/sugarcube/nsdate.rb', line 7

def string_with_style(style)
  date_formatter = NSDateFormatter.new
  if style.is_a? Symbol
    style = style.nsdatesyle
  end
  date_formatter.setDateStyle(style)
  date_formatter.stringFromDate(self)
end

#time_arrayObject

(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [11, 29, 12]



68
69
70
# File 'lib/sugarcube/nsdate.rb', line 68

def time_array
  return [self.hour, self.min, self.sec]
end

#timezoneObject Also known as: timeZone



25
26
27
# File 'lib/sugarcube/nsdate.rb', line 25

def timezone
  return _calendar_components(NSTimeZoneCalendarUnit).timeZone
end

#today?Boolean

Returns:

  • (Boolean)


34
35
36
37
# File 'lib/sugarcube/nsdate.rb', line 34

def today?
  today = self.class.new
  return same_day?(today)
end

#utc_offsetObject

In the rare case you actually get an NSDate object - not a Time object - this method is actually useful.



48
49
50
# File 'lib/sugarcube/nsdate.rb', line 48

def utc_offset
  return self.timezone.secondsFromGMT
end