класс 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 веке необходимость в стандартном времени и, в конечном итоге, часовых поясах стала актуальной из-за введения железных дорог.
Публичные методы класса
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.
static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
} То же, что и DateTime.new.
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 ...>
static VALUE
datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
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, но обратите внимание, что это может занять много времени для анализа.
static VALUE
datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01T00:00:00+00:00");
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, но обратите внимание, что это может занять много времени для анализа.
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 ...>
static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01T00:00:00+00:00");
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, но обратите внимание, что это может занять много времени для анализа.
# File ext/json/lib/json/add/date_time.rb, line 12
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 Десериализует строку JSON, преобразуя год y, месяц m, день d, час H, минуту M, секунду S, смещение of и день календарной реформы sg в DateTime.
static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
} То же, что и DateTime.new.
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 ...>
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 ...>
static VALUE
datetime_s_parse(int argc, VALUE *argv, VALUE klass)
{
VALUE str, comp, sg, opt;
rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01T00:00:00+00:00");
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 вместо этого метода.
Если второй необязательный аргумент истинен, а обнаруженный год находится в диапазоне от «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, но обратите внимание, что это может занять много времени для анализа.
static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
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, но обратите внимание, что это может занять много времени для анализа.
static VALUE
datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01T00:00:00+00:00");
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, но обратите внимание, что это может занять много времени для анализа.
static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
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, но обратите внимание, что это может занять много времени для анализа.
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("-4712-01-01T00:00:00+00:00");
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.
static VALUE
datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
if (!NIL_P(opt)) argc--;
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01T00:00:00+00:00");
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, но имейте в виду, что это может занять много времени.
Методы публичного экземпляра
# File ext/json/lib/json/add/date_time.rb, line 28
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 Возвращает хеш, который будет преобразован в объект JSON и представит этот объект.
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
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
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"
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"
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
Date#minute — псевдоним для Date#min.
Возвращает минуту в диапазоне (0..59):
DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5
Date#minute — псевдоним для Date#min.
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 ...>
static VALUE
d_lite_offset(VALUE self)
{
get_d1(self);
return m_of_in_day(dat);
} Возвращает смещение.
DateTime.parse('04pm+0730').offset #=> (5/16)
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"
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
Date#second — псевдоним для Date#sec.
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)
Date#second_fraction — псевдоним для Date#sec_fraction.
Возвращает секунду в диапазоне (0..59):
DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6
Date#second — псевдоним для Date#sec.
Возвращает дробную часть секунды в диапазоне (Rational(0, 1)…Rational(1, 1)):
DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2)
Date#second_fraction — псевдоним для Date#sec_fraction.
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, отформатированное в соответствии с заданным +форматом:
DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"
Другие форматы см. в разделе Форматы дат и времени.
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, который обозначает текущий объект.
static VALUE
datetime_to_datetime(VALUE self)
{
return self;
} Возвращает текущий объект.
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"
static VALUE
datetime_to_time(VALUE self)
{
get_d1(self);
if (m_julian_p(dat)) {
self = d_lite_gregorian(self);
get_d1a(self);
dat = adat;
}
{
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)));
return t;
}
} Возвращает объект Time, который обозначает текущий объект.
Этот метод эквивалентен 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"
static VALUE
d_lite_zone(VALUE self)
{
get_d1(self);
return m_zone(dat);
} Возвращает часовой пояс.
DateTime.parse('04pm+0730').zone #=> "+07:30"
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.