класс 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. Первый — «Sun». - ABBR_MONTHNAMES
-
Массив строк с сокращёнными именами месяцев в
English. Первый элемент — null. - DAYNAMES
-
Массив строк с полными именами дней недели в
English. Первый — «Воскресенье». - ENGLAND
-
Номер Джулианского дня дня календарной реформы для Англии и её колоний.
- GREGORIAN
-
Номер Джулианского дня дня календарной реформы для пролептического григорианского календаря.
- ITALY
-
Номер Джулианского дня дня календарной реформы для Италии и некоторых католических стран.
- JULIAN
-
Номер Джулианского дня дня календарной реформы для пролептического юлианского календаря.
- MONTHNAMES
-
Массив строк с полными именами месяцев в
English. Первый элемент — null.
Публичные методы класса
static VALUE
date_s__httpdate(VALUE klass, VALUE str)
{
return date__httpdate(str);
} Возвращает хэш разобранных элементов.
static VALUE
date_s__iso8601(VALUE klass, VALUE str)
{
return date__iso8601(str);
} Возвращает хэш разобранных элементов.
static VALUE
date_s__jisx0301(VALUE klass, VALUE str)
{
return date__jisx0301(str);
} Возвращает хэш разобранных элементов.
static VALUE
date_s__parse(int argc, VALUE *argv, VALUE klass)
{
return date_s__parse_internal(argc, argv, klass);
} Разбирает заданное представление даты и времени и возвращает хэш разобранных элементов. Этот метод не работает как валидатор.
Если второй необязательный аргумент имеет значение true, а обнаруженный год находится в диапазоне от «00» до «99», рассматривает год как 2-значный и делает его полным.
Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
static VALUE
date_s__rfc2822(VALUE klass, VALUE str)
{
return date__rfc2822(str);
} Возвращает хэш разобранных элементов.
static VALUE
date_s__rfc3339(VALUE klass, VALUE str)
{
return date__rfc3339(str);
} Возвращает хэш разобранных элементов.
static VALUE
date_s__rfc2822(VALUE klass, VALUE str)
{
return date__rfc2822(str);
} Возвращает хэш разобранных элементов.
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(VALUE klass, VALUE str)
{
return date__xmlschema(str);
} Возвращает хэш разобранных элементов.
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;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__httpdate(klass, str);
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 ...>
static VALUE
date_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__iso8601(klass, str);
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 ...>
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;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__jisx0301(klass, str);
return d_new_by_frags(klass, hash, sg);
}
} Создает новый объект Date, выполняя синтаксический анализ строки в соответствии с некоторыми типичными форматами JIS X 0301.
Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
Для года без эры, устаревшего формата, предполагается Хэйсэй.
Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
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;
rb_scan_args(argc, argv, "03", &str, &comp, &sg);
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01");
case 1:
comp = Qtrue;
case 2:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE argv2[2], hash;
argv2[0] = str;
argv2[1] = comp;
hash = date_s__parse(2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
} Разбирает заданное представление даты и времени и создает объект даты. Этот метод не функционирует как валидатор.
Если второй необязательный аргумент истинен, а обнаруженный год находится в диапазоне от «00» до «99», рассматривает год как 2-значную форму и делает его полным.
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 ...>
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__rfc2822(klass, str);
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 ...>
static VALUE
date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01T00:00:00+00:00");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__rfc3339(klass, str);
return d_new_by_frags(klass, hash, sg);
}
} Создает новый объект Date, выполняя синтаксический анализ строки в соответствии с некоторыми типичными форматами RFC 3339.
Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__rfc2822(klass, str);
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 ...>
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;
rb_scan_args(argc, argv, "02", &str, &sg);
switch (argc) {
case 0:
str = rb_str_new2("-4712-01-01");
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
VALUE hash = date_s__xmlschema(klass, str);
return d_new_by_frags(klass, hash, sg);
}
} Создает новый объект Date, выполняя синтаксический анализ строки в соответствии с некоторыми типичными форматами XML Schema.
Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
Публичные методы экземпляра
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 дней после self. Значение 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 дней до self. Если 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 месяцев до self. Аргумент 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 месяцев после self. Аргумент 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).
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).
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_mday(VALUE self)
{
get_d1(self);
return INT2FIX(m_mday(dat));
} Возвращает день месяца (1-31).
Date.new(2001,2,3).mday #=> 3
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.
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_mon(VALUE self)
{
get_d1(self);
return INT2FIX(m_mon(dat));
} Возвращает месяц (1-12).
Date.new(2001,2,3).mon #=> 2
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').
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_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;
} Итерирует вычисление данного блока, принимающего объект даты. Предел должен быть объектом даты.
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_next(VALUE self)
{
return d_lite_next_day(0, (VALUE *)NULL, self);
} Возвращает объект даты, обозначающий следующий день.
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_iso8601(VALUE self)
{
return strftimev("%Y-%m-%d", self, set_tmx);
} Этот метод эквивалентен strftime('%F').
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_zero(VALUE x)
{
return INT2FIX(0);
} static VALUE
d_lite_zero(VALUE x)
{
return INT2FIX(0);
} static VALUE
d_lite_zero(VALUE x)
{
return INT2FIX(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–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.