Class: Chronos::Duration::Gregorian

Inherits:
Chronos::Duration show all
Defined in:
lib/chronos/duration/gregorian.rb

Constant Summary collapse

FormatToS =
"%dps %d months (%s)".freeze
FormatInspect =
"#<%s:0x%08x %dps %d months (%s)>".freeze
ShortTime =
["%d".freeze, "%02d".freeze, "%02d".freeze, "%02d".freeze].freeze
MinSecondsInMonths =

if you want to estimate minimum seconds in months

[
	0,
	2419200,
	5097600,
	7689600,
	10368000,
	12960000,
	15638400,
	18316800,
	20908800,
	23587200,
	26179200,
	28857600,
	31536000
]
MaxSecondsInMonths =

if you want to estimate maximum seconds in months

[
	0,        # 0 days
	2678401,  # 31 days + leapsecond (june/december)
	5356800,  # 62 days (july, august)
	7948801,  # 92 days + leapsecond (june, july, august)
	10627201, # 123 days + leapsecond
	13219201,
	15897601,
	18489602,
	21168002,
	23760002,
	26438402,
	29116802,
	31622402,
]
After =
Hash.new { |h,(a,b)| raise ArgumentError, "Can't get #{a} after #{b}" }.merge({
	[:picoseconds,  :nanoseconds]  =>                   1_000,
	[:picoseconds,  :microseconds] =>               1_000_000,
	[:picoseconds,  :milliseconds] =>           1_000_000_000,
	[:picoseconds,  :seconds]      =>       1_000_000_000_000,
	[:picoseconds,  :minutes]      =>      60_000_000_000_000,
	[:picoseconds,  :hours]        =>   3_600_000_000_000_000,
	[:picoseconds,  :days]         =>  86_400_000_000_000_000,
	[:picoseconds,  :weeks]        => 345_600_000_000_000_000,
	[:nanoseconds,  :microseconds] =>                   1_000,
	[:nanoseconds,  :milliseconds] =>               1_000_000,
	[:nanoseconds,  :seconds]      =>           1_000_000_000,
	[:nanoseconds,  :minutes]      =>          60_000_000_000,
	[:nanoseconds,  :hours]        =>       3_600_000_000_000,
	[:nanoseconds,  :days]         =>      86_400_000_000_000,
	[:nanoseconds,  :weeks]        =>     345_600_000_000_000,
	[:microseconds, :milliseconds] =>                   1_000,
	[:microseconds, :seconds]      =>               1_000_000,
	[:microseconds, :minutes]      =>              60_000_000,
	[:microseconds, :hours]        =>           3_600_000_000,
	[:microseconds, :days]         =>          86_400_000_000,
	[:microseconds, :weeks]        =>         345_600_000_000,
	[:milliseconds, :seconds]      =>                   1_000,
	[:milliseconds, :minutes]      =>                  60_000,
	[:milliseconds, :hours]        =>               3_600_000,
	[:milliseconds, :days]         =>              86_400_000,
	[:milliseconds, :weeks]        =>             345_600_000,
	[:seconds,      :minutes]      =>                      60,
	[:seconds,      :hours]        =>                   3_600,
	[:seconds,      :days]         =>                  86_400,
	[:seconds,      :weeks]        =>                 345_600,
	[:minutes,      :hours]        =>                      60,
	[:minutes,      :days]         =>                   1_440,
	[:minutes,      :weeks]        =>                  10_080,
	[:hours,        :days]         =>                      24,
	[:hours,        :weeks]        =>                     168,
	[:days,         :weeks]        =>                       7,
	[:months,       :years]        =>                      12,
})

Instance Attribute Summary

Attributes inherited from Chronos::Duration

#language

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Chronos::Duration

#%, #*, #+, #+@, #-, #-@, #/, days, #div, #durations_at, #inspect, #quo, seconds, #split, #values_at

Constructor Details

#initialize(months, days, picoseconds, language = nil) ⇒ Gregorian

seconds+months



122
123
124
125
# File 'lib/chronos/duration/gregorian.rb', line 122

def initialize(months, days, picoseconds, language=nil)
	super(days, picoseconds, language)
	@months = months
end

Class Method Details

.import(duration) ⇒ Object



117
118
119
# File 'lib/chronos/duration/gregorian.rb', line 117

def self.import(duration)
	duration.respond_to?(:to_gregorian_duration) ? duration.to_gregorian_duration : super
end

.with(parts) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/chronos/duration/gregorian.rb', line 96

def self.with(parts)
	y,m,w,d,h,min,s,ms,us,ns,ps = *Hash.new(0).merge(parts).values_at(
		:years,
		:months,
		:weeks,
		:days,
		:hours,
		:minutes,
		:seconds,
		:milliseconds,
		:microseconds,
		:nanoseconds,
		:picoseconds
	)
	seconds  = s+min*60+h*3600+d*86400+w*604800
	ps      += seconds*1_000_000_000_000+ms*1_000_000_000+us*1_000_000+ns*1_000
	days, ps = ps.divmod(PS_IN_DAY)
	months   = m+y*12
	new(months, days, ps, parts[:language])
end

Instance Method Details

#centuriesObject



175
176
177
# File 'lib/chronos/duration/gregorian.rb', line 175

def centuries
	@months.quo(1200)
end

#days(after = nil) ⇒ Object



155
156
157
# File 'lib/chronos/duration/gregorian.rb', line 155

def days(after=nil)
	after ? days%After[[:days, after]] : picoseconds.quo(PS_IN_DAY)
end

#decadesObject



171
172
173
# File 'lib/chronos/duration/gregorian.rb', line 171

def decades
	@months.quo(144)
end

#hours(after = nil) ⇒ Object



151
152
153
# File 'lib/chronos/duration/gregorian.rb', line 151

def hours(after=nil)
	after ? hours%After[[:hours, after]] : picoseconds.quo(PS_IN_HOUR)
end

#microseconds(after = nil) ⇒ Object



135
136
137
# File 'lib/chronos/duration/gregorian.rb', line 135

def microseconds(after=nil)
	after ? microseconds%After[[:microseconds, after]] : picoseconds.quo(PS_IN_MICROSECOND)
end

#milliseconds(after = nil) ⇒ Object



139
140
141
# File 'lib/chronos/duration/gregorian.rb', line 139

def milliseconds(after=nil)
	after ? milliseconds%After[[:milliseconds, after]] : picoseconds.quo(PS_IN_MILLISECOND)
end

#minutes(after = nil) ⇒ Object



147
148
149
# File 'lib/chronos/duration/gregorian.rb', line 147

def minutes(after=nil)
	after ? minutes%After[[:minutes, after]] : picoseconds.quo(PS_IN_MINUTE)
end

#months(after = nil) ⇒ Object



163
164
165
# File 'lib/chronos/duration/gregorian.rb', line 163

def months(after=nil)
	after ? days%After[[:days, after]] : @months
end

#nanoseconds(after = nil) ⇒ Object



131
132
133
# File 'lib/chronos/duration/gregorian.rb', line 131

def nanoseconds(after=nil)
	after ? nanoseconds%After[[:nanoseconds, after]] : picoseconds.quo(PS_IN_NANOSECOND)
end

#picoseconds(after = nil) ⇒ Object



127
128
129
# File 'lib/chronos/duration/gregorian.rb', line 127

def picoseconds(after=nil)
	after ? picoseconds%After[[:picoseconds, after]] : @picoseconds+@days*PS_IN_DAY
end

#seconds(after = nil) ⇒ Object



143
144
145
# File 'lib/chronos/duration/gregorian.rb', line 143

def seconds(after=nil)
	after ? seconds%After[[:seconds, after]] : picoseconds.quo(PS_IN_SECOND)
end

#short_time(fraction_digits = nil, num_elements = nil) ⇒ Object

Return a String in form of DDD:HH:MM:SS.fff

fraction_digits

How many digits to display after the ., defaults to 0

num_elements

How many elements to display at least

* 1 is only SS
* 2 is MM:SS
* 3 is HH:MM:SS
* 4 is DDD:HH:SS


215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/chronos/duration/gregorian.rb', line 215

def short_time(fraction_digits=nil, num_elements=nil)
	elements = [
		days.floor,
		hours(:days).floor,
		minutes(:hours).floor,
		seconds(:minutes)
	]
	elements.shift while (elements.size > num_elements && elements.first.first.zero?)
	display = ShortTime[-elements.size..-1]
	display[-1] = "%#{fraction_digits+3}.#{fraction_digits}f" if (fraction_digits && fraction_digits > 0)
	sprintf(display.join(":"), *elements)
end

#to_a(exclude_language = nil) ⇒ Object



187
188
189
# File 'lib/chronos/duration/gregorian.rb', line 187

def to_a(exclude_language=nil)
	exclude_language ? [@picoseconds, @months] : [@picoseconds, @months, @language]
end

#to_durationObject



179
180
181
# File 'lib/chronos/duration/gregorian.rb', line 179

def to_duration
	Duration.new(@days, @picoseconds, @language)
end

#to_gregorian_durationObject



183
184
185
# File 'lib/chronos/duration/gregorian.rb', line 183

def to_gregorian_duration
	self
end

#to_hashObject



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/chronos/duration/gregorian.rb', line 191

def to_hash
	{
		:years        => years,
		:months       => @months,
		:weeks        => weeks,
		:days         => days,
		:hours        => hours,
		:minutes      => minutes,
		:seconds      => seconds,
		:milliseconds => milliseconds,
		:microseconds => microseconds,
		:nanoseconds  => nanoseconds,
		:picoseconds  => @picoseconds,
		:language     => @language,
	}
end

#to_s(drop = :all_zeros, language = nil) ⇒ Object

return a readable representation



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/chronos/duration/gregorian.rb', line 229

def to_s(drop=:all_zeros, language=nil)
	elements1 = @months.zero? ? [] : [
		[years.floor,             :year],
		[days(:weeks).floor,      :month],
	]
	elements2 = @picoseconds.zero? ? [] : [
		[weeks.floor,                      :week],
		[days(:weeks).floor,               :day],
		[hours(:days).floor,               :hour],
		[minutes(:hours).floor,            :minute],
		[seconds(:minutes).floor,          :second],
		[milliseconds(:seconds).floor,     :millisecond],
		[microseconds(:milliseconds).floor, :microseconds],
		[nanoseconds(:microseconds).floor,  :nanosecond],
		[picoseconds(:nanoseconds).floor,   :picosecond],
	]
	elements = elements1+elements2
	case drop
		when :all_zeros
			elements.reject! { |count,*rest| count.zero? }
		when :leading_zeros
			elements.shift while elements.first.first.zero?
		when nil
		else
			raise ArgumentError, "Unknown directive, #{drop.inspect}"
	end
	elements.empty? ? "0" : elements.map { |count, unit|
		"#{count} #{Chronos.string(language ? Chronos.language(language) : @language, unit, count)}"
	}.join(", ")
end

#weeksObject



159
160
161
# File 'lib/chronos/duration/gregorian.rb', line 159

def weeks
	picoseconds.quo(PS_IN_WEEK)
end

#yearsObject



167
168
169
# File 'lib/chronos/duration/gregorian.rb', line 167

def years
	@months.quo(12)
end