класс Date
Класс для работы с датами и временем — Tadayoshi Funaba 1998-2011
Модуль ‘date’ предоставляет два класса: Date и DateTime.
Термины и определения
Некоторые термины и определения основаны на ISO 8601 и JIS X 0301.
Календарная датаDate
Календарная дата — конкретный день календарного года, определяемый его порядковым номером в календарном месяце в том году.
В этих классах она называется «гражданской».
Порядковая датаDate
Порядковая дата — конкретный день календарного года, определяемый его порядковым номером в году.
В этих классах она называется «порядковой».
Недельная датаDate
Недельная дата — дата, определяемая номерами календарной недели и дня.
Календарная неделя — семидневный период в календарном году, начинающийся в понедельник и определяемый своим порядковым номером в году; первая календарная неделя года — та, которая включает первый четверг того года. В григорианском календаре это эквивалентно неделе, включающей 4 января.
В этих классах она называется «коммерческой».
Номер Джулианского дня
Номер Джулианского дня — это количество прошедших дней с полудня (Гринвичское среднее Time) 1 января 4713 г. до н. э. (в юлианском календаре).
В данном документе астрономический номер Джулианского дня совпадает с исходным номером Джулианского дня. А хронологический номер Джулианского дня — это вариант номера Джулианского дня. Его дни начинаются в полночь по местному времени.
В этом документе, когда просто встречается термин «номер Джулианского дня», он относится к «хронологическому номеру Джулианского дня», а не исходному.
В этих классах они называются «ajd» и «jd».
Изменённый номер Джулианского дня
Изменённый номер Джулианского дня — это количество прошедших дней с полуночи (Координированное универсальное Time) 17 ноября 1858 г. (в григорианском календаре).
В этом документе астрономический изменённый номер Джулианского дня совпадает с исходным изменённым номером Джулианского дня. А хронологический изменённый номер Джулианского дня — это вариант изменённого номера Джулианского дня. Его дни начинаются в полночь по местному времени.
В данном документе, когда упоминается просто «изменённый номер Джулианского дня», имеется в виду «хронологический изменённый номер Джулианского дня», а не исходный.
В этих классах они называются «amjd» и «mjd».
Date
Подкласс Object, включающий модуль Comparable и позволяющий легко работать с датами.
Объект Date создается с помощью Date::new, Date::jd, Date::ordinal, Date::commercial, Date::parse, Date::strptime, Date::today, Time#to_date и др.
require 'date'
Date.new(2001,2,3)
#=> #<Date: 2001-02-03 ...>
Date.jd(2451944)
#=> #<Date: 2001-02-03 ...>
Date.ordinal(2001,34)
#=> #<Date: 2001-02-03 ...>
Date.commercial(2001,5,6)
#=> #<Date: 2001-02-03 ...>
Date.parse('2001-02-03')
#=> #<Date: 2001-02-03 ...>
Date.strptime('03-02-2001', '%d-%m-%Y')
#=> #<Date: 2001-02-03 ...>
Time.new(2001,2,3).to_date
#=> #<Date: 2001-02-03 ...>
Все объекты даты неизменяемы; поэтому их нельзя изменить.
Концепцию объекта даты можно представить как кортеж из количества дней, смещения и дня календарной реформы.
Количество дней обозначает абсолютное положение временной размерности. Смещение — это относительная корректировка, которая определяет декодированное местное время с учётом количества дней. День календарной реформы обозначает начальный день нового стиля. Старый стиль Запада — юлианский календарь, который был принят Цезарем. Новый стиль — григорианский календарь, который является современным гражданским календарём многих стран.
Количество дней фактически является астрономическим номером Джулианского дня. Смещение в этом классе обычно равно нулю и не может быть задано напрямую.
Объект Date может быть создан с необязательным аргументом, днём календарной реформы как номером Джулианского дня, который должен быть от 2298874 до 2426355 или отрицательной/положительной бесконечностью. Значение по умолчанию — Date::ITALY (2299161=1582-10-15). См. также sample/cal.rb.
$ ruby sample/cal.rb -c it 10 1582
October 1582
S M Tu W Th F S
1 2 3 4 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
$ ruby sample/cal.rb -c gb 9 1752
September 1752
S M Tu W Th F S
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30 Объект Date имеет различные методы. См. соответствующие справки.
d = Date.parse('3rd Feb 2001')
#=> #<Date: 2001-02-03 ...>
d.year #=> 2001
d.mon #=> 2
d.mday #=> 3
d.wday #=> 6
d += 1 #=> #<Date: 2001-02-04 ...>
d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001"
Константы
- ABBR_DAYNAMES
-
Массив строк с сокращенными названиями дней недели в
English. Первый — «Вс». - ABBR_MONTHNAMES
-
Массив строк с сокращенными названиями месяцев в
English. Первый элемент — null. - DAYNAMES
-
Массив строк с полными названиями дней недели в
English. Первый — «Воскресенье». - ENGLAND
-
Номер Джулианского дня дня календарной реформы для Англии и её колоний.
- GREGORIAN
-
Номер Джулианского дня дня календарной реформы для пролептического григорианского календаря.
- ITALY
-
Номер Джулианского дня дня календарной реформы для Италии и некоторых католических стран.
- JULIAN
-
Номер Джулианского дня дня календарной реформы для пролептического юлианского календаря.
- MONTHNAMES
-
Массив строк с полными названиями месяцев в
English. Первый элемент — null.
Методы публичного класса
static VALUE
date_s__httpdate(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__httpdate(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__iso8601(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__iso8601(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__jisx0301(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__parse(int argc, VALUE *argv, VALUE klass)
{
return date_s__parse_internal(argc, argv, klass);
} Парсит заданное представление даты и времени и возвращает хэш распарсенных элементов.
Этот метод *не* является валидатором. Если входная строка не строго соответствует допустимым форматам, вы можете получить непредсказуемый результат. Рекомендуется использовать `Date._strptime` или `DateTime._strptime` вместо этого метода, если возможно.
Если необязательный второй аргумент равен true, и обнаруженный год находится в диапазоне «00» до «99», год рассматривается как 2-значный и дополняется до 4-значного.
Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__rfc2822(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__rfc3339(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__rfc2822(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s__strptime(int argc, VALUE *argv, VALUE klass)
{
return date_s__strptime_internal(argc, argv, klass, "%F");
} Парсит заданное представление даты и времени с заданным шаблоном и возвращает хэш распарсенных элементов. _strptime не поддерживает указание флагов и ширины в отличие от strftime.
Date._strptime('2001-02-03', '%Y-%m-%d')
#=> {:year=>2001, :mon=>2, :mday=>3}
См. также strptime(3) и strftime.
static VALUE
date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
{
VALUE str, opt;
rb_scan_args(argc, argv, "1:", &str, &opt);
check_limit(str, opt);
return date__xmlschema(str);
} Возвращает хэш распарсенных элементов.
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s_civil(int argc, VALUE *argv, VALUE klass)
{
return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
} Создаёт объект даты, обозначающий заданную календарную дату.
В этом классе годы до н.э. считаются астрономически. Таким образом, год перед годом 1 — год ноль, а год перед годом ноль — год -1. Месяц и день месяца должны быть положительными или отрицательными числами (в качестве относительного месяца/дня от конца года/месяца при отрицательном значении). Они не должны быть нулевыми.
Последний аргумент должен быть номером юлианского дня, обозначающим день календарной реформы. Date::ITALY (2299161=1582-10-15), Date::ENGLAND (2361222=1752-09-14), Date::GREGORIAN (пролептический григорианский календарь) и Date::JULIAN (пролептический юлианский календарь) могут быть указаны как день календарной реформы.
Date.new(2001) #=> #<Date: 2001-01-01 ...> Date.new(2001,2,3) #=> #<Date: 2001-02-03 ...> Date.new(2001,2,-1) #=> #<Date: 2001-02-28 ...>
См. также ::jd.
static VALUE
date_s_commercial(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vw, vd, vsg, y, fr, fr2, ret;
int w, d;
double sg;
rb_scan_args(argc, argv, "04", &vy, &vw, &vd, &vsg);
y = INT2FIX(-4712);
w = 1;
d = 1;
fr2 = INT2FIX(0);
sg = DEFAULT_SG;
switch (argc) {
case 4:
val2sg(vsg, sg);
case 3:
check_numeric(vd, "cwday");
num2int_with_frac(d, positive_inf);
case 2:
check_numeric(vw, "cweek");
w = NUM2INT(vw);
case 1:
check_numeric(vy, "year");
y = vy;
}
{
VALUE nth;
int ry, rw, rd, rjd, ns;
if (!valid_commercial_p(y, w, d, sg,
&nth, &ry,
&rw, &rd, &rjd,
&ns))
rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
sg,
0, 0, 0,
HAVE_JD);
}
add_frac();
return ret;
} Создаёт объект даты, обозначающий заданную дату недели.
Неделя и день недели должны быть положительными или отрицательными числами (как относительная неделя/день от конца года/недели при отрицательном значении). Они не должны быть нулевыми.
Date.commercial(2001) #=> #<Date: 2001-01-01 ...> Date.commercial(2002) #=> #<Date: 2001-12-31 ...> Date.commercial(2001,5,6) #=> #<Date: 2001-02-03 ...>
static VALUE
date_s_gregorian_leap_p(VALUE klass, VALUE y)
{
VALUE nth;
int ry;
check_numeric(y, "year");
decode_year(y, -1, &nth, &ry);
return f_boolcast(c_gregorian_leap_p(ry));
} Возвращает true, если заданный год является високосным годом в пролептическом григорианском календаре.
Date.gregorian_leap?(1900) #=> false Date.gregorian_leap?(2000) #=> true
static VALUE
date_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
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];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__httpdate(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создаёт новый объект Date, парся строку в соответствии с форматом RFC 2616.
Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
#=> #<Date: 2001-02-03 ...>
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_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-01");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__iso8601(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создаёт новый объект Date, парся строку в соответствии с типичными форматами ISO 8601.
Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...>
Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>
Вызывает исключение ArgumentError, если длина строки превышает предел. Вы можете отключить эту проверку, передав `предел: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s_jd(int argc, VALUE *argv, VALUE klass)
{
VALUE vjd, vsg, jd, fr, fr2, ret;
double sg;
rb_scan_args(argc, argv, "02", &vjd, &vsg);
jd = INT2FIX(0);
fr2 = INT2FIX(0);
sg = DEFAULT_SG;
switch (argc) {
case 2:
val2sg(vsg, sg);
case 1:
check_numeric(vjd, "jd");
num2num_with_frac(jd, positive_inf);
}
{
VALUE nth;
int rjd;
decode_jd(jd, &nth, &rjd);
ret = d_simple_new_internal(klass,
nth, rjd,
sg,
0, 0, 0,
HAVE_JD);
}
add_frac();
return ret;
} Создаёт объект даты, обозначающий заданный хронологический номер юлианского дня.
Date.jd(2451944) #=> #<Date: 2001-02-03 ...> Date.jd(2451945) #=> #<Date: 2001-02-04 ...> Date.jd(0) #=> #<Date: -4712-01-01 ...>
См. также ::new.
static VALUE
date_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-01");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__jisx0301(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создаёт новый объект Date, разобрав строку в соответствии с типичными форматами JIS X 0301.
Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
Для года без эры, используется формат по умолчанию, Heisei.
Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
Возбуждает исключение ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав `limit: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s_julian_leap_p(VALUE klass, VALUE y)
{
VALUE nth;
int ry;
check_numeric(y, "year");
decode_year(y, +1, &nth, &ry);
return f_boolcast(c_julian_leap_p(ry));
} Возвращает true, если данный год является високосным годом в пролептическом юлианском календаре.
Date.julian_leap?(1900) #=> true Date.julian_leap?(1901) #=> false
static VALUE
date_s_gregorian_leap_p(VALUE klass, VALUE y)
{
VALUE nth;
int ry;
check_numeric(y, "year");
decode_year(y, -1, &nth, &ry);
return f_boolcast(c_gregorian_leap_p(ry));
} Возвращает true, если данный год является високосным годом в пролептическом григорианском календаре.
Date.gregorian_leap?(1900) #=> false Date.gregorian_leap?(2000) #=> true
static VALUE
date_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
int m, d;
double sg;
struct SimpleDateData *dat = rb_check_typeddata(self, &d_lite_type);
if (!simple_dat_p(dat)) {
rb_raise(rb_eTypeError, "Date expected");
}
rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);
y = INT2FIX(-4712);
m = 1;
d = 1;
fr2 = INT2FIX(0);
sg = DEFAULT_SG;
switch (argc) {
case 4:
val2sg(vsg, sg);
case 3:
check_numeric(vd, "day");
num2int_with_frac(d, positive_inf);
case 2:
check_numeric(vm, "month");
m = NUM2INT(vm);
case 1:
check_numeric(vy, "year");
y = vy;
}
if (guess_style(y, sg) < 0) {
VALUE nth;
int ry, rm, rd;
if (!valid_gregorian_p(y, m, d,
&nth, &ry,
&rm, &rd))
rb_raise(eDateError, "invalid date");
set_to_simple(self, dat, nth, 0, sg, ry, rm, rd, HAVE_CIVIL);
}
else {
VALUE nth;
int ry, rm, rd, rjd, ns;
if (!valid_civil_p(y, m, d, sg,
&nth, &ry,
&rm, &rd, &rjd,
&ns))
rb_raise(eDateError, "invalid date");
set_to_simple(self, dat, nth, rjd, sg, ry, rm, rd, HAVE_JD | HAVE_CIVIL);
}
ret = self;
add_frac();
return ret;
} static VALUE
date_s_new_bang(int argc, VALUE *argv, VALUE klass)
{
VALUE ajd, of, sg, nth, sf;
int jd, df, rof;
double rsg;
rb_scan_args(argc, argv, "03", &ajd, &of, &sg);
switch (argc) {
case 0:
ajd = INT2FIX(0);
case 1:
of = INT2FIX(0);
case 2:
sg = INT2FIX(DEFAULT_SG);
}
old_to_new(ajd, of, sg,
&nth, &jd, &df, &sf, &rof, &rsg);
if (!df && f_zero_p(sf) && !rof)
return d_simple_new_internal(klass,
nth, jd,
rsg,
0, 0, 0,
HAVE_JD);
else
return d_complex_new_internal(klass,
nth, jd,
df, sf,
rof, rsg,
0, 0, 0,
0, 0, 0,
HAVE_JD | HAVE_DF);
} static VALUE
date_s_nth_kday(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vm, vn, vk, vsg, y, fr, fr2, ret;
int m, n, k;
double sg;
rb_scan_args(argc, argv, "05", &vy, &vm, &vn, &vk, &vsg);
y = INT2FIX(-4712);
m = 1;
n = 1;
k = 1;
fr2 = INT2FIX(0);
sg = DEFAULT_SG;
switch (argc) {
case 5:
val2sg(vsg, sg);
case 4:
num2int_with_frac(k, positive_inf);
case 3:
n = NUM2INT(vn);
case 2:
m = NUM2INT(vm);
case 1:
y = vy;
}
{
VALUE nth;
int ry, rm, rn, rk, rjd, ns;
if (!valid_nth_kday_p(y, m, n, k, sg,
&nth, &ry,
&rm, &rn, &rk, &rjd,
&ns))
rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
sg,
0, 0, 0,
HAVE_JD);
}
add_frac();
return ret;
} static VALUE
date_s_ordinal(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vd, vsg, y, fr, fr2, ret;
int d;
double sg;
rb_scan_args(argc, argv, "03", &vy, &vd, &vsg);
y = INT2FIX(-4712);
d = 1;
fr2 = INT2FIX(0);
sg = DEFAULT_SG;
switch (argc) {
case 3:
val2sg(vsg, sg);
case 2:
check_numeric(vd, "yday");
num2int_with_frac(d, positive_inf);
case 1:
check_numeric(vy, "year");
y = vy;
}
{
VALUE nth;
int ry, rd, rjd, ns;
if (!valid_ordinal_p(y, d, sg,
&nth, &ry,
&rd, &rjd,
&ns))
rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
sg,
0, 0, 0,
HAVE_JD);
}
add_frac();
return ret;
} Создаёт объект даты, обозначающий заданную порядковую дату.
Номер дня в году должен быть отрицательным или положительным числом (в качестве относительного дня от конца года при отрицательном значении). Он не должен быть равен нулю.
Date.ordinal(2001) #=> #<Date: 2001-01-01 ...> Date.ordinal(2001,34) #=> #<Date: 2001-02-03 ...> Date.ordinal(2001,-1) #=> #<Date: 2001-12-31 ...>
static VALUE
date_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-01");
case 1:
comp = Qtrue;
case 2:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 2;
VALUE argv2[3];
argv2[0] = str;
argv2[1] = comp;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__parse(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Разбирает заданное представление даты и времени и создаёт объект даты.
Этот метод *не* выполняет валидацию. Если входная строка не соответствует строго допустимым форматам, результат может быть непредсказуемым. Рекомендуется использовать метод «Date.strptime» вместо этого метода, если это возможно.
Если необязательный второй аргумент равен true, и обнаруженный год находится в диапазоне «00» - «99», год рассматривается как двузначный и дополняется до четырёх знаков.
Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...>
Date.parse('20010203') #=> #<Date: 2001-02-03 ...>
Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...>
Возбуждает исключение ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав ‘limit: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
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];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__rfc2822(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создаёт новый объект Date, разобрав строку в соответствии с типичными форматами RFC 2822.
Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
#=> #<Date: 2001-02-03 ...>
Возбуждает исключение ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав ‘limit: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_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];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__rfc3339(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создаёт новый объект Date, разобрав строку в соответствии с типичными форматами RFC 3339.
Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
Возбуждает исключение ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав ‘limit: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
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];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__rfc2822(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создаёт новый объект Date, разобрав строку в соответствии с типичными форматами RFC 2822.
Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
#=> #<Date: 2001-02-03 ...>
Возбуждает исключение ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав ‘limit: nil`, но имейте в виду, что это может занять много времени.
static VALUE
date_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-01");
case 1:
fmt = rb_str_new2("%F");
case 2:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE argv2[2], hash;
argv2[0] = str;
argv2[1] = fmt;
hash = date_s__strptime(2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Разбирает заданное представление даты и времени с заданным шаблоном и создаёт объект даты. strptime не поддерживает указание флагов и ширины в отличие от strftime.
Date.strptime('2001-02-03', '%Y-%m-%d') #=> #<Date: 2001-02-03 ...>
Date.strptime('03-02-2001', '%d-%m-%Y') #=> #<Date: 2001-02-03 ...>
Date.strptime('2001-034', '%Y-%j') #=> #<Date: 2001-02-03 ...>
Date.strptime('2001-W05-6', '%G-W%V-%u') #=> #<Date: 2001-02-03 ...>
Date.strptime('2001 04 6', '%Y %U %w') #=> #<Date: 2001-02-03 ...>
Date.strptime('2001 05 6', '%Y %W %u') #=> #<Date: 2001-02-03 ...>
Date.strptime('sat3feb01', '%a%d%b%y') #=> #<Date: 2001-02-03 ...>
См. также strptime(3) и strftime.
static VALUE
date_s_test_all(VALUE klass)
{
if (date_s_test_civil(klass) == Qfalse)
return Qfalse;
if (date_s_test_ordinal(klass) == Qfalse)
return Qfalse;
if (date_s_test_commercial(klass) == Qfalse)
return Qfalse;
if (date_s_test_weeknum(klass) == Qfalse)
return Qfalse;
if (date_s_test_nth_kday(klass) == Qfalse)
return Qfalse;
if (date_s_test_unit_conv(klass) == Qfalse)
return Qfalse;
return Qtrue;
} static VALUE
date_s_test_civil(VALUE klass)
{
if (!test_civil(MIN_JD, MIN_JD + 366, GREGORIAN))
return Qfalse;
if (!test_civil(2305814, 2598007, GREGORIAN))
return Qfalse;
if (!test_civil(MAX_JD - 366, MAX_JD, GREGORIAN))
return Qfalse;
if (!test_civil(MIN_JD, MIN_JD + 366, ITALY))
return Qfalse;
if (!test_civil(2305814, 2598007, ITALY))
return Qfalse;
if (!test_civil(MAX_JD - 366, MAX_JD, ITALY))
return Qfalse;
return Qtrue;
} static VALUE
date_s_test_commercial(VALUE klass)
{
if (!test_commercial(MIN_JD, MIN_JD + 366, GREGORIAN))
return Qfalse;
if (!test_commercial(2305814, 2598007, GREGORIAN))
return Qfalse;
if (!test_commercial(MAX_JD - 366, MAX_JD, GREGORIAN))
return Qfalse;
if (!test_commercial(MIN_JD, MIN_JD + 366, ITALY))
return Qfalse;
if (!test_commercial(2305814, 2598007, ITALY))
return Qfalse;
if (!test_commercial(MAX_JD - 366, MAX_JD, ITALY))
return Qfalse;
return Qtrue;
} static VALUE
date_s_test_nth_kday(VALUE klass)
{
if (!test_nth_kday(MIN_JD, MIN_JD + 366, GREGORIAN))
return Qfalse;
if (!test_nth_kday(2305814, 2598007, GREGORIAN))
return Qfalse;
if (!test_nth_kday(MAX_JD - 366, MAX_JD, GREGORIAN))
return Qfalse;
if (!test_nth_kday(MIN_JD, MIN_JD + 366, ITALY))
return Qfalse;
if (!test_nth_kday(2305814, 2598007, ITALY))
return Qfalse;
if (!test_nth_kday(MAX_JD - 366, MAX_JD, ITALY))
return Qfalse;
return Qtrue;
} static VALUE
date_s_test_ordinal(VALUE klass)
{
if (!test_ordinal(MIN_JD, MIN_JD + 366, GREGORIAN))
return Qfalse;
if (!test_ordinal(2305814, 2598007, GREGORIAN))
return Qfalse;
if (!test_ordinal(MAX_JD - 366, MAX_JD, GREGORIAN))
return Qfalse;
if (!test_ordinal(MIN_JD, MIN_JD + 366, ITALY))
return Qfalse;
if (!test_ordinal(2305814, 2598007, ITALY))
return Qfalse;
if (!test_ordinal(MAX_JD - 366, MAX_JD, ITALY))
return Qfalse;
return Qtrue;
} static VALUE
date_s_test_unit_conv(VALUE klass)
{
if (!test_unit_v2v_iter(sec_to_day, day_to_sec))
return Qfalse;
if (!test_unit_v2v_iter(ms_to_sec, sec_to_ms))
return Qfalse;
if (!test_unit_v2v_iter(ns_to_day, day_to_ns))
return Qfalse;
if (!test_unit_v2v_iter(ns_to_sec, sec_to_ns))
return Qfalse;
return Qtrue;
} static VALUE
date_s_test_weeknum(VALUE klass)
{
int f;
for (f = 0; f <= 1; f++) {
if (!test_weeknum(MIN_JD, MIN_JD + 366, f, GREGORIAN))
return Qfalse;
if (!test_weeknum(2305814, 2598007, f, GREGORIAN))
return Qfalse;
if (!test_weeknum(MAX_JD - 366, MAX_JD, f, GREGORIAN))
return Qfalse;
if (!test_weeknum(MIN_JD, MIN_JD + 366, f, ITALY))
return Qfalse;
if (!test_weeknum(2305814, 2598007, f, ITALY))
return Qfalse;
if (!test_weeknum(MAX_JD - 366, MAX_JD, f, ITALY))
return Qfalse;
}
return Qtrue;
} static VALUE
date_s_today(int argc, VALUE *argv, VALUE klass)
{
VALUE vsg, nth, ret;
double sg;
time_t t;
struct tm tm;
int y, ry, m, d;
rb_scan_args(argc, argv, "01", &vsg);
if (argc < 1)
sg = DEFAULT_SG;
else
val2sg(vsg, sg);
if (time(&t) == -1)
rb_sys_fail("time");
tzset();
if (!localtime_r(&t, &tm))
rb_sys_fail("localtime");
y = tm.tm_year + 1900;
m = tm.tm_mon + 1;
d = tm.tm_mday;
decode_year(INT2FIX(y), -1, &nth, &ry);
ret = d_simple_new_internal(klass,
nth, 0,
GREGORIAN,
ry, m, d,
HAVE_CIVIL);
{
get_d1(ret);
set_sg(dat, sg);
}
return ret;
} Создаёт объект даты, обозначающий текущий день.
Date.today #=> #<Date: 2011-06-11 ...>
static VALUE
date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vm, vd, vsg;
VALUE argv2[4];
rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);
RETURN_FALSE_UNLESS_NUMERIC(vy);
RETURN_FALSE_UNLESS_NUMERIC(vm);
RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vm;
argv2[2] = vd;
if (argc < 4)
argv2[3] = INT2FIX(DEFAULT_SG);
else
argv2[3] = vsg;
if (NIL_P(valid_civil_sub(4, argv2, klass, 0)))
return Qfalse;
return Qtrue;
} Возвращает true, если заданная календарная дата является допустимой, и false — если нет. Допустимость в данном контексте определяется тем, будут ли переданные в этот метод аргументы приняты методом ::new.
Date.valid_date?(2001,2,3) #=> true Date.valid_date?(2001,2,29) #=> false Date.valid_date?(2001,2,-1) #=> true
static VALUE
date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vw, vd, vsg;
VALUE argv2[4];
rb_scan_args(argc, argv, "31", &vy, &vw, &vd, &vsg);
RETURN_FALSE_UNLESS_NUMERIC(vy);
RETURN_FALSE_UNLESS_NUMERIC(vw);
RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vw;
argv2[2] = vd;
if (argc < 4)
argv2[3] = INT2FIX(DEFAULT_SG);
else
argv2[3] = vsg;
if (NIL_P(valid_commercial_sub(4, argv2, klass, 0)))
return Qfalse;
return Qtrue;
} Возвращает true, если заданная дата недели является допустимой, и false — если нет.
Date.valid_commercial?(2001,5,6) #=> true Date.valid_commercial?(2001,5,8) #=> false
См. также ::jd и ::commercial.
static VALUE
date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vm, vd, vsg;
VALUE argv2[4];
rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);
RETURN_FALSE_UNLESS_NUMERIC(vy);
RETURN_FALSE_UNLESS_NUMERIC(vm);
RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vm;
argv2[2] = vd;
if (argc < 4)
argv2[3] = INT2FIX(DEFAULT_SG);
else
argv2[3] = vsg;
if (NIL_P(valid_civil_sub(4, argv2, klass, 0)))
return Qfalse;
return Qtrue;
} Возвращает true, если заданная календарная дата является допустимой, и false — если нет. Допустимость в данном контексте определяется тем, будут ли переданные в этот метод аргументы приняты методом ::new.
Date.valid_date?(2001,2,3) #=> true Date.valid_date?(2001,2,29) #=> false Date.valid_date?(2001,2,-1) #=> true
static VALUE
date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
{
VALUE vjd, vsg;
VALUE argv2[2];
rb_scan_args(argc, argv, "11", &vjd, &vsg);
RETURN_FALSE_UNLESS_NUMERIC(vjd);
argv2[0] = vjd;
if (argc < 2)
argv2[1] = INT2FIX(DEFAULT_SG);
else
argv2[1] = vsg;
if (NIL_P(valid_jd_sub(2, argv2, klass, 0)))
return Qfalse;
return Qtrue;
} Просто возвращает true. Это бессмысленно, но это сделано для симметрии.
Date.valid_jd?(2451944) #=> true
См. также ::jd.
static VALUE
date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vd, vsg;
VALUE argv2[3];
rb_scan_args(argc, argv, "21", &vy, &vd, &vsg);
RETURN_FALSE_UNLESS_NUMERIC(vy);
RETURN_FALSE_UNLESS_NUMERIC(vd);
argv2[0] = vy;
argv2[1] = vd;
if (argc < 3)
argv2[2] = INT2FIX(DEFAULT_SG);
else
argv2[2] = vsg;
if (NIL_P(valid_ordinal_sub(3, argv2, klass, 0)))
return Qfalse;
return Qtrue;
} Возвращает true, если заданная дата в формате порядкового номера является допустимой, и false — если нет.
Date.valid_ordinal?(2001,34) #=> true Date.valid_ordinal?(2001,366) #=> false
static VALUE
date_s_weeknum(int argc, VALUE *argv, VALUE klass)
{
VALUE vy, vw, vd, vf, vsg, y, fr, fr2, ret;
int w, d, f;
double sg;
rb_scan_args(argc, argv, "05", &vy, &vw, &vd, &vf, &vsg);
y = INT2FIX(-4712);
w = 0;
d = 1;
f = 0;
fr2 = INT2FIX(0);
sg = DEFAULT_SG;
switch (argc) {
case 5:
val2sg(vsg, sg);
case 4:
f = NUM2INT(vf);
case 3:
num2int_with_frac(d, positive_inf);
case 2:
w = NUM2INT(vw);
case 1:
y = vy;
}
{
VALUE nth;
int ry, rw, rd, rjd, ns;
if (!valid_weeknum_p(y, w, d, f, sg,
&nth, &ry,
&rw, &rd, &rjd,
&ns))
rb_raise(eDateError, "invalid date");
ret = d_simple_new_internal(klass,
nth, rjd,
sg,
0, 0, 0,
HAVE_JD);
}
add_frac();
return ret;
} static VALUE
date_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-01");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2];
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
VALUE hash = date_s__xmlschema(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Создает новый объект Date путем парсинга из строки в соответствии с некоторыми типичными форматами XML Schema.
Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
Вызывает исключение ArgumentError, если длина строки больше, чем limit. Вы можете отключить эту проверку, передав ‘limit: nil`, но учтите, что это может занять много времени.
Методы экземпляра публичного использования
static VALUE
d_lite_plus(VALUE self, VALUE other)
{
int try_rational = 1;
get_d1(self);
again:
switch (TYPE(other)) {
case T_FIXNUM:
{
VALUE nth;
long t;
int jd;
nth = m_nth(dat);
t = FIX2LONG(other);
if (DIV(t, CM_PERIOD)) {
nth = f_add(nth, INT2FIX(DIV(t, CM_PERIOD)));
t = MOD(t, CM_PERIOD);
}
if (!t)
jd = m_jd(dat);
else {
jd = m_jd(dat) + (int)t;
canonicalize_jd(nth, jd);
}
if (simple_dat_p(dat))
return d_simple_new_internal(rb_obj_class(self),
nth, jd,
dat->s.sg,
0, 0, 0,
(dat->s.flags | HAVE_JD) &
~HAVE_CIVIL);
else
return d_complex_new_internal(rb_obj_class(self),
nth, jd,
dat->c.df, dat->c.sf,
dat->c.of, dat->c.sg,
0, 0, 0,
#ifndef USE_PACK
dat->c.hour,
dat->c.min,
dat->c.sec,
#else
EX_HOUR(dat->c.pc),
EX_MIN(dat->c.pc),
EX_SEC(dat->c.pc),
#endif
(dat->c.flags | HAVE_JD) &
~HAVE_CIVIL);
}
break;
case T_BIGNUM:
{
VALUE nth;
int jd, s;
if (f_positive_p(other))
s = +1;
else {
s = -1;
other = f_negate(other);
}
nth = f_idiv(other, INT2FIX(CM_PERIOD));
jd = FIX2INT(f_mod(other, INT2FIX(CM_PERIOD)));
if (s < 0) {
nth = f_negate(nth);
jd = -jd;
}
if (!jd)
jd = m_jd(dat);
else {
jd = m_jd(dat) + jd;
canonicalize_jd(nth, jd);
}
if (f_zero_p(nth))
nth = m_nth(dat);
else
nth = f_add(m_nth(dat), nth);
if (simple_dat_p(dat))
return d_simple_new_internal(rb_obj_class(self),
nth, jd,
dat->s.sg,
0, 0, 0,
(dat->s.flags | HAVE_JD) &
~HAVE_CIVIL);
else
return d_complex_new_internal(rb_obj_class(self),
nth, jd,
dat->c.df, dat->c.sf,
dat->c.of, dat->c.sg,
0, 0, 0,
#ifndef USE_PACK
dat->c.hour,
dat->c.min,
dat->c.sec,
#else
EX_HOUR(dat->c.pc),
EX_MIN(dat->c.pc),
EX_SEC(dat->c.pc),
#endif
(dat->c.flags | HAVE_JD) &
~HAVE_CIVIL);
}
break;
case T_FLOAT:
{
double jd, o, tmp;
int s, df;
VALUE nth, sf;
o = RFLOAT_VALUE(other);
if (o > 0)
s = +1;
else {
s = -1;
o = -o;
}
o = modf(o, &tmp);
if (!floor(tmp / CM_PERIOD)) {
nth = INT2FIX(0);
jd = (int)tmp;
}
else {
double i, f;
f = modf(tmp / CM_PERIOD, &i);
nth = f_floor(DBL2NUM(i));
jd = (int)(f * CM_PERIOD);
}
o *= DAY_IN_SECONDS;
o = modf(o, &tmp);
df = (int)tmp;
o *= SECOND_IN_NANOSECONDS;
sf = INT2FIX((int)round(o));
if (s < 0) {
jd = -jd;
df = -df;
sf = f_negate(sf);
}
if (f_zero_p(sf))
sf = m_sf(dat);
else {
sf = f_add(m_sf(dat), sf);
if (f_lt_p(sf, INT2FIX(0))) {
df -= 1;
sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
}
else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
df += 1;
sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
}
}
if (!df)
df = m_df(dat);
else {
df = m_df(dat) + df;
if (df < 0) {
jd -= 1;
df += DAY_IN_SECONDS;
}
else if (df >= DAY_IN_SECONDS) {
jd += 1;
df -= DAY_IN_SECONDS;
}
}
if (!jd)
jd = m_jd(dat);
else {
jd = m_jd(dat) + jd;
canonicalize_jd(nth, jd);
}
if (f_zero_p(nth))
nth = m_nth(dat);
else
nth = f_add(m_nth(dat), nth);
if (!df && f_zero_p(sf) && !m_of(dat))
return d_simple_new_internal(rb_obj_class(self),
nth, (int)jd,
m_sg(dat),
0, 0, 0,
(dat->s.flags | HAVE_JD) &
~(HAVE_CIVIL | HAVE_TIME |
COMPLEX_DAT));
else
return d_complex_new_internal(rb_obj_class(self),
nth, (int)jd,
df, sf,
m_of(dat), m_sg(dat),
0, 0, 0,
0, 0, 0,
(dat->c.flags |
HAVE_JD | HAVE_DF) &
~(HAVE_CIVIL | HAVE_TIME));
}
break;
default:
expect_numeric(other);
other = f_to_r(other);
if (!k_rational_p(other)) {
if (!try_rational) Check_Type(other, T_RATIONAL);
try_rational = 0;
goto again;
}
/* fall through */
case T_RATIONAL:
{
VALUE nth, sf, t;
int jd, df, s;
if (wholenum_p(other)) {
other = rb_rational_num(other);
goto again;
}
if (f_positive_p(other))
s = +1;
else {
s = -1;
other = f_negate(other);
}
nth = f_idiv(other, INT2FIX(CM_PERIOD));
t = f_mod(other, INT2FIX(CM_PERIOD));
jd = FIX2INT(f_idiv(t, INT2FIX(1)));
t = f_mod(t, INT2FIX(1));
t = f_mul(t, INT2FIX(DAY_IN_SECONDS));
df = FIX2INT(f_idiv(t, INT2FIX(1)));
t = f_mod(t, INT2FIX(1));
sf = f_mul(t, INT2FIX(SECOND_IN_NANOSECONDS));
if (s < 0) {
nth = f_negate(nth);
jd = -jd;
df = -df;
sf = f_negate(sf);
}
if (f_zero_p(sf))
sf = m_sf(dat);
else {
sf = f_add(m_sf(dat), sf);
if (f_lt_p(sf, INT2FIX(0))) {
df -= 1;
sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
}
else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
df += 1;
sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
}
}
if (!df)
df = m_df(dat);
else {
df = m_df(dat) + df;
if (df < 0) {
jd -= 1;
df += DAY_IN_SECONDS;
}
else if (df >= DAY_IN_SECONDS) {
jd += 1;
df -= DAY_IN_SECONDS;
}
}
if (!jd)
jd = m_jd(dat);
else {
jd = m_jd(dat) + jd;
canonicalize_jd(nth, jd);
}
if (f_zero_p(nth))
nth = m_nth(dat);
else
nth = f_add(m_nth(dat), nth);
if (!df && f_zero_p(sf) && !m_of(dat))
return d_simple_new_internal(rb_obj_class(self),
nth, jd,
m_sg(dat),
0, 0, 0,
(dat->s.flags | HAVE_JD) &
~(HAVE_CIVIL | HAVE_TIME |
COMPLEX_DAT));
else
return d_complex_new_internal(rb_obj_class(self),
nth, jd,
df, sf,
m_of(dat), m_sg(dat),
0, 0, 0,
0, 0, 0,
(dat->c.flags |
HAVE_JD | HAVE_DF) &
~(HAVE_CIVIL | HAVE_TIME));
}
break;
}
} Возвращает объект даты, указывающий на other день после текущей. Other должно быть числовым значением. Если other — дробное число, предполагается, что его точность не превышает наносекунды.
Date.new(2001,2,3) + 1 #=> #<Date: 2001-02-04 ...>
DateTime.new(2001,2,3) + Rational(1,2)
#=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>
DateTime.new(2001,2,3) + Rational(-1,2)
#=> #<DateTime: 2001-02-02T12:00:00+00:00 ...>
DateTime.jd(0,12) + DateTime.new(2001,2,3).ajd
#=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
static VALUE
d_lite_minus(VALUE self, VALUE other)
{
if (k_date_p(other))
return minus_dd(self, other);
switch (TYPE(other)) {
case T_FIXNUM:
return d_lite_plus(self, LONG2NUM(-FIX2LONG(other)));
case T_FLOAT:
return d_lite_plus(self, DBL2NUM(-RFLOAT_VALUE(other)));
default:
expect_numeric(other);
/* fall through */
case T_BIGNUM:
case T_RATIONAL:
return d_lite_plus(self, f_negate(other));
}
} Возвращает разницу между двумя датами, если other — объект даты. Если other — числовое значение, возвращает объект даты, указывающий на other день перед текущей. Если other — дробное число, предполагается, что его точность не превышает наносекунды.
Date.new(2001,2,3) - 1 #=> #<Date: 2001-02-02 ...>
DateTime.new(2001,2,3) - Rational(1,2)
#=> #<DateTime: 2001-02-02T12:00:00+00:00 ...>
Date.new(2001,2,3) - Date.new(2001)
#=> (33/1)
DateTime.new(2001,2,3) - DateTime.new(2001,2,2,12)
#=> (1/2)
static VALUE
d_lite_lshift(VALUE self, VALUE other)
{
expect_numeric(other);
return d_lite_rshift(self, f_negate(other));
} Возвращает объект даты, указывающий на n месяц перед текущей. Аргумент n должен быть числовым значением.
Date.new(2001,2,3) << 1 #=> #<Date: 2001-01-03 ...> Date.new(2001,2,3) << -2 #=> #<Date: 2001-04-03 ...>
Если для соответствующего месяца нет такого же дня, используется последний день месяца:
Date.new(2001,3,28) << 1 #=> #<Date: 2001-02-28 ...> Date.new(2001,3,31) << 1 #=> #<Date: 2001-02-28 ...>
Это также приводит к следующему, возможно, неожиданному поведению:
Date.new(2001,3,31) << 2 #=> #<Date: 2001-01-31 ...> Date.new(2001,3,31) << 1 << 1 #=> #<Date: 2001-01-28 ...> Date.new(2001,3,31) << 1 << -1 #=> #<Date: 2001-03-28 ...>
static VALUE
d_lite_cmp(VALUE self, VALUE other)
{
if (!k_date_p(other))
return cmp_gen(self, other);
{
get_d2(self, other);
if (!(simple_dat_p(adat) && simple_dat_p(bdat) &&
m_gregorian_p(adat) == m_gregorian_p(bdat)))
return cmp_dd(self, other);
{
VALUE a_nth, b_nth;
int a_jd, b_jd;
m_canonicalize_jd(self, adat);
m_canonicalize_jd(other, bdat);
a_nth = m_nth(adat);
b_nth = m_nth(bdat);
if (f_eqeq_p(a_nth, b_nth)) {
a_jd = m_jd(adat);
b_jd = m_jd(bdat);
if (a_jd == b_jd) {
return INT2FIX(0);
}
else if (a_jd < b_jd) {
return INT2FIX(-1);
}
else {
return INT2FIX(1);
}
}
else if (f_lt_p(a_nth, b_nth)) {
return INT2FIX(-1);
}
else {
return INT2FIX(1);
}
}
}
} Сравнивает две даты и возвращает -1, ноль, 1 или nil. Other должен быть объектом даты или числовым значением как числом Джулиана (астрономическое).
Date.new(2001,2,3) <=> Date.new(2001,2,4) #=> -1 Date.new(2001,2,3) <=> Date.new(2001,2,3) #=> 0 Date.new(2001,2,3) <=> Date.new(2001,2,2) #=> 1 Date.new(2001,2,3) <=> Object.new #=> nil Date.new(2001,2,3) <=> Rational(4903887,2) #=> 0
См. также Comparable.
static VALUE
d_lite_equal(VALUE self, VALUE other)
{
if (!k_date_p(other))
return equal_gen(self, other);
{
get_d2(self, other);
if (!(m_gregorian_p(adat) == m_gregorian_p(bdat)))
return equal_gen(self, other);
{
VALUE a_nth, b_nth;
int a_jd, b_jd;
m_canonicalize_jd(self, adat);
m_canonicalize_jd(other, bdat);
a_nth = m_nth(adat);
b_nth = m_nth(bdat);
a_jd = m_local_jd(adat);
b_jd = m_local_jd(bdat);
if (f_eqeq_p(a_nth, b_nth) &&
a_jd == b_jd)
return Qtrue;
return Qfalse;
}
}
} Возвращает true, если это один и тот же день.
Date.new(2001,2,3) === Date.new(2001,2,3)
#=> true
Date.new(2001,2,3) === Date.new(2001,2,4)
#=> false
DateTime.new(2001,2,3) === DateTime.new(2001,2,3,12)
#=> true
DateTime.new(2001,2,3) === DateTime.new(2001,2,3,0,0,0,'+24:00')
#=> true
DateTime.new(2001,2,3) === DateTime.new(2001,2,4,0,0,0,'+24:00')
#=> false
static VALUE
d_lite_rshift(VALUE self, VALUE other)
{
VALUE t, y, nth, rjd2;
int m, d, rjd;
double sg;
get_d1(self);
t = f_add3(f_mul(m_real_year(dat), INT2FIX(12)),
INT2FIX(m_mon(dat) - 1),
other);
if (FIXNUM_P(t)) {
long it = FIX2LONG(t);
y = LONG2NUM(DIV(it, 12));
it = MOD(it, 12);
m = (int)it + 1;
}
else {
y = f_idiv(t, INT2FIX(12));
t = f_mod(t, INT2FIX(12));
m = FIX2INT(t) + 1;
}
d = m_mday(dat);
sg = m_sg(dat);
while (1) {
int ry, rm, rd, ns;
if (valid_civil_p(y, m, d, sg,
&nth, &ry,
&rm, &rd, &rjd, &ns))
break;
if (--d < 1)
rb_raise(eDateError, "invalid date");
}
encode_jd(nth, rjd, &rjd2);
return d_lite_plus(self, f_sub(rjd2, m_real_local_jd(dat)));
} Возвращает объект даты, указывающий на n месяц после текущей. Аргумент n должен быть числовым значением.
Date.new(2001,2,3) >> 1 #=> #<Date: 2001-03-03 ...> Date.new(2001,2,3) >> -2 #=> #<Date: 2000-12-03 ...>
Если для соответствующего месяца нет такого же дня, используется последний день месяца:
Date.new(2001,1,28) >> 1 #=> #<Date: 2001-02-28 ...> Date.new(2001,1,31) >> 1 #=> #<Date: 2001-02-28 ...>
Это также приводит к следующему, возможно, неожиданному поведению:
Date.new(2001,1,31) >> 2 #=> #<Date: 2001-03-31 ...> Date.new(2001,1,31) >> 1 >> 1 #=> #<Date: 2001-03-28 ...> Date.new(2001,1,31) >> 1 >> -1 #=> #<Date: 2001-01-28 ...>
static VALUE
d_lite_ajd(VALUE self)
{
get_d1(self);
return m_ajd(dat);
} Возвращает число Джулиана (астрономическое). Это дробное число, которое не скорректировано сдвигом.
DateTime.new(2001,2,3,4,5,6,'+7').ajd #=> (11769328217/4800) DateTime.new(2001,2,2,14,5,6,'-7').ajd #=> (11769328217/4800)
static VALUE
d_lite_amjd(VALUE self)
{
get_d1(self);
return m_amjd(dat);
} Возвращает число изменённого Джулиана (астрономическое). Это дробное число, которое не скорректировано сдвигом.
DateTime.new(2001,2,3,4,5,6,'+7').amjd #=> (249325817/4800) DateTime.new(2001,2,2,14,5,6,'-7').amjd #=> (249325817/4800)
# File ext/json/lib/json/add/date.rb, line 19
def as_json(*)
{
JSON.create_id => self.class.name,
'y' => year,
'm' => month,
'd' => day,
'sg' => start,
}
end Возвращает хеш, который будет преобразован в объект JSON и представит этот объект.
static VALUE
d_lite_asctime(VALUE self)
{
return strftimev("%a %b %e %H:%M:%S %Y", self, set_tmx);
} Возвращает строку в формате asctime(3) (но без “n0” в конце). Этот метод эквивалентен strftime(‘%c’).
См. также asctime(3) или ctime(3).
Возвращает строку в формате asctime(3) (но без “n0” в конце). Этот метод эквивалентен strftime(‘%c’).
См. также asctime(3) или ctime(3).
static VALUE
d_lite_cwday(VALUE self)
{
get_d1(self);
return INT2FIX(m_cwday(dat));
} Возвращает день календарной недели (1-7, понедельник — 1).
Date.new(2001,2,3).cwday #=> 6
static VALUE
d_lite_cweek(VALUE self)
{
get_d1(self);
return INT2FIX(m_cweek(dat));
} Возвращает номер календарной недели (1-53).
Date.new(2001,2,3).cweek #=> 5
static VALUE
d_lite_cwyear(VALUE self)
{
get_d1(self);
return m_real_cwyear(dat);
} Возвращает год календарной недели.
Date.new(2001,2,3).cwyear #=> 2001 Date.new(2000,1,1).cwyear #=> 1999
static VALUE
d_lite_day_fraction(VALUE self)
{
get_d1(self);
if (simple_dat_p(dat))
return INT2FIX(0);
return m_fr(dat);
} Возвращает дробную часть дня.
DateTime.new(2001,2,3,12).day_fraction #=> (1/2)
static VALUE
d_lite_downto(VALUE self, VALUE min)
{
VALUE date;
RETURN_ENUMERATOR(self, 1, &min);
date = self;
while (FIX2INT(d_lite_cmp(date, min)) >= 0) {
rb_yield(date);
date = d_lite_plus(date, INT2FIX(-1));
}
return self;
} Этот метод эквивалентен step(min, -1){|date| …}.
static VALUE
d_lite_england(VALUE self)
{
return dup_obj_with_new_start(self, ENGLAND);
} Этот метод эквивалентен new_start(Date::ENGLAND).
static VALUE
d_lite_fill(VALUE self)
{
get_d1(self);
if (simple_dat_p(dat)) {
get_s_jd(dat);
get_s_civil(dat);
}
else {
get_c_jd(dat);
get_c_civil(dat);
get_c_df(dat);
get_c_time(dat);
}
return self;
} static VALUE
d_lite_friday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 5);
} Возвращает true, если дата — пятница.
static VALUE
d_lite_gregorian(VALUE self)
{
return dup_obj_with_new_start(self, GREGORIAN);
} Этот метод эквивалентен new_start(Date::GREGORIAN).
static VALUE
d_lite_gregorian_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_gregorian_p(dat));
} Возвращает true, если дата равна или позже дня реформы календаря.
Date.new(1582,10,15).gregorian? #=> true (Date.new(1582,10,15) - 1).gregorian? #=> false
static VALUE
d_lite_httpdate(VALUE self)
{
volatile VALUE dup = dup_obj_with_new_offset(self, 0);
return strftimev("%a, %d %b %Y %T GMT", dup, set_tmx);
} Этот метод эквивалентен strftime(‘%a, %d %b %Y %T GMT’). См. также RFC 2616.
# File ext/date/lib/date.rb, line 9 def infinite? false end
static VALUE
d_lite_inspect(VALUE self)
{
get_d1(self);
return mk_inspect(dat, rb_obj_class(self), self);
} Возвращает значение в виде строки для инспекции.
Date.new(2001,2,3).inspect
#=> "#<Date: 2001-02-03>"
DateTime.new(2001,2,3,4,5,6,'-7').inspect
#=> "#<DateTime: 2001-02-03T04:05:06-07:00>"
static VALUE
d_lite_inspect_raw(VALUE self)
{
get_d1(self);
return mk_inspect_raw(dat, rb_obj_class(self));
} static VALUE
d_lite_iso8601(VALUE self)
{
return strftimev("%Y-%m-%d", self, set_tmx);
} Этот метод эквивалентен strftime(‘%F’).
static VALUE
d_lite_italy(VALUE self)
{
return dup_obj_with_new_start(self, ITALY);
} Этот метод эквивалентен new_start(Date::ITALY).
static VALUE
d_lite_jd(VALUE self)
{
get_d1(self);
return m_real_local_jd(dat);
} Возвращает номер Джулианского дня. Это целое число, скорректированное смещением в соответствии с местным временем.
DateTime.new(2001,2,3,4,5,6,'+7').jd #=> 2451944 DateTime.new(2001,2,3,4,5,6,'-7').jd #=> 2451944
static VALUE
d_lite_jisx0301(VALUE self)
{
char fmtbuf[JISX0301_DATE_SIZE];
const char *fmt;
get_d1(self);
fmt = jisx0301_date_format(fmtbuf, sizeof(fmtbuf),
m_real_local_jd(dat),
m_real_year(dat));
return strftimev(fmt, self, set_tmx);
} Возвращает строку в формате JIS X 0301.
Date.new(2001,2,3).jisx0301 #=> "H13.02.03"
static VALUE
d_lite_julian(VALUE self)
{
return dup_obj_with_new_start(self, JULIAN);
} Этот метод эквивалентен new_start(Date::JULIAN).
static VALUE
d_lite_julian_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_julian_p(dat));
} Возвращает true, если дата предшествует дню реформы календаря.
Date.new(1582,10,15).julian? #=> false (Date.new(1582,10,15) - 1).julian? #=> true
static VALUE
d_lite_ld(VALUE self)
{
get_d1(self);
return f_sub(m_real_local_jd(dat), INT2FIX(2299160));
} Возвращает номер Лилианского дня. Это целое число, скорректированное смещением в соответствии с местным временем.
Date.new(2001,2,3).ld #=> 152784
static VALUE
d_lite_leap_p(VALUE self)
{
int rjd, ns, ry, rm, rd;
get_d1(self);
if (m_gregorian_p(dat))
return f_boolcast(c_gregorian_leap_p(m_year(dat)));
c_civil_to_jd(m_year(dat), 3, 1, m_virtual_sg(dat),
&rjd, &ns);
c_jd_to_civil(rjd - 1, m_virtual_sg(dat), &ry, &rm, &rd);
return f_boolcast(rd == 29);
} Возвращает true, если год високосный.
Date.new(2000).leap? #=> true Date.new(2001).leap? #=> false
static VALUE
d_lite_marshal_dump_old(VALUE self)
{
VALUE a;
get_d1(self);
a = rb_ary_new3(3,
m_ajd(dat),
m_of_in_day(dat),
DBL2NUM(m_sg(dat)));
if (FL_TEST(self, FL_EXIVAR)) {
rb_copy_generic_ivar(a, self);
FL_SET(a, FL_EXIVAR);
}
return a;
} static VALUE
d_lite_mday(VALUE self)
{
get_d1(self);
return INT2FIX(m_mday(dat));
} Возвращает день месяца (1-31).
Date.new(2001,2,3).mday #=> 3
static VALUE
d_lite_mjd(VALUE self)
{
get_d1(self);
return f_sub(m_real_local_jd(dat), INT2FIX(2400001));
} Возвращает номер изменённого Джулианского дня. Это целое число, скорректированное смещением в соответствии с местным временем.
DateTime.new(2001,2,3,4,5,6,'+7').mjd #=> 51943 DateTime.new(2001,2,3,4,5,6,'-7').mjd #=> 51943
static VALUE
d_lite_mon(VALUE self)
{
get_d1(self);
return INT2FIX(m_mon(dat));
} Возвращает месяц (1-12).
Date.new(2001,2,3).mon #=> 2
static VALUE
d_lite_monday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 1);
} Возвращает true, если дата понедельник.
static VALUE
d_lite_new_start(int argc, VALUE *argv, VALUE self)
{
VALUE vsg;
double sg;
rb_scan_args(argc, argv, "01", &vsg);
sg = DEFAULT_SG;
if (argc >= 1)
val2sg(vsg, sg);
return dup_obj_with_new_start(self, sg);
} Создаёт копию и сбрасывает день реформы календаря.
d = Date.new(1582,10,15) d.new_start(Date::JULIAN) #=> #<Date: 1582-10-05 ...>
static VALUE
d_lite_next(VALUE self)
{
return d_lite_next_day(0, (VALUE *)NULL, self);
} Возвращает объект даты, обозначающий следующий день.
static VALUE
d_lite_next_day(int argc, VALUE *argv, VALUE self)
{
VALUE n;
rb_scan_args(argc, argv, "01", &n);
if (argc < 1)
n = INT2FIX(1);
return d_lite_plus(self, n);
} Этот метод эквивалентен d + n.
static VALUE
d_lite_next_month(int argc, VALUE *argv, VALUE self)
{
VALUE n;
rb_scan_args(argc, argv, "01", &n);
if (argc < 1)
n = INT2FIX(1);
return d_lite_rshift(self, n);
} Этот метод эквивалентен d >> n.
Примеры см. в Date#>>.
static VALUE
d_lite_next_year(int argc, VALUE *argv, VALUE self)
{
VALUE n;
rb_scan_args(argc, argv, "01", &n);
if (argc < 1)
n = INT2FIX(1);
return d_lite_rshift(self, f_mul(n, INT2FIX(12)));
} Этот метод эквивалентен d >> (n * 12).
Date.new(2001,2,3).next_year #=> #<Date: 2002-02-03 ...> Date.new(2008,2,29).next_year #=> #<Date: 2009-02-28 ...> Date.new(2008,2,29).next_year(4) #=> #<Date: 2012-02-29 ...>
См. также Date#>>.
static VALUE
d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
{
int rjd, ns;
get_d1(self);
if (NUM2INT(k) != m_wday(dat))
return Qfalse;
c_nth_kday_to_jd(m_year(dat), m_mon(dat),
NUM2INT(n), NUM2INT(k), m_virtual_sg(dat), /* !=m_sg() */
&rjd, &ns);
if (m_local_jd(dat) != rjd)
return Qfalse;
return Qtrue;
} static VALUE
d_lite_prev_day(int argc, VALUE *argv, VALUE self)
{
VALUE n;
rb_scan_args(argc, argv, "01", &n);
if (argc < 1)
n = INT2FIX(1);
return d_lite_minus(self, n);
} Этот метод эквивалентен d - n.
static VALUE
d_lite_prev_month(int argc, VALUE *argv, VALUE self)
{
VALUE n;
rb_scan_args(argc, argv, "01", &n);
if (argc < 1)
n = INT2FIX(1);
return d_lite_lshift(self, n);
} Этот метод эквивалентен d << n.
Примеры см. в Date#<<.
static VALUE
d_lite_prev_year(int argc, VALUE *argv, VALUE self)
{
VALUE n;
rb_scan_args(argc, argv, "01", &n);
if (argc < 1)
n = INT2FIX(1);
return d_lite_lshift(self, f_mul(n, INT2FIX(12)));
} Этот метод эквивалентен d << (n * 12).
Date.new(2001,2,3).prev_year #=> #<Date: 2000-02-03 ...> Date.new(2008,2,29).prev_year #=> #<Date: 2007-02-28 ...> Date.new(2008,2,29).prev_year(4) #=> #<Date: 2004-02-29 ...>
См. также Date#<<.
static VALUE
d_lite_rfc2822(VALUE self)
{
return strftimev("%a, %-d %b %Y %T %z", self, set_tmx);
} Этот метод эквивалентен strftime(‘%a, %-d %b %Y %T %z’).
static VALUE
d_lite_rfc3339(VALUE self)
{
return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
} Этот метод эквивалентен strftime(‘%FT%T%:z’).
Создаёт новый объект Date путём парсинга строки в соответствии с типовыми форматами RFC 2822.
Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
#=> #<Date: 2001-02-03 ...>
Вызывает исключение ArgumentError, если длина строки превышает limit. Вы можете отключить эту проверку, передав ‘limit: nil`, но имейте в виду, что парсинг может занять много времени.
static VALUE
d_lite_saturday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 6);
} Возвращает true, если дата — суббота.
static VALUE
d_lite_start(VALUE self)
{
get_d1(self);
return DBL2NUM(m_sg(dat));
} Возвращает число Юлианского дня, обозначающее день реформы календаря.
Date.new(2001,2,3).start #=> 2299161.0 Date.new(2001,2,3,Date::GREGORIAN).start #=> -Infinity
static VALUE
d_lite_step(int argc, VALUE *argv, VALUE self)
{
VALUE limit, step, date;
int c;
rb_scan_args(argc, argv, "11", &limit, &step);
if (argc < 2)
step = INT2FIX(1);
#if 0
if (f_zero_p(step))
rb_raise(rb_eArgError, "step can't be 0");
#endif
RETURN_ENUMERATOR(self, argc, argv);
date = self;
c = f_cmp(step, INT2FIX(0));
if (c < 0) {
while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
rb_yield(date);
date = d_lite_plus(date, step);
}
}
else if (c == 0) {
while (1)
rb_yield(date);
}
else /* if (c > 0) */ {
while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
rb_yield(date);
date = d_lite_plus(date, step);
}
}
return self;
} Итерирует вычисление заданного блока, который принимает объект даты. Значение limit должно быть объектом даты.
Date.new(2001).step(Date.new(2001,-1,-1)).select{|d| d.sunday?}.size
#=> 52
static VALUE
d_lite_strftime(int argc, VALUE *argv, VALUE self)
{
return date_strftime_internal(argc, argv, self,
"%Y-%m-%d", set_tmx);
} Форматирует дату в соответствии с указаниями в заданной строке формата. Директивы начинаются с символа процента (%). Любой текст, не являющийся директивой, будет передан в строку вывода.
Директива состоит из символа процента (%), нуля или более флагов, необязательной минимальной ширины поля, необязательного модификатора и спецификатора преобразования следующим образом.
%<flags><width><modifier><conversion>
Флаги:
- don't pad a numerical output. _ use spaces for padding. 0 use zeros for padding. ^ upcase the result string. # change case.
Минимальная ширина поля задаёт минимальную ширину.
Модификаторы — “E”, “O”, “:”, “::” и “:::”. “E” и “O” игнорируются. В настоящее время на результат не влияют.
Директивы формата:
Date (Year, Month, Day):
%Y - Year with century (can be negative, 4 digits at least)
-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)
%B - The full month name (``January'')
%^B uppercased (``JANUARY'')
%b - The abbreviated month name (``Jan'')
%^b uppercased (``JAN'')
%h - Equivalent to %b
%d - Day of the month, zero-padded (01..31)
%-d no-padded (1..31)
%e - Day of the month, blank-padded ( 1..31)
%j - Day of the year (001..366)
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)
%I - Hour of the day, 12-hour clock, zero-padded (01..12)
%l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
%P - Meridian indicator, lowercase (``am'' or ``pm'')
%p - Meridian indicator, uppercase (``AM'' or ``PM'')
%M - Minute of the hour (00..59)
%S - Second of the minute (00..60)
%L - Millisecond of the second (000..999)
%N - Fractional seconds digits, default is 9 digits (nanosecond)
%3N millisecond (3 digits) %15N femtosecond (15 digits)
%6N microsecond (6 digits) %18N attosecond (18 digits)
%9N nanosecond (9 digits) %21N zeptosecond (21 digits)
%12N picosecond (12 digits) %24N yoctosecond (24 digits)
Time zone:
%z - Time zone as hour and minute offset from UTC (e.g. +0900)
%:z - hour and minute offset from UTC with a colon (e.g. +09:00)
%::z - hour, minute and second offset from UTC (e.g. +09:00:00)
%:::z - hour, minute and second offset from UTC
(e.g. +09, +09:30, +09:30:30)
%Z - Equivalent to %:z (e.g. +09:00)
Weekday:
%A - The full weekday name (``Sunday'')
%^A uppercased (``SUNDAY'')
%a - The abbreviated name (``Sun'')
%^a uppercased (``SUN'')
%u - Day of the week (Monday is 1, 1..7)
%w - Day of the week (Sunday is 0, 0..6)
ISO 8601 week-based year and week number:
The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
The days in the year before the first week are in the last week of
the previous year.
%G - The week-based year
%g - The last 2 digits of the week-based year (00..99)
%V - Week number of the week-based year (01..53)
Week number:
The week 1 of YYYY starts with a Sunday or Monday (according to %U
or %W). The days in the year before the first week are in week 0.
%U - Week number of the year. The week starts with Sunday. (00..53)
%W - Week number of the year. The week starts with Monday. (00..53)
Seconds since the Unix Epoch:
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
Literal string:
%n - Newline character (\n)
%t - Tab character (\t)
%% - Literal ``%'' character
Combination:
%c - date and time (%a %b %e %T %Y)
%D - Date (%m/%d/%y)
%F - The ISO 8601 date format (%Y-%m-%d)
%v - VMS date (%e-%^b-%Y)
%x - Same as %D
%X - Same as %T
%r - 12-hour time (%I:%M:%S %p)
%R - 24-hour time (%H:%M)
%T - 24-hour time (%H:%M:%S)
%+ - date(1) (%a %b %e %H:%M:%S %Z %Y) Этот метод аналогичен функции strftime() в ISO C и POSIX. Несколько директив (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* и %Z) зависят от локали в функции. Однако этот метод независим от локали. Поэтому результат может отличаться даже при использовании одной и той же строки формата в других системах, таких как C. Хорошей практикой является избегание %x и %X, так как существуют соответствующие локали-независимые представления, %D и %T.
Примеры:
d = DateTime.new(2007,11,19,8,37,48,"-06:00")
#=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007"
d.strftime("at %I:%M%p") #=> "at 08:37AM"
Различные форматы ISO 8601:
%Y%m%d => 20071119 Calendar date (basic) %F => 2007-11-19 Calendar date (extended) %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month %Y => 2007 Calendar date, reduced accuracy, specific year %C => 20 Calendar date, reduced accuracy, specific century %Y%j => 2007323 Ordinal date (basic) %Y-%j => 2007-323 Ordinal date (extended) %GW%V%u => 2007W471 Week date (basic) %G-W%V-%u => 2007-W47-1 Week date (extended) %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic) %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended) %H%M%S => 083748 Local time (basic) %T => 08:37:48 Local time (extended) %H%M => 0837 Local time, reduced accuracy, specific minute (basic) %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended) %H => 08 Local time, reduced accuracy, specific hour %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic) %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended) %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic) %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended) %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic) %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended) %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic) %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended) %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic) %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended) %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic) %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended) %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic) %FT%R => 2007-11-19T08:37 Calendar date and local time (extended) %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic) %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended) %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic) %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended)
См. также strftime(3) и ::strptime.
static VALUE
d_lite_sunday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 0);
} Возвращает true, если дата — воскресенье.
static VALUE
d_lite_thursday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 4);
} Возвращает true, если дата — четверг.
static VALUE
date_to_date(VALUE self)
{
return self;
} Возвращает self.
static VALUE
date_to_datetime(VALUE self)
{
get_d1a(self);
if (simple_dat_p(adat)) {
VALUE new = d_lite_s_alloc_simple(cDateTime);
{
get_d1b(new);
bdat->s = adat->s;
return new;
}
}
else {
VALUE new = d_lite_s_alloc_complex(cDateTime);
{
get_d1b(new);
bdat->c = adat->c;
bdat->c.df = 0;
RB_OBJ_WRITE(new, &bdat->c.sf, INT2FIX(0));
#ifndef USE_PACK
bdat->c.hour = 0;
bdat->c.min = 0;
bdat->c.sec = 0;
#else
bdat->c.pc = PACK5(EX_MON(adat->c.pc), EX_MDAY(adat->c.pc),
0, 0, 0);
bdat->c.flags |= HAVE_DF | HAVE_TIME;
#endif
return new;
}
}
} Возвращает объект DateTime, который обозначает self.
static VALUE
d_lite_to_s(VALUE self)
{
return strftimev("%Y-%m-%d", self, set_tmx);
} Возвращает строку в формате ISO 8601. (Этот метод не использует расширенные представления.)
Date.new(2001,2,3).to_s #=> "2001-02-03"
static VALUE
date_to_time(VALUE self)
{
get_d1a(self);
if (m_julian_p(adat)) {
VALUE tmp = d_lite_gregorian(self);
get_d1b(tmp);
adat = bdat;
}
return f_local3(rb_cTime,
m_real_year(adat),
INT2FIX(m_mon(adat)),
INT2FIX(m_mday(adat)));
} Возвращает объект Time, который обозначает self. Если self — дата Юлианского календаря, преобразует её в дату григорианского календаря перед преобразованием в Time.
static VALUE
d_lite_tuesday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 2);
} Возвращает true, если дата — вторник.
static VALUE
d_lite_upto(VALUE self, VALUE max)
{
VALUE date;
RETURN_ENUMERATOR(self, 1, &max);
date = self;
while (FIX2INT(d_lite_cmp(date, max)) <= 0) {
rb_yield(date);
date = d_lite_plus(date, INT2FIX(1));
}
return self;
} Этот метод эквивалентен step(max, 1){|date| …}.
static VALUE
d_lite_wday(VALUE self)
{
get_d1(self);
return INT2FIX(m_wday(dat));
} Возвращает день недели (0-6, воскресенье — ноль).
Date.new(2001,2,3).wday #=> 6
static VALUE
d_lite_wednesday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 3);
} Возвращает true, если дата — среда.
static VALUE
d_lite_yday(VALUE self)
{
get_d1(self);
return INT2FIX(m_yday(dat));
} Возвращает день года (1-366).
Date.new(2001,2,3).yday #=> 34
static VALUE
d_lite_year(VALUE self)
{
get_d1(self);
return m_real_year(dat);
} Возвращает год.
Date.new(2001,2,3).year #=> 2001 (Date.new(1,1,1) - 1).year #=> 0
Приватные методы экземпляров
static VALUE
d_lite_zero(VALUE x)
{
return INT2FIX(0);
} static VALUE
d_lite_wnum0(VALUE self)
{
get_d1(self);
return INT2FIX(m_wnum0(dat));
} static VALUE
d_lite_wnum1(VALUE self)
{
get_d1(self);
return INT2FIX(m_wnum1(dat));
}
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.