Time

Time (시간·날짜)

Time 객체는 날짜와 시간을 나타내요. 예를 들어 이렇게 만들 수 있어요.

Time.new(2000, 1, 1, 0, 0, 0)  # => 2000-01-01 00:00:00 -0600

그 값은 하나의 숫자로도 표현되지만(Epoch Seconds 참고), 필요에 따라 부품별로 다루기도 편해요.

t = Time.new(2000, 12, 31, 23, 59, 59.5)  # => 2000-12-31 23:59:59.5 -0600
t.year    # => 2000
t.month   # => 12
t.mday    # => 31
t.hour    # => 23
t.min     # => 59
t.sec     # => 59
t.subsec  # => (1/2)

출처: Ruby 3.3 API

본문

Epoch Seconds (에포크 초)

에포크 초(epoch seconds)는 Unix Epoch(1970년 1월 1일) 이후의 정확한 초 수(분수 초 포함)예요. Time.to_r로 정확히 얻을 수 있어요.

Time.at(0).to_r          # => (0/1)
Time.at(0.999999).to_r   # => (9007190247541737/9007199254740992)

반면 Time#to_iTime#to_f는 서브초를 반올림하거나 잘라낸 값을 돌려줄 수 있어요.

Time 만들기 (Methods for Creating)

  • ::new - 지정한 인자(년, 월 등)와 선택적 타임존 값으로 새 time을 돌려줘요. new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil)
  • ::local (::mktime 별칭) - ::new과 같되 타임존이 로컬 타임존이에요.
  • ::utc (::gm 별칭) - ::new과 같되 타임존이 UTC예요.
  • ::at - 에포크 이후 초를 기준으로 새 time을 돌려줘요.
  • ::now - 현재 시스템 시간으로 새 time을 돌려줘요.
  • + (plus) - 주어진 초만큼 늘어난 새 time을 돌려줘요.
  • - (minus) - 주어진 초만큼 줄어든 새 time을 돌려줘요.

아무 인자 없이 Time.new를 호출하면 Time.now의 값이 돌아와요.

Time.new(2002)        #=> 2002-01-01 00:00:00 -0500
Time.new(2002, 10)    #=> 2002-10-01 00:00:00 -0500
Time.new(2002,10,31)  #=> 2002-10-31 00:00:00 -0500

UTC 오프셋도 줄 수 있어요.

Time.new(2002,10,31,2,2,2,"+02:00")  #=> 2002-10-31 02:02:02 +0200

타임존 객체도 가능해요.

zone = timezone("Europe/Athens")  # Eastern European Time, UTC+2
Time.new(2002,10,31,2,2,2,zone)  #=> 2002-10-31 02:02:02 +0200

값 가져오기 (Methods for Fetching)

  • year - 연도. month(mon 별칭) - 월. mday(day 별칭) - 일.
  • hour - 시. min - 분. sec - 초.
  • usec(tv_usec 별칭) - 서브초 값의 마이크로초 수. nsec(tv_nsec 별칭) - 서브초의 나노초 수. subsec - 정확한 서브초.
  • wday - 정수 요일 값(0 == 일요일). yday - 정수 연중 일수(1 == 1월 1일).
  • hash - 정수 해시 값.
  • utc_offset(gmt_offset, gmtoff 별칭) - UTC와의 오프셋(초).
  • to_f - 에포크 이후 초의 float 값. to_i(tv_sec 별칭) - 정수 값. to_r - Rational 값.
  • zone - time의 타임존 문자열 표현.

질의하기 (Methods for Querying)

  • utc?(gmt? 별칭) - UTC인지. dst?(isdst 별칭) - DST(일광 절약 시간)인지.
  • sunday? ~ saturday? - 각 요일인지.

비교하기 (Methods for Comparing)

  • <=> - self를 다른 time과 비교. eql? - 다른 time과 같은지.

변환하기 (Methods for Converting)

  • asctime(ctime 별칭) - 문자열로. inspect - 자세히 문자열로. strftime - 주어진 형식에 따라 문자열로. to_a - 10개 요소 배열로. to_s - 문자열 표현으로.
  • getutc(getgm 별칭) - UTC로 변환된 새 time. getlocal - 로컬 시간으로 변환된 새 time.
  • utc(gmtime 별칭) - 제자리에서 UTC로 변환. localtime - 제자리에서 로컬 시간으로 변환.
  • deconstruct_keys - 패턴 매칭에 쓰이는 부품 해시.
  • to_date(Date로), to_datetime(DateTime으로), to_time(self 반환).

반올림하기 (Methods for Rounding)

  • round(ndigits = 0) - 서브초를 반올림한 새 time. ceil(ndigits = 0) - 올림한 새 time. floor(ndigits = 0) - 내림한 새 time.

상수 (Constants)

  • Time::VERSION

클래스 메서드 상세

at(time, subsec = false, unit = :microsecond, in: nil)

주어진 인자에 기반한 새 Time 객체를 돌려줘요. 필수 인자 time은 다음 중 하나일 수 있어요.

  • Time 객체 (반환 time의 기준 값; 선택 키워드 인자 in:에 영향받음)
  • 에포크 초의 숫자 값
t = Time.new(2000,12,31,23,59,59)  # => 2000-12-31 23:59:59 -0600
secs = t.to_i                       # => 978328799
Time.at(secs)                       # => 2000-12-31 23:59:59 -0600
Time.at(secs + 0.5)                 # => 2000-12-31 23:59:59.5 -0600
Time.at(1000000000)                 # => 2001-09-08 20:46:40 -0500

선택 숫자 인자 subsec와 선택 심볼 인자 unit(:microsecond, :millisecond, :nanosecond 등)이 서브초를 지정해요.

local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) / mktime

Time.utc과 같되, 반환된 time의 타임존이 로컬 타임존(UTC가 아님)이에요.

Time.local(0,1,2,3,4,5,6)   # => 0000-01-02 03:04:05.000006 -0600
Time.local(0,1,2,3,4,5,6,7,8,9)  # => 0005-04-03 02:01:00 -0600

now(in: nil)

현재 시스템 시간으로 새 Time 객체를 만들어요. 인자 없는 Time.new와 같아요.

Time.now             # => 2009-06-24 12:39:54 +0900
Time.now(in: '+04:00')  # => 2009-06-24 07:39:54 +0400

parse(date, now=self.now) { |year| ... }

Time의 문자열 표현을 휴리스틱(heuristic)으로 파싱해요. 검증기(validator)로 동작하지 않아요. 형식이 엄격하지 않은 입력이면 이상한 결과가 나올 수 있어요. 가능하면 이 메서드 대신 Time.strptime을 고려하세요. require 'time'가 필요해요.

require 'time'
Time.parse("2010-10-31")  # => 2010-10-31 00:00:00 ...

strptime(date, format, now=self.now) { |year| ... }

parse와 비슷하되 휴리스틱 대신 명시적 형식 문자열 format을 받아요. 블록을 주면 date에 기술된 연도를 블록이 변환해요.

타임존 문자열 파서

  • httpdate(date) - RFC 2616의 HTTP-date를 파싱해 Time으로. 형식 준수 실패 시 ArgumentError.
  • rfc2822(date) (rfc822 별칭) - RFC 2822의 date-time을 파싱.
  • xmlschema(time) (iso8601 별칭) - XML Schema dateTime(ISO 8601의 제한 버전)을 파싱.
  • zone_offset(zone, year=self.now.year) - 지정 time zone이 UTC와 다른 초 수를 반환.

utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) / gm

UTC 타임존의 새 Time 객체를 돌려줘요.

Time.utc(2000)   # => 2000-01-01 00:00:00 UTC
Time.utc(-2000)  # => -2000-01-01 00:00:00 UTC

인스턴스 메서드 상세

+ / -

t = Time.new(2000)            # => 2000-01-01 00:00:00 -0600
t + (60*60*24)                # => 2000-01-02 00:00:00 -0600
t + 0.5                       # => 2000-01-01 00:00:00.5 -0600
t - (60*60*24)                # => 1999-12-31 00:00:00 -0600
t - 0.5                       # => 1999-12-31 23:59:59.5 -0600

self - other_time은 두 time의 초 차이를 Float으로 돌려줘요.

<=> , eql?

self를 다른 time과 비교해 -1/0/1/nil을, eql?은 값이 완전히 같으면 true를 돌려줘요.

t1 = Time.new(2010); t2 = Time.new(2011)
t1 == t2   # => false
t1 == t1   # => true
t1 < t2    # => true
Time.new(2010,10,31).between?(t1, t2)  # => true  (Comparable)

as_json / to_json / json_create

Time#as_jsonTime.json_createTime 객체를 직렬화·역직렬화할 수 있어요. require 'json/add/time'가 필요해요.

require 'json/add/time'
x = Time.now.as_json  # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644}

ceil(ndigits = 0) / floor(ndigits = 0) / round(ndigits = 0)

t = Time.utc(2010,3,30,5,43,25.123456789r)
t          # => 2010-03-30 05:43:25.123456789 UTC
t.ceil     # => 2010-03-30 05:43:26 UTC
t.ceil(2)  # => 2010-03-30 05:43:25.13 UTC
t.floor    # => 2010-03-30 05:43:25 UTC
t.floor(2) # => 2010-03-30 05:43:25.12 UTC
t.round    # => 2010-03-30 05:43:25 UTC
t.round(2) # => 2010-03-30 05:43:25.12 UTC

ctime / asctime

strftime('%a %b %e %T %Y')(약칭 strftime('%c'))로 형식화한 문자열 표현을 돌려줘요.

t = Time.new(2000,12,31,23,59,59,0.5)
t.ctime  # => "Sun Dec 31 23:59:59 2000"

deconstruct_keys(array_of_names_or_nil)

패턴 매칭에 사용할 이름/값 쌍 해시를 돌려줘요. 가능한 키: :year, :month, :day, :yday, :wday, :hour, :min, :sec, :subsec, :dst, :zone.

t = Time.utc(2022,10,5,21,25,30)
if t in {wday: 3, day: ..7}   # uses deconstruct_keys underneath
  puts "first Wednesday of the month"
end

getlocal(zone = nil) / getutc / localtime / utc

t = Time.utc(2000)          # => 2000-01-01 00:00:00 UTC
t.getlocal                  # => 1999-12-31 18:00:00 -0600
t.getlocal('+12:00')        # => 2000-01-01 12:00:00 +1200
t.getutc                    # => 2000-01-01 00:00:00 UTC
t.localtime                 # => 2000-01-01 00:00:00 -0600 (로컬로 변환된 self 또는 새 Time)
t.utc                       # => UTC로 변환

strftime(format_string)

주어진 형식 문자열에 따라 self의 문자열 표현을 돌려줘요.

to_a

self를 나타내는 10개 요소 배열을 돌려줘요.

Time.utc(2000,1,1).to_a
# => [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"]
#    [sec, min, hour, day, mon, year, wday, yday, dst?, zone]

to_i / to_f / to_r

Time.utc(1970,1,1,0,0,0).to_i        # => 0
Time.utc(1970,1,1,0,0,0,999999).to_i # => 0  (subseconds are truncated)
Time.utc(1970,1,1,0,0,0).to_f        # => 0.0
Time.now.to_r                        # => (16571402750320203/10000000)

utc? / dst? / utc_offset / zone / wday / yday

now = Time.now
now.utc?          # => false
now.getutc.utc?   # => true
Time.utc(2000,1,1).utc_offset   # => 0
Time.local(2000,1,1).utc_offset # => -21600  # -6*3600
Time.utc(2000,1,1).zone         # => "UTC"

아래 메서드들은 각각 해당하는 값을 정수로 돌려줘요: year, mon(month), mday(day), hour, min, sec, wday(0..6, 일요일=0), yday(1..366), usec/tv_usec, nsec/tv_nsec, subsec, hash. 그리고 요일 질의 메서드 sunday?~saturday?는 해당 요일이면 true를 돌려줘요.

더 알아보기

타임존 지정자(Timezone Specifiers)의 자세한 형태(±HH:MM 문자열, 단일 문자, 정수 오프셋, 타임존 객체, 타임존 이름)와 %Z/%z 같은 형식 사양은 원문 rdoc의 "Timezone Specifiers", "Formats for Dates and Times" 섹션을 참고하세요.