Date 类
Date 类提供了存储和操作日历日期的方法。
如果满足以下条件,请考虑使用 Time 类 而不是 Date 类:
-
你需要日期和时间;Date 类只处理日期。
-
你只需要格里高利日期(而不是儒略日期);请参阅 儒略和格里高利日历。
Date 对象一旦创建,就不可变,无法修改。
创建 Date 对象¶ ↑
你可以使用 Date.today 创建当前日期的 Date 对象
Date.today # => #<Date: 1999-12-31>
你可以使用各种参数组合创建特定的日期
-
Date.new接受整数年、月和日Date.new(1999, 12, 31) # => #<Date: 1999-12-31>
-
Date.ordinal接受整数年和一年中的第几天Date.ordinal(1999, 365) # => #<Date: 1999-12-31>
-
Date.jd接受整数儒略日Date.jd(2451544) # => #<Date: 1999-12-31>
-
Date.commercial接受整数商业数据(年、周、一周中的第几天)Date.commercial(1999, 52, 5) # => #<Date: 1999-12-31>
-
Date.parse接受一个字符串,并进行启发式解析Date.parse('1999-12-31') # => #<Date: 1999-12-31> Date.parse('31-12-1999') # => #<Date: 1999-12-31> Date.parse('1999-365') # => #<Date: 1999-12-31> Date.parse('1999-W52-5') # => #<Date: 1999-12-31>
-
Date.strptime接受一个日期字符串和一个格式字符串,然后根据格式字符串解析日期字符串Date.strptime('1999-12-31', '%Y-%m-%d') # => #<Date: 1999-12-31> Date.strptime('31-12-1999', '%d-%m-%Y') # => #<Date: 1999-12-31> Date.strptime('1999-365', '%Y-%j') # => #<Date: 1999-12-31> Date.strptime('1999-W52-5', '%G-W%V-%u') # => #<Date: 1999-12-31> Date.strptime('1999 52 5', '%Y %U %w') # => #<Date: 1999-12-31> Date.strptime('1999 52 5', '%Y %W %u') # => #<Date: 1999-12-31> Date.strptime('fri31dec99', '%a%d%b%y') # => #<Date: 1999-12-31>
另请参阅 日期和时间格式中的“专用格式字符串”中的专门方法
参数 limit¶ ↑
Date 中某些解析字符串参数的单例方法还接受可选的关键字参数 limit,它可以限制字符串参数的长度。
当 limit 为
-
非负数:如果字符串长度大于 limit,则引发
ArgumentError异常。 -
其他数值或
nil:忽略limit。 -
其他非数值:引发
TypeError异常。
常量
- ABBR_DAYNAMES
-
一个包含
English中缩写星期名称的字符串数组。第一个是 “Sun”。 - ABBR_MONTHNAMES
-
一个包含
English中缩写月份名称的字符串数组。第一个元素是 nil。 - DAYNAMES
-
一个包含
English中完整星期名称的字符串数组。第一个是 “Sunday”。 - ENGLAND
-
英格兰及其殖民地日历改革日期的儒略日数值。
- GREGORIAN
-
前推格里高利历日历改革日期的儒略日数值。
- ITALY
-
意大利和一些天主教国家日历改革日期的儒略日数值。
- JULIAN
-
前推儒略历日历改革日期的儒略日数值。
- MONTHNAMES
-
一个包含
English中完整月份名称的字符串数组。第一个元素是 nil。
公共类方法
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该是有效的 HTTP 日期格式
d = Date.new(2001, 2, 3) s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" Date._httpdate(s) # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0}
相关:Date.httpdate(返回 Date 对象)。
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该包含 ISO 8601 格式的日期
d = Date.new(2001, 2, 3) s = d.iso8601 # => "2001-02-03" Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2}
请参阅参数 limit。
相关:Date.iso8601(返回 Date 对象)。
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该是有效的 JIS X 0301 日期格式
d = Date.new(2001, 2, 3) s = d.jisx0301 # => "H13.02.03" Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3}
请参阅参数 limit。
相关:Date.jisx0301(返回 Date 对象)。
源代码
static VALUE
date_s__parse(int argc, VALUE *argv, VALUE klass)
{
return date_s__parse_internal(argc, argv, klass);
}
注意:此方法可以识别 string 中的多种格式,但它不是验证器。有关格式,请参阅日期和时间格式中的“专用格式字符串”
如果 string 未指定有效日期,则结果不可预测;请考虑改用 Date._strptime。
返回从 string 解析的值的哈希值
Date._parse('2001-02-03') # => {:year=>2001, :mon=>2, :mday=>3}
如果 comp 为 true 并且给定的年份在 (0..99) 范围内,则提供当前世纪;否则,年份按原样获取
Date._parse('01-02-03', true) # => {:year=>2001, :mon=>2, :mday=>3} Date._parse('01-02-03', false) # => {:year=>1, :mon=>2, :mday=>3}
请参阅参数 limit。
相关:Date.parse(返回 Date 对象)。
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该是有效的 RFC 2822 日期格式
d = Date.new(2001, 2, 3) s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" Date._rfc2822(s) # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0}
请参阅参数 limit。
相关:Date.rfc2822(返回 Date 对象)。
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该是有效的 RFC 3339 格式
d = Date.new(2001, 2, 3) s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" Date._rfc3339(s) # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0}
请参阅参数 limit。
相关:Date.rfc3339(返回 Date 对象)。
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该是有效的 RFC 2822 日期格式
d = Date.new(2001, 2, 3) s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" Date._rfc2822(s) # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0}
请参阅参数 limit。
相关:Date.rfc2822(返回 Date 对象)。
源代码
static VALUE
date_s__strptime(int argc, VALUE *argv, VALUE klass)
{
return date_s__strptime_internal(argc, argv, klass, "%F");
}
返回根据给定 format 从 string 解析的值的哈希值
Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3}
有关其他格式,请参阅日期和时间格式。(与 Date.strftime 不同,不支持标志和宽度。)
另请参阅 strptime(3)。
相关:Date.strptime(返回 Date 对象)。
源代码
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);
}
返回从 string 解析的值的哈希值,string 应该是有效的 XML 日期格式
d = Date.new(2001, 2, 3) s = d.xmlschema # => "2001-02-03" Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3}
请参阅参数 limit。
相关:Date.xmlschema(返回 Date 对象)。
源代码
static VALUE
date_s_civil(int argc, VALUE *argv, VALUE klass)
{
return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
}
与 Date.new 相同。
源代码
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 对象。
参数 cwyear 提供年份,并且应该是一个整数。
参数 cweek 提供一年中周的索引,并且应该在 (1..53) 或 (-53..-1) 范围内;在某些年份,53 或 -53 将超出范围;如果为负数,则从年末倒数
Date.commercial(2022, 1, 1).to_s # => "2022-01-03" Date.commercial(2022, 52, 1).to_s # => "2022-12-26"
参数 cwday 提供一周中工作日的索引,并且应该在 (1..7) 或 (-7..-1) 范围内;1 或 -7 是星期一;如果为负数,则从周末倒数
Date.commercial(2022, 1, 1).to_s # => "2022-01-03" Date.commercial(2022, 1, -7).to_s # => "2022-01-03"
当 cweek 为 1 时
-
如果 1 月 1 日是星期五、星期六或星期日,则第一周在之后的那一周开始
Date::ABBR_DAYNAMES[Date.new(2023, 1, 1).wday] # => "Sun" Date.commercial(2023, 1, 1).to_s # => "2023-01-02" Date.commercial(2023, 1, 7).to_s # => "2023-01-08"
-
否则,第一周是 1 月 1 日所在的周,这可能意味着某些日子落在前一年
Date::ABBR_DAYNAMES[Date.new(2020, 1, 1).wday] # => "Wed" Date.commercial(2020, 1, 1).to_s # => "2019-12-30" Date.commercial(2020, 1, 7).to_s # => "2020-01-05"
请参阅参数 start。
源代码
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,否则返回 false
Date.gregorian_leap?(2000) # => true Date.gregorian_leap?(2001) # => false
源代码
static VALUE
date_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__httpdate(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个新 Date 对象,其值从 string 解析而来,string 应该是有效的 HTTP 日期格式
d = Date.new(2001, 2, 3) s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" Date.httpdate(s) # => #<Date: 2001-02-03>
请参阅
相关:Date._httpdate(返回哈希值)。
源代码
static VALUE
date_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATE);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__iso8601(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个新 Date 对象,其值从 string 解析而来,string 应该包含 ISO 8601 格式的日期
d = Date.new(2001, 2, 3) s = d.iso8601 # => "2001-02-03" Date.iso8601(s) # => #<Date: 2001-02-03>
请参阅
相关:Date._iso8601(返回哈希值)。
源代码
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 对象
Date.jd(2451944).to_s # => "2001-02-03" Date.jd(2451945).to_s # => "2001-02-04" Date.jd(0).to_s # => "-4712-01-01"
返回的日期是
-
格里高利日期,如果参数大于或等于
startDate::ITALY # => 2299161 Date.jd(Date::ITALY).gregorian? # => true Date.jd(Date::ITALY + 1).gregorian? # => true
-
儒略日期,否则
Date.jd(Date::ITALY - 1).julian? # => true
请参阅参数 start。
相关:Date.new。
源代码
static VALUE
date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATE);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__jisx0301(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个新 Date 对象,其值从 string 解析而来,string 应该是有效的 JIS X 0301 格式
d = Date.new(2001, 2, 3) s = d.jisx0301 # => "H13.02.03" Date.jisx0301(s) # => #<Date: 2001-02-03>
对于非纪元年份,传统格式,假设为平成。
Date.jisx0301('13.02.03') # => #<Date: 2001-02-03>
请参阅
相关:Date._jisx0301(返回哈希值)。
源代码
# File ext/json/lib/json/add/date.rb, line 10 def self.json_create(object) civil(*object.values_at('y', 'm', 'd', 'sg')) end
请参阅 as_json。
源代码
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,否则返回 false
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,否则返回 false
Date.gregorian_leap?(2000) # => true Date.gregorian_leap?(2001) # => false
源代码
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;
}
返回一个使用给定参数构造的新 Date 对象
Date.new(2022).to_s # => "2022-01-01" Date.new(2022, 2).to_s # => "2022-02-01" Date.new(2022, 2, 4).to_s # => "2022-02-04"
参数 month 应该在 (1..12) 或 (-12..-1) 范围内;当参数为负数时,从年末倒数
Date.new(2022, -11, 4).to_s # => "2022-02-04"
参数 mday 的取值范围应为 (1..n) 或 (-n..-1),其中 n 是该月的天数;当参数为负数时,从月末开始倒数。
请参阅参数 start。
相关方法:Date.jd。
源代码
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 对象。
无参数时,返回公元前 4712 年 1 月 1 日的日期。
Date.ordinal.to_s # => "-4712-01-01"
带有参数 year 时,返回该年 1 月 1 日的日期。
Date.ordinal(2001).to_s # => "2001-01-01" Date.ordinal(-2001).to_s # => "-2001-01-01"
带有正数参数 yday == n 时,返回给定年份的第 n 天的日期。
Date.ordinal(2001, 14).to_s # => "2001-01-14"
带有负数参数 yday 时,从年末开始倒数。
Date.ordinal(2001, -14).to_s # => "2001-12-18"
如果 yday 为零或超出范围,则会引发异常。
请参阅参数 start。
源代码
static VALUE
date_s_parse(int argc, VALUE *argv, VALUE klass)
{
VALUE str, comp, sg, opt;
argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATE);
case 1:
comp = Qtrue;
case 2:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 2;
VALUE argv2[3], hash;
argv2[0] = str;
argv2[1] = comp;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__parse(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
注意:此方法可以识别 string 中的多种格式,但它不是验证器。有关格式,请参阅日期和时间格式中的“专用格式字符串”。如果 string 未指定有效的日期,则结果是不可预测的;请考虑改用 Date._strptime。
返回一个从 string 解析出的值的新 Date 对象。
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>
如果 comp 为 true 并且给定的年份在 (0..99) 范围内,则提供当前世纪;否则,年份按原样获取
Date.parse('01-02-03', true) # => #<Date: 2001-02-03> Date.parse('01-02-03', false) # => #<Date: 0001-02-03>
请参阅
相关方法:Date._parse (返回一个哈希)。
源代码
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__rfc2822(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个从 string 解析出的值的新 Date 对象,该 string 应为有效的 RFC 2822 日期格式。
d = Date.new(2001, 2, 3) s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" Date.rfc2822(s) # => #<Date: 2001-02-03>
请参阅
相关方法:Date._rfc2822 (返回一个哈希)。
源代码
static VALUE
date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATETIME);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__rfc3339(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个从 string 解析出的值的新 Date 对象,该 string 应为有效的 RFC 3339 格式。
d = Date.new(2001, 2, 3) s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" Date.rfc3339(s) # => #<Date: 2001-02-03>
请参阅
相关方法:Date._rfc3339 (返回一个哈希)。
源代码
static VALUE
date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__rfc2822(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个从 string 解析出的值的新 Date 对象,该 string 应为有效的 RFC 2822 日期格式。
d = Date.new(2001, 2, 3) s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" Date.rfc2822(s) # => #<Date: 2001-02-03>
请参阅
相关方法:Date._rfc2822 (返回一个哈希)。
源代码
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(JULIAN_EPOCH_DATE);
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);
}
}
返回一个根据给定的 format 从 string 解析出的值的新 Date 对象。
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>
有关其他格式,请参阅日期和时间格式。(与 Date.strftime 不同,不支持标志和宽度。)
请参阅参数 start。
另请参阅 strptime(3)。
相关方法:Date._strptime (返回一个哈希)。
源代码
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 对象。
Date.today.to_s # => "2022-07-06"
请参阅参数 start。
源代码
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。
Date.valid_date?(2001, 2, 3) # => true Date.valid_date?(2001, 2, 29) # => false Date.valid_date?(2001, 2, -1) # => true
请参阅参数 start。
源代码
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
请参阅 Date.commercial。
请参阅参数 start。
相关方法:Date.jd、Date.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。
Date.valid_date?(2001, 2, 3) # => true Date.valid_date?(2001, 2, 29) # => false Date.valid_date?(2001, 2, -1) # => true
请参阅参数 start。
源代码
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;
}
为了兼容性而实现;除非 jd 无效(即不是 Numeric),否则返回 true。
Date.valid_jd?(2451944) # => true
请参阅参数 start。
相关方法:Date.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
请参阅参数 start。
相关方法:Date.jd、Date.ordinal。
源代码
static VALUE
date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
VALUE str, sg, opt;
argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
switch (argc) {
case 0:
str = rb_str_new2(JULIAN_EPOCH_DATE);
case 1:
sg = INT2FIX(DEFAULT_SG);
}
{
int argc2 = 1;
VALUE argv2[2], hash;
argv2[0] = str;
if (!NIL_P(opt)) argv2[argc2++] = opt;
hash = date_s__xmlschema(argc2, argv2, klass);
return d_new_by_frags(klass, hash, sg);
}
}
返回一个从 string 解析出的值的新 Date 对象,该 string 应为有效的 XML 日期格式。
d = Date.new(2001, 2, 3) s = d.xmlschema # => "2001-02-03" Date.xmlschema(s) # => #<Date: 2001-02-03>
请参阅
相关方法:Date._xmlschema (返回一个哈希)。
公共实例方法
源代码
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;
}
}
返回一个指向自 self 之后 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 是一个日期对象,则返回一个 Rational,其值是两个日期之间的天数差。如果 other 是一个数值,则返回一个指向 self 之前 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 个月前日期的新 Date 对象;n 应该是一个数值。
(Date.new(2001, 2, 3) << 1).to_s # => "2001-01-03" (Date.new(2001, 2, 3) << -2).to_s # => "2001-04-03"
当新月份不存在同一天时,将使用该月的最后一天代替。
(Date.new(2001, 3, 31) << 1).to_s # => "2001-02-28" (Date.new(2001, 3, 31) << -6).to_s # => "2001-09-30"
这会导致以下可能出乎意料的行为
d0 = Date.new(2001, 3, 31) d0 << 2 # => #<Date: 2001-01-31> d0 << 1 << 1 # => #<Date: 2001-01-28> d0 = Date.new(2001, 3, 31) d1 = d0 << 1 # => #<Date: 2001-02-28> d2 = d1 << -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);
}
}
}
}
比较 self 和 other,返回:
-
如果
other较大,则返回-1。 -
如果两者相等,则返回
0。 -
如果
other较小,则返回1。 -
如果两者不可比较,则返回
nil。
参数 other 可以是:
-
另一个 Date 对象
d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)> prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)> next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)> d <=> next_date # => -1 d <=> d # => 0 d <=> prev_date # => 1
-
一个
DateTime对象d <=> DateTime.new(2022, 7, 26) # => 1 d <=> DateTime.new(2022, 7, 27) # => 0 d <=> DateTime.new(2022, 7, 28) # => -1
-
一个数值(将
self.ajd与other进行比较)d <=> 2459788 # => -1 d <=> 2459787 # => 1 d <=> 2459786 # => 1 d <=> d.ajd # => 0
-
任何其他对象
d <=> Object.new # => nil
源代码
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;
}
}
}
如果 self 和 other 表示相同的日期,则返回 true,如果不是,则返回 false,如果两者不可比较,则返回 nil。
参数 other 可以是:
-
另一个 Date 对象
d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)> prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)> next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)> d === prev_date # => false d === d # => true d === next_date # => false
-
一个
DateTime对象d === DateTime.new(2022, 7, 26) # => false d === DateTime.new(2022, 7, 27) # => true d === DateTime.new(2022, 7, 28) # => false
-
一个数值(将
self.jd与other进行比较)d === 2459788 # => true d === 2459787 # => false d === 2459786 # => false d === d.jd # => true
-
一个不可比较的对象
d === Object.new # => nil
源代码
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 个月后日期的新 Date 对象;n 应该是一个数值。
(Date.new(2001, 2, 3) >> 1).to_s # => "2001-03-03" (Date.new(2001, 2, 3) >> -2).to_s # => "2000-12-03"
当新月份不存在同一天时,将使用该月的最后一天代替。
(Date.new(2001, 1, 31) >> 1).to_s # => "2001-02-28" (Date.new(2001, 1, 31) >> -4).to_s # => "2000-09-30"
这会导致以下可能出乎意料的行为
d0 = Date.new(2001, 1, 31) d1 = d0 >> 1 # => #<Date: 2001-02-28> d2 = d1 >> 1 # => #<Date: 2001-03-28> d0 = Date.new(2001, 1, 31) d1 = d0 >> 1 # => #<Date: 2001-02-28> d2 = d1 >> -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 32 def as_json(*) { JSON.create_id => self.class.name, 'y' => year, 'm' => month, 'd' => day, 'sg' => start, } end
方法 Date#as_json 和 Date.json_create 可用于序列化和反序列化 Date 对象;请参阅 Marshal。
方法 Date#as_json 序列化 self,返回一个表示 self 的包含 2 个元素的哈希。
require 'json/add/date' x = Date.today.as_json # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
方法 JSON.create 反序列化此类哈希,返回一个 Date 对象。
Date.json_create(x) # => #<Date: 2023-11-21 ((2460270j,0s,0n),+0s,2299161j)>
源代码
static VALUE
d_lite_cwday(VALUE self)
{
get_d1(self);
return INT2FIX(m_cwday(dat));
}
返回 self 的商业日期工作日索引(请参阅 Date.commercial);1 表示星期一。
Date.new(2001, 2, 3).cwday # => 6
源代码
static VALUE
d_lite_cweek(VALUE self)
{
get_d1(self);
return INT2FIX(m_cweek(dat));
}
返回 self 的商业日期周索引(请参阅 Date.commercial)。
Date.new(2001, 2, 3).cweek # => 5
源代码
static VALUE
d_lite_cwyear(VALUE self)
{
get_d1(self);
return m_real_cwyear(dat);
}
返回 self 的商业日期年份(请参阅 Date.commercial)。
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);
}
返回一天中小数部分,范围为 (Rational(0, 1)…Rational(1, 1))。
DateTime.new(2001,2,3,12).day_fraction # => (1/2)
源代码
static VALUE
d_lite_deconstruct_keys(VALUE self, VALUE keys)
{
return deconstruct_keys(self, keys, /* is_datetime=false */ 0);
}
返回名称/值对的哈希,用于模式匹配。可能的键为::year、:month、:day、:wday、:yday。
可能的用法
d = Date.new(2022, 10, 5) if d in wday: 3, day: ..7 # uses deconstruct_keys underneath puts "first Wednesday of the month" end #=> prints "first Wednesday of the month" case d in year: ...2022 puts "too old" in month: ..9 puts "quarter 1-3" in wday: 1..5, month: puts "working day in month #{month}" end #=> prints "working day in month 10"
请注意,通过模式进行的解构也可以与类检查相结合
if d in Date(wday: 3, day: ..7) puts "first Wednesday of the month" end
源代码
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;
}
等效于带有参数 min 和 -1 的 step。
源代码
static VALUE
d_lite_england(VALUE self)
{
return dup_obj_with_new_start(self, ENGLAND);
}
等效于带有参数 Date::ENGLAND 的 Date#new_start。
源代码
static VALUE
d_lite_friday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 5);
}
如果 self 是星期五,则返回 true,否则返回 false。
源代码
static VALUE
d_lite_gregorian(VALUE self)
{
return dup_obj_with_new_start(self, GREGORIAN);
}
等效于带有参数 Date::GREGORIAN 的 Date#new_start。
源代码
static VALUE
d_lite_gregorian_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_gregorian_p(dat));
}
如果日期在日历改革日期或之后,则返回 true,否则返回 false。
Date.new(1582, 10, 15).gregorian? # => true (Date.new(1582, 10, 15) - 1).gregorian? # => false
源代码
源代码
static VALUE
d_lite_inspect(VALUE self)
{
get_d1(self);
return mk_inspect(dat, rb_obj_class(self), self);
}
返回 self 的字符串表示形式。
Date.new(2001, 2, 3).inspect # => "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>"
源代码
static VALUE
d_lite_iso8601(VALUE self)
{
return strftimev("%Y-%m-%d", self, set_tmx);
}
等效于带有参数 '%Y-%m-%d' (或其 简写形式 '%F') 的 strftime;
Date.new(2001, 2, 3).iso8601 # => "2001-02-03"
源代码
static VALUE
d_lite_italy(VALUE self)
{
return dup_obj_with_new_start(self, ITALY);
}
等效于带有参数 Date::ITALY 的 Date#new_start。
源代码
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);
}
返回 self 中日期的 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);
}
等效于带有参数 Date::JULIAN 的 Date#new_start。
源代码
static VALUE
d_lite_julian_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_julian_p(dat));
}
如果日期在日历改革日期之前,则返回 true,否则返回 false。
(Date.new(1582, 10, 15) - 1).julian? # => true Date.new(1582, 10, 15).julian? # => false
源代码
static VALUE
d_lite_ld(VALUE self)
{
get_d1(self);
return f_sub(m_real_local_jd(dat), INT2FIX(2299160));
}
返回 Lilian 日期编号,这是自公历开始(1582 年 10 月 15 日)以来的天数。
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,否则返回 false。
Date.new(2000).leap? # => true Date.new(2001).leap? # => false
源代码
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);
}
如果 self 是星期一,则返回 true,否则返回 false。
源代码
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);
}
返回 self 的一个副本,并带有给定的 start 值。
d0 = Date.new(2000, 2, 3) d0.julian? # => false d1 = d0.new_start(Date::JULIAN) d1.julian? # => true
请参阅参数 start。
源代码
static VALUE
d_lite_next(VALUE self)
{
return d_lite_next_day(0, (VALUE *)NULL, self);
}
返回一个表示下一天的新 Date 对象。
d = Date.new(2001, 2, 3) d.to_s # => "2001-02-03" d.next.to_s # => "2001-02-04"
源代码
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);
}
等效于带有参数 n 的 Date#+。
源代码
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);
}
等效于带有参数 n 的 >>。
源代码
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)));
}
等效于带有参数 n * 12 的 >>。
源代码
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);
}
等效于带有参数 n 的 Date#-。
源代码
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);
}
等效于带有参数 n 的 <<。
源代码
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)));
}
等效于带有参数 n * 12 的 <<。
源代码
static VALUE
d_lite_rfc2822(VALUE self)
{
return strftimev("%a, %-d %b %Y %T %z", self, set_tmx);
}
等效于带有参数 '%a, %-d %b %Y %T %z' 的 strftime;请参阅 日期和时间格式。
Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
源代码
源代码
static VALUE
d_lite_saturday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 6);
}
如果 self 是星期六,则返回 true,否则返回 false。
源代码
static VALUE
d_lite_start(VALUE self)
{
get_d1(self);
return DBL2NUM(m_sg(dat));
}
返回日历改革的儒略起始日期;如果不是无穷大,则返回的值适合传递给 Date#jd。
d = Date.new(2001, 2, 3, Date::ITALY) s = d.start # => 2299161.0 Date.jd(s).to_s # => "1582-10-15" d = Date.new(2001, 2, 3, Date::ENGLAND) s = d.start # => 2361222.0 Date.jd(s).to_s # => "1752-09-14" Date.new(2001, 2, 3, Date::GREGORIAN).start # => -Infinity Date.new(2001, 2, 3, Date::JULIAN).start # => Infinity
请参阅参数 start。
源代码
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;
}
使用指定的日期调用代码块;返回 self。
-
第一个
date是self。 -
每个连续的
date是date + step,其中step是以天为单位的数字步长。 -
最后一个日期是小于或等于
limit的最后一个日期,limit应该是一个 Date 对象。
示例
limit = Date.new(2001, 12, 31) Date.new(2001).step(limit){|date| p date.to_s if date.mday == 31 }
输出
"2001-01-31" "2001-03-31" "2001-05-31" "2001-07-31" "2001-08-31" "2001-10-31" "2001-12-31"
如果没有给出代码块,则返回一个 Enumerator。
源代码
static VALUE
d_lite_strftime(int argc, VALUE *argv, VALUE self)
{
return date_strftime_internal(argc, argv, self,
"%Y-%m-%d", set_tmx);
}
返回 self 中日期的字符串表示形式,根据给定的 format 格式化。
Date.new(2001, 2, 3).strftime # => "2001-02-03"
有关其他格式,请参阅 日期和时间的格式。
源代码
static VALUE
d_lite_sunday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 0);
}
如果 self 是星期日,则返回 true,否则返回 false。
源代码
static VALUE
d_lite_thursday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 4);
}
如果 self 是星期四,则返回 true,否则返回 false。
源代码
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 相同。
Date.new(2001, 2, 3).to_datetime # => #<DateTime: 2001-02-03T00:00:00+00:00>
源代码
# File ext/json/lib/json/add/date.rb, line 51 def to_json(*args) as_json.to_json(*args) end
返回表示 self 的 JSON 字符串。
require 'json/add/date' puts Date.today.to_json
输出
{"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0}
源代码
static VALUE
d_lite_to_s(VALUE self)
{
return strftimev("%Y-%m-%d", self, set_tmx);
}
返回 self 中日期的字符串表示形式,采用 ISO 8601 扩展日期格式 ('%Y-%m-%d')。
Date.new(2001, 2, 3).to_s # => "2001-02-03"
源代码
static VALUE
date_to_time(VALUE self)
{
VALUE t;
get_d1a(self);
if (m_julian_p(adat)) {
VALUE g = d_lite_gregorian(self);
get_d1b(g);
adat = bdat;
self = g;
}
t = f_local3(rb_cTime,
m_real_year(adat),
INT2FIX(m_mon(adat)),
INT2FIX(m_mday(adat)));
RB_GC_GUARD(self); /* may be the converted gregorian */
return t;
}
返回一个新的 Time 对象,其值与 self 相同;如果 self 是一个儒略日期,则会导出其公历日期以转换为 Time 对象。
Date.new(2001, 2, 3).to_time # => 2001-02-03 00:00:00 -0600 Date.new(2001, 2, 3, Date::JULIAN).to_time # => 2001-02-16 00:00:00 -0600
源代码
static VALUE
d_lite_tuesday_p(VALUE self)
{
get_d1(self);
return f_boolcast(m_wday(dat) == 2);
}
如果 self 是星期二,则返回 true,否则返回 false。
源代码
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;
}
等同于使用参数 max 和 1 的 step。
源代码
static VALUE
d_lite_wday(VALUE self)
{
get_d1(self);
return INT2FIX(m_wday(dat));
}
返回一周中的第几天,范围为 (0..6);星期日是 0。
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);
}
如果 self 是星期三,则返回 true,否则返回 false。
源代码
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