Spec-Zone.ru › Ruby 3.4

класс DateTime

Родитель:
Дата

DateTime

Подкласс Date, легко обрабатывающий дату, час, минуту, секунду и смещение.

Класс DateTime считается устаревшим. Используйте класс Time.

DateTime не учитывает високосные секунды и не отслеживает правила летнего времени.

Объект DateTime создаётся с помощью DateTime::new, DateTime::jd, DateTime::ordinal, DateTime::commercial, DateTime::parse, DateTime::strptime, DateTime::now, Time#to_datetime и т. д.

require 'date'

DateTime.new(2001,2,3,4,5,6)
                    #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

Последний элемент дня, часа, минуты или секунды может быть дробным числом. Точность дробного числа предполагается не более наносекунд.

DateTime.new(2001,2,3.5)
                    #=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>

Необязательный аргумент, смещение, указывает разницу между местным временем и UTC. Например, Rational(3,24) означает на 3 часа вперёд от UTC, а Rational(-5,24) означает на 5 часов назад от UTC. Смещение должно быть от -1 до +1, а его точность предполагается не более секунды. Значение по умолчанию равно нулю (равно UTC).

DateTime.new(2001,2,3,4,5,6,Rational(3,24))
                    #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

Смещение также принимает строковый формат:

DateTime.new(2001,2,3,4,5,6,'+03:00')
                    #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

Необязательный аргумент, день календарной реформы (start), обозначает число юлианского дня, которое должно быть от 2298874 до 2426355 или отрицательная/положительная бесконечность. Значение по умолчанию равно Date::ITALY (2299161=1582-10-15).

Объект DateTime имеет различные методы. См. соответствующие справки.

d = DateTime.parse('3rd Feb 2001 04:05:06+03:30')
                    #=> #<DateTime: 2001-02-03T04:05:06+03:30 ...>
d.hour              #=> 4
d.min               #=> 5
d.sec               #=> 6
d.offset            #=> (7/48)
d.zone              #=> "+03:30"
d += Rational('1.5')
                    #=> #<DateTime: 2001-02-04%16:05:06+03:30 ...>
d = d.new_offset('+09:00')
                    #=> #<DateTime: 2001-02-04%21:35:06+09:00 ...>
d.strftime('%I:%M:%S %p')
                    #=> "09:35:06 PM"
d > DateTime.new(1999)
                    #=> true

Когда следует использовать DateTime, а когда Time?

Распространённое заблуждение, что Уильям Шекспир и Мигель де Сервантес умерли в один и тот же день - настолько, что ЮНЕСКО назвала 23 апреля Международным днём книги из-за этого факта. Однако, поскольку Англия ещё не приняла Григорианскую реформу календаря (и не сделает этого до 1752 года), их смерти разделяют 10 дней. Поскольку класс Time Ruby реализует пролептический григорианский календарь и не имеет понятия о календарной реформе, выразить это с объектами Time невозможно. Здесь на помощь приходит DateTime:

shakespeare = DateTime.iso8601('1616-04-23', Date::ENGLAND)
 #=> Tue, 23 Apr 1616 00:00:00 +0000
cervantes = DateTime.iso8601('1616-04-23', Date::ITALY)
 #=> Sat, 23 Apr 1616 00:00:00 +0000

Уже можно заметить нечто странное - дни недели отличаются. Продолжая:

cervantes == shakespeare
 #=> false
(shakespeare - cervantes).to_i
 #=> 10

Это показывает, что на самом деле они умерли с разницей в 10 дней (на самом деле в 11 дней, так как Сервантес умер на день раньше, но был похоронен 23-го). Мы можем увидеть фактическую дату смерти Шекспира, используя метод gregorian для конвертации:

shakespeare.gregorian
 #=> Tue, 03 May 1616 00:00:00 +0000

Таким образом, есть аргумент, что все торжества, которые проходят 23 апреля в Стратфорде-на-Эйвоне, на самом деле неправильны, поскольку Англия сейчас использует григорианский календарь. Вы можете увидеть это, когда мы пересекаем границу даты реформы:

# start off with the anniversary of Shakespeare's birth in 1751
shakespeare = DateTime.iso8601('1751-04-23', Date::ENGLAND)
 #=> Tue, 23 Apr 1751 00:00:00 +0000

# add 366 days since 1752 is a leap year and April 23 is after February 29
shakespeare + 366
 #=> Thu, 23 Apr 1752 00:00:00 +0000

# add another 365 days to take us to the anniversary in 1753
shakespeare + 366 + 365
 #=> Fri, 04 May 1753 00:00:00 +0000

Как видно, если мы точно отслеживаем количество солнечных лет с момента рождения Шекспира, то правильная годовщина была бы 4 мая, а не 23 апреля.

Итак, когда следует использовать DateTime в Ruby, а когда Time? Скорее всего, вы захотите использовать Time, так как ваше приложение, вероятно, работает с текущими датами и временами. Однако, если вам нужно работать с датами и временами в историческом контексте, вы захотите использовать DateTime, чтобы избежать тех же ошибок, что и ЮНЕСКО. Если вам также нужно работать с часовыми поясами, то удачи - просто имейте в виду, что вы, вероятно, будете работать с местным солнечным временем, поскольку только в 19 веке введение железных дорог потребовало стандартного времени и, в конечном итоге, часовых поясов.

Публичные методы класса

_strptime(string[, format='%FT%T%z']) → hash
Исходный код
static VALUE
datetime_s__strptime(int argc, VALUE *argv, VALUE klass)
{
    return date_s__strptime_internal(argc, argv, klass, "%FT%T%z");
}

Разбирает заданное представление даты и времени с заданным шаблоном и возвращает хэш разобранных элементов. _strptime не поддерживает указание флагов и ширины в отличие от strftime.

См. также strptime(3) и strftime.

civil (*args)
Исходный код
static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
    return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
}

То же самое, что и DateTime.new.

commercial([cwyear=-4712[, cweek=1[, cwday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime
Исходный код
static VALUE
datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int w, d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    w = 1;
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 8:
        val2sg(vsg, sg);
      case 7:
        val2off(vof, rof);
      case 6:
        check_numeric(vs, "second");
        num2int_with_frac(s, positive_inf);
      case 5:
        check_numeric(vmin, "minute");
        num2int_with_frac(min, 5);
      case 4:
        check_numeric(vh, "hour");
        num2int_with_frac(h, 4);
      case 3:
        check_numeric(vd, "cwday");
        num2int_with_frac(d, 3);
      case 2:
        check_numeric(vw, "cweek");
        w = NUM2INT(vw);
      case 1:
        check_numeric(vy, "year");
        y = vy;
    }

    {
        VALUE nth;
        int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_commercial_p(y, w, d, sg,
                                &nth, &ry,
                                &rw, &rd, &rjd,
                                &ns))
            rb_raise(eDateError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(eDateError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}

Создает объект DateTime, обозначающий заданную неделю.

DateTime.commercial(2001) #=> #<DateTime: 2001-01-01T00:00:00+00:00 ...>
DateTime.commercial(2002) #=> #<DateTime: 2001-12-31T00:00:00+00:00 ...>
DateTime.commercial(2001,5,6,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) → datetime
Исходный код
static VALUE
datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__httpdate(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создает новый объект DateTime, выполняя синтаксический разбор строки в соответствии с некоторым форматом RFC 2616.

DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
                          #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

Вызывает исключение ArgumentError, когда длина строки больше, чем limit. Можно остановить эту проверку, передав limit: nil, но учтите, что разбор может занять много времени.

iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__iso8601(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создает новый объект DateTime, выполняя синтаксический разбор строки в соответствии с некоторыми типичными форматами ISO 8601.

DateTime.iso8601('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.iso8601('20010203T040506+0700')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.iso8601('2001-W05-6T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Вызывает исключение ArgumentError, когда длина строки больше, чем limit. Можно остановить эту проверку, передав limit: nil, но учтите, что разбор может занять много времени.

jd([jd=0[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]) → datetime
Исходный код
static VALUE
datetime_s_jd(int argc, VALUE *argv, VALUE klass)
{
    VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret;
    int h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "06", &vjd, &vh, &vmin, &vs, &vof, &vsg);

    jd = INT2FIX(0);

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 6:
        val2sg(vsg, sg);
      case 5:
        val2off(vof, rof);
      case 4:
        check_numeric(vs, "second");
        num2int_with_frac(s, positive_inf);
      case 3:
        check_numeric(vmin, "minute");
        num2int_with_frac(min, 3);
      case 2:
        check_numeric(vh, "hour");
        num2int_with_frac(h, 2);
      case 1:
        check_numeric(vjd, "jd");
        num2num_with_frac(jd, 1);
    }

    {
        VALUE nth;
        int rh, rmin, rs, rjd, rjd2;

        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(eDateError, "invalid date");
        canon24oc();

        decode_jd(jd, &nth, &rjd);
        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}

Создает объект DateTime, обозначающий заданный хронологический юлианский день.

DateTime.jd(2451944)      #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.jd(2451945)      #=> #<DateTime: 2001-02-04T00:00:00+00:00 ...>
DateTime.jd(Rational('0.5'))
                          #=> #<DateTime: -4712-01-01T12:00:00+00:00 ...>
jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__jisx0301(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создает новый объект DateTime, выполняя синтаксический разбор строки в соответствии с некоторыми типичными форматами JIS X 0301.

DateTime.jisx0301('H13.02.03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Для года без эры, в формате legacy, предполагается Хэйсэй.

DateTime.jisx0301('13.02.03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Вызывает исключение ArgumentError, когда длина строки больше, чем limit. Можно остановить эту проверку, передав limit: nil, но учтите, что разбор может занять много времени.

json_create (object)
Исходный код
# File ext/json/lib/json/add/date_time.rb, line 10
def self.json_create(object)
  args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
  of_a, of_b = object['of'].split('/')
  if of_b and of_b != '0'
    args << Rational(of_a.to_i, of_b.to_i)
  else
    args << of_a
  end
  args << object['sg']
  civil(*args)
end

См. as_json.

new (*args)
Исходный код
static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
    return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
}

То же самое, что и DateTime.new.

now([start=Date::ITALY]) → datetime
Исходный код
static VALUE
datetime_s_now(int argc, VALUE *argv, VALUE klass)
{
    VALUE vsg, nth, ret;
    double sg;
#ifdef HAVE_CLOCK_GETTIME
    struct timespec ts;
#else
    struct timeval tv;
#endif
    time_t sec;
    struct tm tm;
    long sf, of;
    int y, ry, m, d, h, min, s;

    rb_scan_args(argc, argv, "01", &vsg);

    if (argc < 1)
        sg = DEFAULT_SG;
    else
        sg = NUM2DBL(vsg);

#ifdef HAVE_CLOCK_GETTIME
    if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
        rb_sys_fail("clock_gettime");
    sec = ts.tv_sec;
#else
    if (gettimeofday(&tv, NULL) == -1)
        rb_sys_fail("gettimeofday");
    sec = tv.tv_sec;
#endif
    tzset();
    if (!localtime_r(&sec, &tm))
        rb_sys_fail("localtime");

    y = tm.tm_year + 1900;
    m = tm.tm_mon + 1;
    d = tm.tm_mday;
    h = tm.tm_hour;
    min = tm.tm_min;
    s = tm.tm_sec;
    if (s == 60)
        s = 59;
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
    of = tm.tm_gmtoff;
#elif defined(HAVE_TIMEZONE)
#if defined(HAVE_ALTZONE) && !defined(_AIX)
    of = (long)-((tm.tm_isdst > 0) ? altzone : timezone);
#else
    of = (long)-timezone;
    if (tm.tm_isdst) {
        time_t sec2;

        tm.tm_isdst = 0;
        sec2 = mktime(&tm);
        of += (long)difftime(sec2, sec);
    }
#endif
#elif defined(HAVE_TIMEGM)
    {
        time_t sec2;

        sec2 = timegm(&tm);
        of = (long)difftime(sec2, sec);
    }
#else
    {
        struct tm tm2;
        time_t sec2;

        if (!gmtime_r(&sec, &tm2))
            rb_sys_fail("gmtime");
        tm2.tm_isdst = tm.tm_isdst;
        sec2 = mktime(&tm2);
        of = (long)difftime(sec, sec2);
    }
#endif
#ifdef HAVE_CLOCK_GETTIME
    sf = ts.tv_nsec;
#else
    sf = tv.tv_usec * 1000;
#endif

    if (of < -DAY_IN_SECONDS || of > DAY_IN_SECONDS) {
        of = 0;
        rb_warning("invalid offset is ignored");
    }

    decode_year(INT2FIX(y), -1, &nth, &ry);

    ret = d_complex_new_internal(klass,
                                 nth, 0,
                                 0, LONG2NUM(sf),
                                 (int)of, GREGORIAN,
                                 ry, m, d,
                                 h, min, s,
                                 HAVE_CIVIL | HAVE_TIME);
    {
        get_d1(ret);
        set_sg(dat, sg);
    }
    return ret;
}

Создает объект DateTime, обозначающий текущее время.

DateTime.now              #=> #<DateTime: 2011-06-11T21:20:44+09:00 ...>
ordinal([year=-4712[, yday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]) → datetime
Исходный код
static VALUE
datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 7:
        val2sg(vsg, sg);
      case 6:
        val2off(vof, rof);
      case 5:
        check_numeric(vs, "second");
        num2int_with_frac(s, positive_inf);
      case 4:
        check_numeric(vmin, "minute");
        num2int_with_frac(min, 4);
      case 3:
        check_numeric(vh, "hour");
        num2int_with_frac(h, 3);
      case 2:
        check_numeric(vd, "yday");
        num2int_with_frac(d, 2);
      case 1:
        check_numeric(vy, "year");
        y = vy;
    }

    {
        VALUE nth;
        int ry, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_ordinal_p(y, d, sg,
                             &nth, &ry,
                             &rd, &rjd,
                             &ns))
            rb_raise(eDateError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(eDateError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}

Создает объект DateTime, обозначающий заданную порядковую дату.

DateTime.ordinal(2001,34) #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.ordinal(2001,34,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.ordinal(2001,-332,-20,-55,-54,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_parse(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, comp, sg, opt;

    argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME);
      case 1:
        comp = Qtrue;
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 2;
        VALUE argv2[3], hash;
        argv2[0] = str;
        argv2[1] = comp;
        argv2[2] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__parse(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Разбирает заданное представление даты и времени и создает объект DateTime.

Этот метод не является валидатором. Если входная строка строго не соответствует допустимым форматам, вы можете получить загадочный результат. Стоит рассмотреть использование DateTime.strptime вместо этого метода.

Если второй необязательный аргумент имеет значение true, а обнаруженный год находится в диапазоне от «00» до «99», делает его полным.

DateTime.parse('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.parse('20010203T040506+0700')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.parse('3rd Feb 2001 04:05:06 PM')
                          #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>

Вызывает исключение ArgumentError, когда длина строки больше, чем limit. Можно остановить эту проверку, передав limit: nil, но учтите, что разбор может занять много времени.

rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__rfc2822(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создает новый объект DateTime, выполняя синтаксический разбор строки в соответствии с некоторыми типичными форматами RFC 2822.

DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
                         #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Вызывает исключение ArgumentError, когда длина строки больше, чем limit. Можно остановить эту проверку, передав limit: nil, но учтите, что разбор может занять много времени.

rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__rfc3339(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создаёт новый объект DateTime, разобрав строку по одному из типичных форматов RFC 3339.

DateTime.rfc3339('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Вызовет ArgumentError, если длина строки превысит limit. Вы можете отключить эту проверку, передав limit: nil, но обратите внимание, что это может занять много времени.

rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__rfc2822(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создаёт новый объект DateTime, разобрав строку по одному из типичных форматов RFC 2822.

DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
                         #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Вызовет ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав limit: nil, но обратите внимание, что это может занять много времени.

strptime([string='-4712-01-01T00:00:00+00:00'[, format='%FT%T%z'[ ,start=Date::ITALY]]]) → datetime
Исходный код
static VALUE
datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, fmt, sg;

    rb_scan_args(argc, argv, "03", &str, &fmt, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME);
      case 1:
        fmt = rb_str_new2("%FT%T%z");
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE argv2[2], hash;

        argv2[0] = str;
        argv2[1] = fmt;
        hash = date_s__strptime(2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Парсит заданное представление даты и времени с заданным шаблоном и создаёт объект DateTime. strptime не поддерживает указание флагов и ширины в отличие от strftime.

DateTime.strptime('2001-02-03T04:05:06+07:00', '%Y-%m-%dT%H:%M:%S%z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('03-02-2001 04:05:06 PM', '%d-%m-%Y %I:%M:%S %p')
                          #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
DateTime.strptime('2001-W05-6T04:05:06+07:00', '%G-W%V-%uT%H:%M:%S%z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('2001 04 6 04 05 06 +7', '%Y %U %w %H %M %S %z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('2001 05 6 04 05 06 +7', '%Y %W %u %H %M %S %z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('-1', '%s')
                          #=> #<DateTime: 1969-12-31T23:59:59+00:00 ...>
DateTime.strptime('-1000', '%Q')
                          #=> #<DateTime: 1969-12-31T23:59:59+00:00 ...>
DateTime.strptime('sat3feb014pm+7', '%a%d%b%y%H%p%z')
                          #=> #<DateTime: 2001-02-03T16:00:00+07:00 ...>

См. также strptime(3) и strftime.

xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime
Исходный код
static VALUE
datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);

    switch (argc) {
      case 0:
        str = rb_str_new2(JULIAN_EPOCH_DATETIME);
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__xmlschema(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

Создаёт новый объект DateTime, разобрав строку по одному из типичных форматов XML Schema.

DateTime.xmlschema('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

Вызовет ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав limit: nil, но обратите внимание, что это может занять много времени.

Публичные методы экземпляра

as_json (*)
Исходный код
# File ext/json/lib/json/add/date_time.rb, line 39
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'y' => year,
    'm' => month,
    'd' => day,
    'H' => hour,
    'M' => min,
    'S' => sec,
    'of' => offset.to_s,
    'sg' => start,
  }
end

Методы DateTime#as_json и DateTime.json_create могут использоваться для сериализации и десериализации объекта DateTime; см. Marshal.

Метод DateTime#as_json сериализует self, возвращая 2-элементный хэш, представляющий self:

require 'json/add/datetime'
x = DateTime.now.as_json
# => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}

Метод JSON.create десериализует такой хэш, возвращая объект DateTime:

DateTime.json_create(x) # BUG? Raises Date::Error "invalid date"
deconstruct_keys(array_of_names_or_nil) → hash
Исходный код
static VALUE
dt_lite_deconstruct_keys(VALUE self, VALUE keys)
{
    return deconstruct_keys(self, keys, /* is_datetime=true */ 1);
}

Возвращает хэш пар имя/значение для использования в сопоставлении с образцом. Возможные ключи: :year, :month, :day, :wday, :yday, :hour, :min, :sec, :sec_fraction, :zone.

Возможные варианты использования:

dt = DateTime.new(2022, 10, 5, 13, 30)

if d in wday: 1..5, hour: 10..18  # uses deconstruct_keys underneath
  puts "Working time"
end
#=> prints "Working time"

case dt
in year: ...2022
  puts "too old"
in month: ..9
  puts "quarter 1-3"
in wday: 1..5, month:
  puts "working day in month #{month}"
end
#=> prints "working day in month 10"

Обратите внимание, что деконструкция по образцу также может быть объединена с проверкой класса:

if d in DateTime(wday: 1..5, hour: 10..18, day: ..7)
  puts "Working time, first week of the month"
end
hour → integer
Исходный код
static VALUE
d_lite_hour(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_hour(dat));
}

Возвращает час в диапазоне (0..23):

DateTime.new(2001, 2, 3, 4, 5, 6).hour # => 4
iso8601([n=0]) → string
Исходный код
static VALUE
dt_lite_iso8601(int argc, VALUE *argv, VALUE self)
{
    long n = 0;

    rb_check_arity(argc, 0, 1);
    if (argc >= 1)
        n = NUM2LONG(argv[0]);

    return rb_str_append(strftimev("%Y-%m-%d", self, set_tmx),
                         iso8601_timediv(self, n));
}

Этот метод эквивалентен strftime(‘%FT%T%:z’). Необязательный аргумент n — это количество цифр для дробных секунд.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"
Также является псевдонимом для: xmlschema
jisx0301([n=0]) → string
Исходный код
static VALUE
dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
{
    long n = 0;

    rb_check_arity(argc, 0, 1);
    if (argc >= 1)
        n = NUM2LONG(argv[0]);

    return rb_str_append(d_lite_jisx0301(self),
                         iso8601_timediv(self, n));
}

Возвращает строку в формате JIS X 0301. Необязательный аргумент n — это количество цифр для дробных секунд.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').jisx0301(9)
                          #=> "H13.02.03T04:05:06.123456789+07:00"
min → integer
Исходный код
static VALUE
d_lite_min(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_min(dat));
}

Возвращает минуту в диапазоне (0..59):

DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5
Также является псевдонимом для: minute
minute
Псевдоним для: min
new_offset([offset=0]) → date
Исходный код
static VALUE
d_lite_new_offset(int argc, VALUE *argv, VALUE self)
{
    VALUE vof;
    int rof;

    rb_scan_args(argc, argv, "01", &vof);

    rof = 0;
    if (argc >= 1)
        val2off(vof, rof);

    return dup_obj_with_new_offset(self, rof);
}

Создаёт копию объекта и сбрасывает его смещение.

d = DateTime.new(2001,2,3,4,5,6,'-02:00')
                          #=> #<DateTime: 2001-02-03T04:05:06-02:00 ...>
d.new_offset('+09:00')    #=> #<DateTime: 2001-02-03T15:05:06+09:00 ...>
offset → rational
Исходный код
static VALUE
d_lite_offset(VALUE self)
{
    get_d1(self);
    return m_of_in_day(dat);
}

Возвращает смещение.

DateTime.parse('04pm+0730').offset        #=> (5/16)
rfc3339([n=0]) → string
Исходный код
static VALUE
dt_lite_rfc3339(int argc, VALUE *argv, VALUE self)
{
    return dt_lite_iso8601(argc, argv, self);
}

Этот метод эквивалентен strftime(‘%FT%T%:z’). Необязательный аргумент n — это количество цифр для дробных секунд.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').rfc3339(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"
sec → integer
Исходный код
static VALUE
d_lite_sec(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_sec(dat));
}

Возвращает секунду в диапазоне (0..59):

DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6
Также является псевдонимом для: second
sec_fraction → rational
Исходный код
static VALUE
d_lite_sec_fraction(VALUE self)
{
    get_d1(self);
    return m_sf_in_sec(dat);
}

Возвращает дробную часть секунды в диапазоне (Rational(0, 1)…Rational(1, 1)):

DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2)
Также является псевдонимом для: second_fraction
second
Псевдоним для: sec
second_fraction
Псевдоним для: sec_fraction
strftime(format = '%FT%T%:z') → string
Исходный код
static VALUE
dt_lite_strftime(int argc, VALUE *argv, VALUE self)
{
    return date_strftime_internal(argc, argv, self,
                                  "%Y-%m-%dT%H:%M:%S%:z", set_tmx);
}

Возвращает строковое представление self, отформатированное в соответствии с заданным +format:

DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"

Для других форматов см. Форматы дат и времени:

to_date → date
Исходный код
static VALUE
datetime_to_date(VALUE self)
{
    get_d1a(self);

    if (simple_dat_p(adat)) {
        VALUE new = d_lite_s_alloc_simple(cDate);
        {
            get_d1b(new);
            bdat->s = adat->s;
            bdat->s.jd = m_local_jd(adat);
            return new;
        }
    }
    else {
        VALUE new = d_lite_s_alloc_simple(cDate);
        {
            get_d1b(new);
            copy_complex_to_simple(new, &bdat->s, &adat->c);
            bdat->s.jd = m_local_jd(adat);
            bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
            return new;
        }
    }
}

Возвращает объект Date, обозначающий self.

to_datetime → self
Исходный код
static VALUE
datetime_to_datetime(VALUE self)
{
    return self;
}

Возвращает self.

to_json (*args)
Исходный код
# File ext/json/lib/json/add/date_time.rb, line 62
def to_json(*args)
  as_json.to_json(*args)
end

Возвращает строку JSON, представляющую self:

require 'json/add/datetime'
puts DateTime.now.to_json

Вывод:

{"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0}
to_s → строка
Исходный код
static VALUE
dt_lite_to_s(VALUE self)
{
    return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
}

Возвращает строку в формате ISO 8601. (Этот метод не использует расширенные представления.)

DateTime.new(2001,2,3,4,5,6,'-7').to_s
                         #=> "2001-02-03T04:05:06-07:00"
to_time → время
Исходный код
static VALUE
datetime_to_time(VALUE self)
{
    get_d1(self);

    if (m_julian_p(dat)) {
        VALUE g = d_lite_gregorian(self);
        get_d1a(g);
        dat = adat;
        self = g;
    }

    {
        VALUE t;

        t = rb_funcall(rb_cTime,
                   rb_intern("new"),
                   7,
                   m_real_year(dat),
                   INT2FIX(m_mon(dat)),
                   INT2FIX(m_mday(dat)),
                   INT2FIX(m_hour(dat)),
                   INT2FIX(m_min(dat)),
                   f_add(INT2FIX(m_sec(dat)),
                         m_sf_in_sec(dat)),
                   INT2FIX(m_of(dat)));
        RB_GC_GUARD(self); /* may be the converted gregorian */
        return t;
    }
}

Возвращает объект Time, который обозначает текущий объект.

xmlschema([n=0]) → строка

Этот метод эквивалентен strftime(‘%FT%T%:z’). Необязательный аргумент n — количество цифр для дробной части секунды.

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"
Псевдоним для: iso8601
zone → строка
Исходный код
static VALUE
d_lite_zone(VALUE self)
{
    get_d1(self);
    return m_zone(dat);
}

Возвращает часовой пояс.

DateTime.parse('04pm+0730').zone          #=> "+07:30"

Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API