Class: NSDate
- Defined in:
- lib/sugarcube/nsdate.rb,
lib/sugarcube/nsdate_delta.rb
Constant Summary collapse
- SugarCubeFormats =
these formatters are used in
string_with_format
. Symbols are convertd to a string using string_with_format's templating, and strings are concatenated as-is { iso8601: [:yyyy, '-', :MM, '-', :dd, ' ', :HH, ':', :mm, ':', :ss, '.', :SSS] }
Class Method Summary collapse
Instance Method Summary collapse
-
#date_array ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [2012, 9, 27].
-
#datetime_array ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [2012, 9, 12, 11, 29, 12].
- #days_in_month ⇒ Object
- #days_in_year ⇒ Object
- #delta(_components) ⇒ Object
- #downto(last_date, delta = {days: -1}, &block) ⇒ Object
-
#end_of_day ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.end_of_day => 2012-09-28 00:00:00 +0900.
-
#end_of_month ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.end_of_month => 2012-10-01 00:00:00 +0900.
- #era ⇒ Object
- #leap_year? ⇒ Boolean
- #same_day?(other) ⇒ Boolean
-
#start_of_day ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.start_of_day => 2012-09-27 00:00:00 +0900.
-
#start_of_month ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.start_of_month => 2012-09-01 00:00:00 +0900.
-
#string_with_format(format) ⇒ Object
Pass in a format string or a Symbol.
- #string_with_style(date_style = NSDateFormatterMediumStyle, time_style = NSDateFormatterNoStyle) ⇒ Object
-
#time_array ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [11, 29, 12].
- #timezone ⇒ Object (also: #timeZone)
- #today? ⇒ Boolean
- #upto(last_date, delta = {days: 1}, &block) ⇒ Object
-
#utc_offset ⇒ Object
In the rare case you actually get an NSDate object - not a Time object - this method is actually useful.
Class Method Details
.from_components(components) ⇒ Object
9 10 11 12 13 14 15 16 |
# File 'lib/sugarcube/nsdate.rb', line 9 def self.from_components(components) date_components = NSDateComponents.new components.each do |property,value| date_components.send("#{property}=", value) end calendar = NSCalendar.alloc.initWithCalendarIdentifier(NSGregorianCalendar) return calendar.dateFromComponents(date_components) end |
Instance Method Details
#date_array ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [2012, 9, 27]
125 126 127 |
# File 'lib/sugarcube/nsdate.rb', line 125 def date_array return [self.year, self.month, self.day] end |
#datetime_array ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [2012, 9, 12, 11, 29, 12]
141 142 143 |
# File 'lib/sugarcube/nsdate.rb', line 141 def datetime_array return [self.year, self.month, self.day, self.hour, self.min, self.sec] end |
#days_in_month ⇒ Object
179 180 181 |
# File 'lib/sugarcube/nsdate.rb', line 179 def days_in_month NSCalendar.currentCalendar.rangeOfUnit(NSDayCalendarUnit, inUnit:NSMonthCalendarUnit, forDate:self).length end |
#days_in_year ⇒ Object
183 184 185 |
# File 'lib/sugarcube/nsdate.rb', line 183 def days_in_year leap_year? ? 366 : 365 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 106 107 108 |
# 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 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 else # 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 delta = 0 delta += d.days delta += w.weeks return_date += delta # 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 |
#downto(last_date, delta = {days: -1}, &block) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/sugarcube/nsdate.rb', line 74 def downto(last_date, delta={days: -1}, &block) return if last_date > self date = self while date >= last_date if block.arity == 0 block.call else block.call(date) end new_date = date.delta(delta) break if new_date >= date date = new_date end end |
#end_of_day ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.end_of_day => 2012-09-28 00:00:00 +0900
158 159 160 161 |
# File 'lib/sugarcube/nsdate.rb', line 158 def end_of_day time_interval = (23 - self.hour).hours + (59 - self.min).minutes - self.sec + 60 return self + time_interval end |
#end_of_month ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.end_of_month => 2012-10-01 00:00:00 +0900
175 176 177 |
# File 'lib/sugarcube/nsdate.rb', line 175 def end_of_month return self.end_of_day.delta(days:days_in_month - day) end |
#era ⇒ Object
95 96 97 |
# File 'lib/sugarcube/nsdate.rb', line 95 def era return _calendar_components(NSEraCalendarUnit).era end |
#leap_year? ⇒ Boolean
117 118 119 |
# File 'lib/sugarcube/nsdate.rb', line 117 def leap_year? self.year % 4 == 0 and self.year % 100 != 0 or self.year % 400 == 0 end |
#same_day?(other) ⇒ Boolean
104 105 106 107 108 109 |
# File 'lib/sugarcube/nsdate.rb', line 104 def same_day?(other) return other.day == self.day && other.month == self.month && other.year == self.year && other.era == self.era end |
#start_of_day ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.start_of_day => 2012-09-27 00:00:00 +0900
149 150 151 152 |
# File 'lib/sugarcube/nsdate.rb', line 149 def start_of_day time_interval = self.hour.hours + self.min.minutes + self.sec return self - time_interval end |
#start_of_month ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.start_of_month => 2012-09-01 00:00:00 +0900
167 168 169 |
# File 'lib/sugarcube/nsdate.rb', line 167 def start_of_month return self.start_of_day.delta(days:1 - day) end |
#string_with_format(format) ⇒ Object
Pass in a format string or a Symbol. The Symbol must exist in NSDate::SugarCubeFormats.
See https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1 and http://www.unicode.org/reports/tr35/tr35-19.html#Date_Format_Patterns for more information about date format strings.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/sugarcube/nsdate.rb', line 35 def string_with_format(format) if format.is_a?(Symbol) formatters = SugarCubeFormats[format] raise "No format found for #{format.inspect}" unless formatters retval = '' formatters.each do |formatter| case formatter when Symbol retval << string_with_format(formatter.to_s) when String retval << formatter end end return retval else format_template = NSDateFormatter.dateFormatFromTemplate(format, options:0, locale:NSLocale.currentLocale) date_formatter = NSDateFormatter.new date_formatter.setDateFormat(format_template) return date_formatter.stringFromDate(self) end end |
#string_with_style(date_style = NSDateFormatterMediumStyle, time_style = NSDateFormatterNoStyle) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/sugarcube/nsdate.rb', line 18 def string_with_style(date_style=NSDateFormatterMediumStyle,time_style=NSDateFormatterNoStyle) date_formatter = NSDateFormatter.new date_style = date_style.nsdatestyle if date_style.is_a? Symbol time_style = time_style.nsdatestyle if time_style.is_a? Symbol date_formatter.setDateStyle(date_style) date_formatter.setTimeStyle(time_style) date_formatter.stringFromDate(self) end |
#time_array ⇒ Object
(main)> t = Time.new => 2012-09-27 11:29:12 +0900 (main)> t.time_array => [11, 29, 12]
133 134 135 |
# File 'lib/sugarcube/nsdate.rb', line 133 def time_array return [self.hour, self.min, self.sec] end |
#timezone ⇒ Object Also known as: timeZone
90 91 92 |
# File 'lib/sugarcube/nsdate.rb', line 90 def timezone return _calendar_components(NSTimeZoneCalendarUnit).timeZone end |
#today? ⇒ Boolean
99 100 101 102 |
# File 'lib/sugarcube/nsdate.rb', line 99 def today? today = self.class.new return same_day?(today) end |
#upto(last_date, delta = {days: 1}, &block) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/sugarcube/nsdate.rb', line 58 def upto(last_date, delta={days: 1}, &block) return if last_date < self date = self while date <= last_date if block.arity == 0 block.call else block.call(date) end new_date = date.delta(delta) break if new_date <= date date = new_date end end |
#utc_offset ⇒ Object
In the rare case you actually get an NSDate object - not a Time object - this method is actually useful.
113 114 115 |
# File 'lib/sugarcube/nsdate.rb', line 113 def utc_offset return self.timezone.secondsFromGMT end |