Class: Vanadiel::Time
- Inherits:
-
Object
- Object
- Vanadiel::Time
- Includes:
- Comparable
- Defined in:
- lib/vanadiel/time.rb
Overview
Vanadiel::Time is an abstraction of Vana'diel dates and times from Final Fantasy XI. Time is stored internally as the number of microseconds since C.E. 0001-01-01 00:00:00.
Vana'diel time spec:
One year = 12 months = 360 days
One month = 30 days
One day = 24 hours
One hour = 60 minutes
One minute = 60 seconds
One second = 0.04 seconds of the earth's (1/25th of a second)
Vana'diel second = 0.04 earth seconds (1/25th of a second)
Vana'diel minute = 2.4 earth seconds
Vana'diel hour = 2 minutes 24 earth seconds
Vana'diel day = 57 minutes 36 earth seconds
Vana'diel week = 7 hours 40 minutes 48 earth seconds
Vana'diel calendar month = 1 day 4 hours 48 earth minutes
Vana'diel lunar month = 3 days 14 hours 24 earth minutes
Vana'diel year = 14 days 9 hours 36 earth minutes
Each full lunar cycle lasts for 84 Vana'diel days.
Vana'diel has 12 distinct moon phases.
Japanese client expresses moon phases by 12 kinds of texts. (percentage is not displayed in Japanese client)
Non-Japanese client expresses moon phases by 7 kinds of texts and percentage.
C.E. = Crystal Era
A.D. -91270800 => 1967/02/10 00:00:00 +0900
C.E. 0 => 0001/01/01 00:00:00
A.D. 2002/01/01(Tue) 00:00:00 JST
C.E. 0886/01/01(Fir) 00:00:00
A.D. 2047/10/22(Tue) 01:00:00 JST
C.E. 2047/10/22(Wat) 01:00:00
A.D. 2047/10/21(Mon) 15:37:30 UTC
C.E. 2047/10/21(Win) 15:37:30
Constant Summary collapse
- VERSION =
vanadiel-time version
"0.2.1"
- ONE_SECOND =
1000000
- ONE_MINUTE =
60 * ONE_SECOND
- ONE_HOUR =
60 * ONE_MINUTE
- ONE_DAY =
24 * ONE_HOUR
- ONE_WEEK =
8 * ONE_DAY
- ONE_MONTH =
30 * ONE_DAY
- ONE_YEAR =
360 * ONE_DAY
- VANA_TIME_SCALE =
Vana'diel time goes 25 times faster than the Earth
25
- VANA_BASE_YEAR =
886
- VANA_BASE_TIME =
(VANA_BASE_YEAR * ONE_YEAR) / VANA_TIME_SCALE
- EARTH_BASE_TIME =
2002/01/01 00:00:00.000 JST
1009810800 * ONE_SECOND
- DIFF_TIME =
VANA_BASE_TIME - EARTH_BASE_TIME
- MOON_CYCLE_DAYS =
Vana'diel moon cycle lasts 84 days
84
Instance Attribute Summary collapse
-
#hour ⇒ Fixnum
readonly
The hour of the day (0..23) for time.
-
#mday ⇒ Fixnum
(also: #day)
readonly
The day of the month (1..30) for time.
-
#min ⇒ Fixnum
readonly
The minute of the hour (0..59) for time.
-
#month ⇒ Fixnum
(also: #mon)
readonly
The month of the year (1..12) for time.
-
#moon_age ⇒ Fixnum
(also: #moon_age12)
readonly
An integer representing the moon age (0..11), for Japanese service.
-
#moon_age7 ⇒ Fixnum
readonly
An integer representing the moon age (0..7), for Non-Japanese service.
-
#moon_percent ⇒ Fixnum
readonly
An integer representing the moon phase percentage (0..100), for Non-Japanese service.
-
#sec ⇒ Fixnum
readonly
The second of the minute (0..59) for time.
-
#time ⇒ Bignum
The value of the time as microseconds since C.E.
-
#time_of_moon ⇒ Fixnum
readonly
The number of microseconds of the moon.
-
#usec ⇒ Fixnum
readonly
Just the number of microseconds (0..999999) for time.
-
#wday ⇒ Fixnum
readonly
An integer representing the day of the week, 0..7, with Firesday == 0.
-
#yday ⇒ Fixnum
readonly
An integer representing the day of the year (1..360).
-
#year ⇒ Fixnum
readonly
The year for time.
Class Method Summary collapse
-
.at(time, usec = 0) ⇒ Object
Creates a new time object with the value given by time.
-
.earth_to_vana(earth_time) ⇒ Integer
Converts microseconds as the Earth time to microseconds as Vana'diel time from the Epoch.
-
.mktime(year, *rest_part) ⇒ Vanadiel::Time
Same as Vanadiel::Time.new, but the year is required.
-
.now ⇒ Vanadiel::Time
Synonym for Vanadiel::Time.new.
-
.vana_to_earth(vana_time) ⇒ Integer
Converts microseconds as Vana'diel time to microseconds as the Earth time from the Epoch.
-
.ymdhms_to_usec(year, mon = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) ⇒ Integer
Converts to the value of time as an integer number of microseconds since C.E.
Instance Method Summary collapse
-
#+(sec) ⇒ Vanadiel::Time
Adds some number of seconds (possibly fractional) to time and returns that value as a new time.
-
#-(time) ⇒ Object
Returns a new time that represents the difference between two times, or subtracts the given number of seconds in numeric from time.
-
#<=>(other_time) ⇒ -1, ...
Compares time with other time.
-
#darksday? ⇒ Boolean
Returns true if time represents Darksday.
-
#earthsday? ⇒ Boolean
Returns true if time represents Earthsday.
-
#eql?(other) ⇒ Boolean
Returns true if time and other time are both Vanadiel::Time objects with the same time.
-
#firesday? ⇒ Boolean
Returns true if time represents Firesday.
-
#hash ⇒ Fixnum
Returns a hash code for this time object.
-
#iceday? ⇒ Boolean
Returns true if time represents Iceday.
-
#initialize(*args) ⇒ Time
constructor
It is initialized to the current time if no argument.
-
#lightningday? ⇒ Boolean
Returns true if time represents Lightningday.
-
#lightsday? ⇒ Boolean
Returns true if time represents Lightsday.
- #marshal_dump ⇒ Object
- #marshal_load(obj) ⇒ Object
-
#strftime(format) ⇒ String
Format Vana'diel time according to the directives in the format string.
-
#to_earth_time ⇒ ::Time
Returns the value of time as the Earth time object.
-
#to_f ⇒ Integer
Returns the value of time as an integer number of seconds since C.E.
-
#to_i ⇒ Float
Returns the value of time as a floating point number of seconds since C.E.
-
#to_s ⇒ String
Returns a string representing time.
-
#watersday? ⇒ Boolean
Returns true if time represents Watersday.
-
#windsday? ⇒ Boolean
Returns true if time represents Windsday.
Constructor Details
#new ⇒ Time #new(year, mon = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) ⇒ Time
It is initialized to the current time if no argument. If one or more arguments specified, the time is initialized to the specified time.
128 129 130 |
# File 'lib/vanadiel/time.rb', line 128 def initialize(*args) self.time = args.empty? ? self.class.earth_to_vana(::Time.now.to_f * ONE_SECOND) : self.class.ymdhms_to_usec(*args) end |
Instance Attribute Details
#hour ⇒ Fixnum (readonly)
Returns the hour of the day (0..23) for time.
84 85 86 |
# File 'lib/vanadiel/time.rb', line 84 def hour @hour end |
#mday ⇒ Fixnum (readonly) Also known as: day
Returns the day of the month (1..30) for time.
80 81 82 |
# File 'lib/vanadiel/time.rb', line 80 def mday @mday end |
#min ⇒ Fixnum (readonly)
Returns the minute of the hour (0..59) for time.
87 88 89 |
# File 'lib/vanadiel/time.rb', line 87 def min @min end |
#month ⇒ Fixnum (readonly) Also known as: mon
Returns the month of the year (1..12) for time.
74 75 76 |
# File 'lib/vanadiel/time.rb', line 74 def month @month end |
#moon_age ⇒ Fixnum (readonly) Also known as: moon_age12
Returns an integer representing the moon age (0..11), for Japanese service.
102 103 104 |
# File 'lib/vanadiel/time.rb', line 102 def moon_age @moon_age end |
#moon_age7 ⇒ Fixnum (readonly)
Returns an integer representing the moon age (0..7), for Non-Japanese service.
106 107 108 |
# File 'lib/vanadiel/time.rb', line 106 def moon_age7 @moon_age7 end |
#moon_percent ⇒ Fixnum (readonly)
Returns an integer representing the moon phase percentage (0..100), for Non-Japanese service.
109 110 111 |
# File 'lib/vanadiel/time.rb', line 109 def moon_percent @moon_percent end |
#sec ⇒ Fixnum (readonly)
Returns the second of the minute (0..59) for time.
90 91 92 |
# File 'lib/vanadiel/time.rb', line 90 def sec @sec end |
#time ⇒ Bignum
Returns the value of the time as microseconds since C.E. 0001-01-01 00:00:00.
68 69 70 |
# File 'lib/vanadiel/time.rb', line 68 def time @time end |
#time_of_moon ⇒ Fixnum (readonly)
Returns the number of microseconds of the moon.
112 113 114 |
# File 'lib/vanadiel/time.rb', line 112 def time_of_moon @time_of_moon end |
#usec ⇒ Fixnum (readonly)
Returns just the number of microseconds (0..999999) for time.
93 94 95 |
# File 'lib/vanadiel/time.rb', line 93 def usec @usec end |
#wday ⇒ Fixnum (readonly)
Returns an integer representing the day of the week, 0..7, with Firesday == 0.
96 97 98 |
# File 'lib/vanadiel/time.rb', line 96 def wday @wday end |
#yday ⇒ Fixnum (readonly)
Returns an integer representing the day of the year (1..360).
99 100 101 |
# File 'lib/vanadiel/time.rb', line 99 def yday @yday end |
#year ⇒ Fixnum (readonly)
Returns the year for time.
71 72 73 |
# File 'lib/vanadiel/time.rb', line 71 def year @year end |
Class Method Details
.at(time) ⇒ Vanadiel::Time .at(seconds, usec = 0) ⇒ Vanadiel::Time
Creates a new time object with the value given by time.
156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/vanadiel/time.rb', line 156 def self.at(time, usec = 0) obj = self.new if time.is_a? ::Time obj.time = self.earth_to_vana(time.to_f * ONE_SECOND) elsif time.is_a?(Vanadiel::Time) obj.time = time.time elsif time.is_a?(Integer) || time.is_a?(Float) obj.time = ((time * ONE_SECOND) + usec).to_i else raise ArgumentError, 'invalid argument' end obj end |
.earth_to_vana(earth_time) ⇒ Integer
Converts microseconds as the Earth time to microseconds as Vana'diel time from the Epoch.
182 183 184 |
# File 'lib/vanadiel/time.rb', line 182 def self.earth_to_vana(earth_time) (earth_time + DIFF_TIME) * VANA_TIME_SCALE - ONE_YEAR end |
.mktime(year, *rest_part) ⇒ Vanadiel::Time
Same as Vanadiel::Time.new, but the year is required.
142 143 144 145 |
# File 'lib/vanadiel/time.rb', line 142 def self.mktime(year, *rest_part) args = [year, *rest_part] self.new(*args) end |
.now ⇒ Vanadiel::Time
Synonym for Vanadiel::Time.new. Returns a new time object initialized to the current time.
135 136 137 |
# File 'lib/vanadiel/time.rb', line 135 def self.now self.new end |
.vana_to_earth(vana_time) ⇒ Integer
Converts microseconds as Vana'diel time to microseconds as the Earth time from the Epoch.
174 175 176 |
# File 'lib/vanadiel/time.rb', line 174 def self.vana_to_earth(vana_time) (((vana_time + ONE_YEAR) / VANA_TIME_SCALE) - DIFF_TIME) end |
.ymdhms_to_usec(year, mon = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) ⇒ Integer
Converts to the value of time as an integer number of microseconds since C.E. 0001-01-01 00:00:00.
459 460 461 462 463 464 465 466 467 468 |
# File 'lib/vanadiel/time.rb', line 459 def self.ymdhms_to_usec(year, mon = 1, day = 1, hour = 0, min = 0, sec = 0, usec = 0) raise ArgumentError, 'year out of range' if year < 0 raise ArgumentError, 'mon out of range' if mon < 1 || mon > 12 raise ArgumentError, 'day out of range' if day < 1 || day > 30 raise ArgumentError, 'hour out of range' if hour < 0 || hour > 23 raise ArgumentError, 'min out of range' if min < 0 || min > 59 raise ArgumentError, 'sec out of range' if sec < 0 || sec > 59 raise ArgumentError, 'usec out of range' if usec < 0 || usec > 999999 ((year - 1) * ONE_YEAR) + ((mon - 1) * ONE_MONTH) + ((day - 1) * ONE_DAY) + (hour * ONE_HOUR) + (min * ONE_MINUTE) + (sec * ONE_SECOND) + usec end |
Instance Method Details
#+(sec) ⇒ Vanadiel::Time
Adds some number of seconds (possibly fractional) to time and returns that value as a new time.
355 356 357 |
# File 'lib/vanadiel/time.rb', line 355 def +(sec) self.class.at((@time + (sec * ONE_SECOND)) / ONE_SECOND) end |
#-(time) ⇒ Float #-(seconds) ⇒ Vanadiel::Time
Returns a new time that represents the difference between two times, or subtracts the given number of seconds in numeric from time.
370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/vanadiel/time.rb', line 370 def -(time) if time.is_a? ::Time (@time.to_f - self.class.earth_to_vana(time.to_f * ONE_SECOND)) / ONE_SECOND elsif time.is_a?(Vanadiel::Time) (@time.to_f - time.time) / ONE_SECOND elsif time.is_a?(Integer) || time.is_a?(Float) self.class.at((@time / ONE_SECOND) - time) else raise ArgumentError, 'invalid argument' end end |
#<=>(other_time) ⇒ -1, ...
Compares time with other time.
389 390 391 |
# File 'lib/vanadiel/time.rb', line 389 def <=>(other_time) @time <=> other_time.time end |
#darksday? ⇒ Boolean
Returns true if time represents Darksday.
224 |
# File 'lib/vanadiel/time.rb', line 224 def darksday?; @wday == Vanadiel::Day::DARKSDAY; end |
#earthsday? ⇒ Boolean
Returns true if time represents Earthsday.
194 |
# File 'lib/vanadiel/time.rb', line 194 def earthsday?; @wday == Vanadiel::Day::EARTHSDAY; end |
#eql?(other) ⇒ Boolean
Returns true if time and other time are both Vanadiel::Time objects with the same time.
430 |
# File 'lib/vanadiel/time.rb', line 430 def eql?(other); self.hash == other.hash; end |
#firesday? ⇒ Boolean
Returns true if time represents Firesday.
189 |
# File 'lib/vanadiel/time.rb', line 189 def firesday?; @wday == Vanadiel::Day::FIRESDAY; end |
#hash ⇒ Fixnum
Returns a hash code for this time object.
425 |
# File 'lib/vanadiel/time.rb', line 425 def hash; @time.hash ^ self.class.hash; end |
#iceday? ⇒ Boolean
Returns true if time represents Iceday.
209 |
# File 'lib/vanadiel/time.rb', line 209 def iceday?; @wday == Vanadiel::Day::ICEDAY; end |
#lightningday? ⇒ Boolean
Returns true if time represents Lightningday.
214 |
# File 'lib/vanadiel/time.rb', line 214 def lightningday?; @wday == Vanadiel::Day::LIGHTNINGDAY; end |
#lightsday? ⇒ Boolean
Returns true if time represents Lightsday.
219 |
# File 'lib/vanadiel/time.rb', line 219 def lightsday?; @wday == Vanadiel::Day::LIGHTSDAY; end |
#marshal_dump ⇒ Object
441 442 443 |
# File 'lib/vanadiel/time.rb', line 441 def marshal_dump @time end |
#marshal_load(obj) ⇒ Object
445 446 447 |
# File 'lib/vanadiel/time.rb', line 445 def marshal_load(obj) self.time = obj end |
#strftime(format) ⇒ String
Format Vana'diel time according to the directives in the format string. The directives begins with a percent (%) character. Any text not listed as a directive will be passed through to the output string.
The directive consists of a percent (%) character, zero or more flags, optional minimum field width and a conversion specifier as follows.
%<flags><width><conversion>
Flags:
- don't pad a numerical output.
_ use spaces for padding.
0 use zeros for padding.
^ upcase the result string.
# change case.
The minimum field width specifies the minimum width.
Format directives:
Date (Year, Month, Day):
%Y - Year with century (can be negative)
-0001, 0000, 1995, 2009, 14292, etc.
%C - year / 100 (round down. 20 in 2009)
%y - year % 100 (00..99)
%m - Month of the year, zero-padded (01..12)
%_m blank-padded ( 1..12)
%-m no-padded (1..12)
%d - Day of the month, zero-padded (01..30)
%-d no-padded (1..30)
%e - Day of the month, blank-padded ( 1..30)
%j - Day of the year (001..360)
Time (Hour, Minute, Second, Subsecond):
%H - Hour of the day, 24-hour clock, zero-padded (00..23)
%k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
%M - Minute of the hour (00..59)
%S - Second of the minute (00..59)
%L - Millisecond of the second (000..999)
%N - Fractional seconds digits, default is 6 digits (microsecond)
%3N millisecond (3 digits)
%6N microsecond (6 digits)
Weekday:
%A - The full weekday name (``Firesday'')
%^A uppercased (``FIRESDAY'')
%w - Day of the week (Firesday is 0, 0..7)
Seconds since the Epoch:
%s - Number of seconds since 0001-01-01 00:00:00
Literal string:
%n - Newline character (\n)
%t - Tab character (\t)
%% - Literal ``%'' character
Combination:
%F - The ISO 8601 date format (%Y-%m-%d)
%X - Same as %T
%R - 24-hour time (%H:%M)
%T - 24-hour time (%H:%M:%S)
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/vanadiel/time.rb', line 297 def strftime(format) source = { 'Y' => @year, 'C' => @year / 100, 'y' => @year % 100, 'm' => @month, 'd' => @mday, 'e' => @mday, 'j' => @yday, 'H' => @hour, 'k' => @hour, 'M' => @min, 'S' => @sec, 'L' => @usec, 'N' => @usec, 'A' => @wday, 'w' => @wday, 's' => @time, 'n' => "\n", 't' => "\t", '%' => '%' } default_padding = { 'e' => ' ', 'k' => ' ', 'A' => ' ', 'n' => ' ', 't' => ' ', '%' => ' ' } default_padding.default = '0' default_width = { 'y' => 2, 'm' => 2, 'd' => 2, 'e' => 2, 'H' => 2, 'k' => 2, 'M' => 2, 'S' => 2, 'j' => 3, 'L' => 3, 'N' => 6 } default_width.default = 0 format.gsub(/%([-_0^#]+)?(\d+)?([FXRT])/) { case $3 when 'F' then '%Y-%m-%d' when 'T', 'X' then '%H:%M:%S' when 'R' then '%H:%M' end }.gsub(/%([-_0^#]+)?(\d+)?([YCymdejHkMSLNAawsnt%])/) {|s| flags = $1; width = $2.to_i; conversion = $3; upcase = false padding = default_padding[conversion] width = default_width[conversion] if width.zero? v = source[conversion] flags.each_char {|c| case c when '-' then padding = nil when '_' then padding = ' ' when '0' then padding = '0' when '^', '#' then upcase = true end } if flags case conversion when 'L', 'N' if (width <= 6) v = v / (100000 / (10 ** (width - 1))) else v = v * (10 ** (width - 6)) end when 'A' v = Vanadiel::Day::DAYNAMES[v] end v = v.to_s if width > 0 && padding && v.length < width v = (padding * (width - v.length)) + v end upcase ? v.upcase : v } end |
#to_earth_time ⇒ ::Time
Returns the value of time as the Earth time object.
418 419 420 |
# File 'lib/vanadiel/time.rb', line 418 def to_earth_time ::Time.at(self.class.vana_to_earth(@time) / ONE_SECOND) end |
#to_f ⇒ Integer
Returns the value of time as an integer number of seconds since C.E. 0001-01-01 00:00:00.
403 404 405 |
# File 'lib/vanadiel/time.rb', line 403 def to_f @time.to_f / ONE_SECOND end |
#to_i ⇒ Float
Returns the value of time as a floating point number of seconds since C.E. 0001-01-01 00:00:00.
396 397 398 |
# File 'lib/vanadiel/time.rb', line 396 def to_i @time / ONE_SECOND end |
#to_s ⇒ String
Returns a string representing time. Equivalent to calling #strftime with a format string of "%Y-%m-%d %H:%M:%S".
411 412 413 |
# File 'lib/vanadiel/time.rb', line 411 def to_s self.strftime('%Y-%m-%d %H:%M:%S') end |