class Strftime

Strftime is a faster way to format time string like strftime(3).

@example

generator = Strftime.new('%Y-%m-%dT%H:%M:%S%z')
generator.source #=> "%Y-%m-%dT%H:%M:%S%z"
generator.exec(Time.now) #=> 2017-12-25T12:34:56+09:00

Public Class Methods

new(p1) click to toggle source

@overload new(format)

@param format [String] strftime(3) style format string.

returns generator object

static VALUE
strftime_init(VALUE self, VALUE fmt)
{
    struct strftime_object *tobj;
    void **isns;
    size_t rlen;
    StringValueCStr(fmt);
    TypedData_Get_Struct(self, struct strftime_object, &strftime_data_type,
                         tobj);
    isns = strftime_compile(RSTRING_PTR(fmt), RSTRING_LEN(fmt), &rlen);
    tobj->isns = isns;
    tobj->fmt = rb_str_new_frozen(fmt);
    tobj->result_length = rlen;
    return self;
}

Public Instance Methods

exec(p1) click to toggle source

@overload exec(str)

@param str [String] string to parse

@return [Time] the time object given string means

Return a formatted datetime string

static VALUE
strftime_exec(VALUE self, VALUE time)
{
    struct strftime_object *sobj;
    struct timespec ts = rb_time_timespec(time);
#ifdef HAVE_RB_TIME_UTC_OFFSET
    int gmtoff = FIX2INT(rb_time_utc_offset(time));
#else
    int gmtoff = NUM2INT(rb_funcall(time, id_gmtoff, 0));
#endif
    GetStrftimeval(self, sobj);

    return strftime_exec0(sobj->isns, sobj->fmt, &ts, gmtoff, sobj->result_length);
}
execi(p1) click to toggle source

@overload execi(epoch)

@param epoch [Integer] Unix epoch

@return [String] the formatted datetime string

Return a formatted datetime string

static VALUE
strftime_execi(VALUE self, VALUE epoch)
{
    struct strftime_object *tobj;
    struct timespec ts;
    GetStrftimeval(self, tobj);

    if (RB_INTEGER_TYPE_P(epoch)) {
        ts.tv_sec = NUM2TIMET(epoch);
        ts.tv_nsec = 0;
    } else if (RB_FLOAT_TYPE_P(epoch)) {
        double d = NUM2DBL(epoch);
        ts.tv_sec = (time_t)d;
        ts.tv_nsec = (int)((int64_t)(d * 1000000000) % 1000000000);
    } else if (RB_TYPE_P(epoch, T_RATIONAL)) {
        ts.tv_sec = NUM2TIMET(epoch);
        ts.tv_nsec = NUM2INT(rb_funcall(rb_funcall(epoch, '*', 1, INT2FIX(1000000000)), '%', 1, INT2FIX(1000000000)));
    }

    return strftime_exec0(tobj->isns, tobj->fmt, &ts, 0, tobj->result_length);
}
initialize_copy(p1) click to toggle source

@api private For Ruby VM internal.

static VALUE
strftime_init_copy(VALUE copy, VALUE self)
{
    struct strftime_object *tobj, *tcopy;

    if (!OBJ_INIT_COPY(copy, self)) return copy;
    GetStrftimeval(self, tobj);
    GetNewStrftimeval(copy, tcopy);
    MEMCPY(tcopy, tobj, struct strftime_object, 1);

    return copy;
}
source() click to toggle source

@overload source @return [String] source format string

static VALUE
strftime_source(VALUE self)
{
    struct strftime_object *tobj;
    GetStrftimeval(self, tobj);

    return tobj->fmt;
}