Skip to content
Permalink
Browse files

merge revision(s) 66745,67397,67398,67399,67400,67409,67410,67411,674…

…12,67425,67426,67473,67474: [Backport #15742]

	Bump version to date-2.0.0.

	  I forgot to change it when Ruby 2.6.0 was released.

	date_parse.c: extract Japanese era initials

	* expand tabs.

	date_parse.c: removed 'r' which is not in JIS X 0301 yet

	Added tests for end of Heisei

	date: use del_hash to extract an element destructively

	* expand tabs.

	date_parse.c: renamed JAPANESE prefix as JISX0301

	date_parse.c: name JISX0301_DEFAULT_ERA

	date: make zone a substring to copy encoding and taintedness

	* expand tabs.

	date_core.c: [DOC] Heisei will be assumed if no-era [ci skip]

	date: support for Reiwa, new Japanese era

	[Feature #15742]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67527 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
nurse committed Apr 13, 2019
1 parent d8cac33 commit d6387f706834957d48e61716bc8053ec8b6aa6c5
Showing with 146 additions and 47 deletions.
  1. +6 −0 NEWS
  2. +15 −13 ext/date/date_core.c
  3. +24 −27 ext/date/date_parse.c
  4. +2 −4 ext/date/date_strptime.c
  5. +92 −1 test/date/test_date_parse.rb
  6. +6 −1 test/date/test_date_strftime.rb
  7. +1 −1 version.h
6 NEWS
@@ -529,6 +529,12 @@ sufficient information, see the ChangeLog file or Redmine
* Upgrade to 3.0.4.
See https://github.com/ruby/csv/blob/master/NEWS.md.

Date::

* Date.jisx0301, Date#jisx0301, and Date.parse provisionally support the
new Japanese era as an informal extension, until the new JIS X 0301 is
issued. [Feature #15742]

[RSS]

[New options]
@@ -3692,7 +3692,7 @@ rt_rewrite_frags(VALUE hash)
{
VALUE seconds;

seconds = ref_hash("seconds");
seconds = del_hash("seconds");
if (!NIL_P(seconds)) {
VALUE offset, d, h, min, s, fr;

@@ -3717,7 +3717,6 @@ rt_rewrite_frags(VALUE hash)
set_hash("min", min);
set_hash("sec", s);
set_hash("sec_fraction", fr);
del_hash("seconds");
}
return hash;
}
@@ -4307,16 +4306,6 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)

hash = date__parse(vstr, vcomp);

{
VALUE zone = ref_hash("zone");

if (!NIL_P(zone)) {
rb_enc_copy(zone, vstr);
OBJ_INFECT(zone, vstr);
set_hash("zone", zone);
}
}

return hash;
}

@@ -4619,6 +4608,10 @@ date_s__jisx0301(VALUE klass, VALUE str)
* some typical JIS X 0301 formats.
*
* Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
*
* For no-era year, legacy format, Heisei is assumed.
*
* Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
*/
static VALUE
date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
@@ -7046,10 +7039,14 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
c = 'S';
s = 1925;
}
else {
else if (d < 2458605) {
c = 'H';
s = 1988;
}
else {
c = 'R';
s = 2018;
}
snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s);
return fmt;
}
@@ -8156,6 +8153,11 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
*
* DateTime.jisx0301('H13.02.03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
*
* For no-era year, legacy format, Heisei is assumed.
*
* DateTime.jisx0301('13.02.03T04:05:06+07:00')
* #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
*/
static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
@@ -1212,6 +1212,9 @@ parse_iso2(VALUE str, VALUE hash)
return 1;
}

#define JISX0301_ERA_INITIALS "mtshr"
#define JISX0301_DEFAULT_ERA 'H' /* obsolete */

static int
gengo(int c)
{
@@ -1222,6 +1225,7 @@ gengo(int c)
case 'T': case 't': e = 1911; break;
case 'S': case 's': e = 1925; break;
case 'H': case 'h': e = 1988; break;
case 'R': case 'r': e = 2018; break;
default: e = 0; break;
}
return e;
@@ -1252,11 +1256,11 @@ parse_jis(VALUE str, VALUE hash)
{
static const char pat_source[] =
#ifndef TIGHT_PARSER
"\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
"\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
#else
BOS
FPW_COM FPT_COM
"([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
"([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
TEE_FPT COM_FPW
EOS
#endif
@@ -1859,30 +1863,26 @@ parse_ddd_cb(VALUE m, VALUE hash)
set_hash("zone", s5);

if (*cs5 == '[') {
VALUE vbuf = 0;
char *buf = ALLOCV_N(char, vbuf, l5 + 1);
char *s1, *s2, *s3;
const char *s1, *s2;
VALUE zone;

memcpy(buf, cs5, l5);
buf[l5 - 1] = '\0';

s1 = buf + 1;
s2 = strchr(buf, ':');
l5 -= 2;
s1 = cs5 + 1;
s2 = memchr(s1, ':', l5);
if (s2) {
*s2 = '\0';
s2++;
zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1));
s5 = rb_str_subseq(s5, 1, s2 - s1);
}
if (s2)
s3 = s2;
else
s3 = s1;
zone = rb_str_new2(s3);
else {
zone = rb_str_subseq(s5, 1, l5);
if (isdigit((unsigned char)*s1))
s5 = rb_str_append(rb_str_new_cstr("+"), zone);
else
s5 = zone;
}
set_hash("zone", zone);
if (isdigit((unsigned char)*s1))
*--s1 = '+';
set_hash("offset", date_zone_to_diff(rb_str_new2(s1)));
ALLOCV_END(vbuf);
set_hash("offset", date_zone_to_diff(s5));
}
RB_GC_GUARD(s5);
}
@@ -2175,7 +2175,7 @@ date__parse(VALUE str, VALUE comp)
#endif

{
if (RTEST(ref_hash("_bc"))) {
if (RTEST(del_hash("_bc"))) {
VALUE y;

y = ref_hash("cwyear");
@@ -2190,7 +2190,7 @@ date__parse(VALUE str, VALUE comp)
}
}

if (RTEST(ref_hash("_comp"))) {
if (RTEST(del_hash("_comp"))) {
VALUE y;

y = ref_hash("cwyear");
@@ -2213,9 +2213,6 @@ date__parse(VALUE str, VALUE comp)

}

del_hash("_bc");
del_hash("_comp");

{
VALUE zone = ref_hash("zone");
if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
@@ -2954,7 +2951,7 @@ jisx0301_cb(VALUE m, VALUE hash)
s[i] = rb_reg_nth_match(i, m);
}

ep = gengo(NIL_P(s[1]) ? 'h' : *RSTRING_PTR(s[1]));
ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1]));
set_hash("year", f_add(str2num(s[2]), INT2FIX(ep)));
set_hash("mon", str2num(s[3]));
set_hash("mday", str2num(s[4]));
@@ -2979,7 +2976,7 @@ static int
jisx0301(VALUE str, VALUE hash)
{
static const char pat_source[] =
"\\A\\s*([mtsh])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
"\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
"(?:t"
"(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?"
"(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z";
@@ -669,7 +669,7 @@ date__strptime(const char *str, size_t slen,
if (fail_p())
return Qnil;

cent = ref_hash("_cent");
cent = del_hash("_cent");
if (!NIL_P(cent)) {
VALUE year;

@@ -679,10 +679,9 @@ date__strptime(const char *str, size_t slen,
year = ref_hash("year");
if (!NIL_P(year))
set_hash("year", f_add(year, f_mul(cent, INT2FIX(100))));
del_hash("_cent");
}

merid = ref_hash("_merid");
merid = del_hash("_merid");
if (!NIL_P(merid)) {
VALUE hour;

@@ -691,7 +690,6 @@ date__strptime(const char *str, size_t slen,
hour = f_mod(hour, INT2FIX(12));
set_hash("hour", f_add(hour, merid));
}
del_hash("_merid");
}

return hash;
@@ -121,6 +121,8 @@ def test__parse
[['S40.05.23T23:55:21-09:00',false],[1965,5,23,23,55,21,'-09:00',-9*3600,nil], __LINE__],
[['H11.05.23 23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil], __LINE__],
[['H11.05.23T23:55:21Z',false],[1999,5,23,23,55,21,'Z',0,nil], __LINE__],
[['H31.04.30 23:55:21Z',false],[2019,4,30,23,55,21,'Z',0,nil], __LINE__],
[['H31.04.30T23:55:21Z',false],[2019,4,30,23,55,21,'Z',0,nil], __LINE__],

# ofx date
[['19990523235521',false],[1999,5,23,23,55,21,nil,nil,nil], __LINE__],
@@ -416,7 +418,14 @@ def test__parse
a[1] = -1
a[2] = h[:yday]
end
assert_equal(y, a, format('<failed at line %d>', l))
l = format('<failed at line %d>', l)
assert_equal(y, a, l)
if y[6]
h = Date._parse(x[0].dup.taint, *x[1..-1])
assert_equal(y[6], h[:zone], l)
assert_equal(y[6].encoding, h[:zone].encoding, l)
assert_predicate(h[:zone], :tainted?, l)
end
end
end

@@ -984,6 +993,15 @@ def test__jisx0301
h = Date._jisx0301('S63.02.03')
assert_equal([1988, 2, 3, nil, nil, nil, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.04.30')
assert_equal([2019, 4, 30, nil, nil, nil, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.05.01')
assert_equal([2019, 5, 1, nil, nil, nil, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('R01.05.01')
assert_equal([2019, 5, 1, nil, nil, nil, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))

h = Date._jisx0301('H13.02.03T04:05:06')
assert_equal([2001, 2, 3, 4, 5, 6, nil],
@@ -998,6 +1016,45 @@ def test__jisx0301
assert_equal([2001, 2, 3, 4, 5, 6, 3600],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))

h = Date._jisx0301('H31.04.30T04:05:06')
assert_equal([2019, 4, 30, 4, 5, 6, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.04.30T04:05:06,07')
assert_equal([2019, 4, 30, 4, 5, 6, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.04.30T04:05:06Z')
assert_equal([2019, 4, 30, 4, 5, 6, 0],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.04.30T04:05:06.07+0100')
assert_equal([2019, 4, 30, 4, 5, 6, 3600],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))

h = Date._jisx0301('H31.05.01T04:05:06')
assert_equal([2019, 5, 1, 4, 5, 6, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.05.01T04:05:06,07')
assert_equal([2019, 5, 1, 4, 5, 6, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.05.01T04:05:06Z')
assert_equal([2019, 5, 1, 4, 5, 6, 0],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('H31.05.01T04:05:06.07+0100')
assert_equal([2019, 5, 1, 4, 5, 6, 3600],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))

h = Date._jisx0301('R01.05.01T04:05:06')
assert_equal([2019, 5, 1, 4, 5, 6, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('R01.05.01T04:05:06,07')
assert_equal([2019, 5, 1, 4, 5, 6, nil],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('R01.05.01T04:05:06Z')
assert_equal([2019, 5, 1, 4, 5, 6, 0],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
h = Date._jisx0301('R01.05.01T04:05:06.07+0100')
assert_equal([2019, 5, 1, 4, 5, 6, 3600],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))

h = Date._jisx0301('')
assert_equal({}, h)
end
@@ -1083,9 +1140,33 @@ def test_jisx0301
assert_equal(Date.new(2001,2,3), d)
assert_equal(Date::ITALY + 10, d.start)

d = Date.jisx0301('H31.04.30', Date::ITALY + 10)
assert_equal(Date.new(2019,4,30), d)
assert_equal(Date::ITALY + 10, d.start)

d = Date.jisx0301('H31.05.01', Date::ITALY + 10)
assert_equal(Date.new(2019,5,1), d)
assert_equal(Date::ITALY + 10, d.start)

d = Date.jisx0301('R01.05.01', Date::ITALY + 10)
assert_equal(Date.new(2019,5,1), d)
assert_equal(Date::ITALY + 10, d.start)

d = DateTime.jisx0301('H13.02.03T04:05:06+07:00', Date::ITALY + 10)
assert_equal(DateTime.new(2001,2,3,4,5,6,'+07:00'), d)
assert_equal(Date::ITALY + 10, d.start)

d = DateTime.jisx0301('H31.04.30T04:05:06+07:00', Date::ITALY + 10)
assert_equal(DateTime.new(2019,4,30,4,5,6,'+07:00'), d)
assert_equal(Date::ITALY + 10, d.start)

d = DateTime.jisx0301('H31.05.01T04:05:06+07:00', Date::ITALY + 10)
assert_equal(DateTime.new(2019,5,1,4,5,6,'+07:00'), d)
assert_equal(Date::ITALY + 10, d.start)

d = DateTime.jisx0301('R01.05.01T04:05:06+07:00', Date::ITALY + 10)
assert_equal(DateTime.new(2019,5,1,4,5,6,'+07:00'), d)
assert_equal(Date::ITALY + 10, d.start)
end

def test_given_string
@@ -1120,6 +1201,16 @@ def test_given_string
s0 = s.dup
assert_not_equal({}, Date._jisx0301(s))
assert_equal(s0, s)

s = 'H31.04.30T04:05:06,07Z'
s0 = s.dup
assert_not_equal({}, Date._jisx0301(s))
assert_equal(s0, s)

s = 'H31.05.01T04:05:06,07Z'
s0 = s.dup
assert_not_equal({}, Date._jisx0301(s))
assert_equal(s0, s)
end

end
@@ -406,6 +406,8 @@ def test__different_format
assert_equal('S64.01.07', Date.parse('1989-01-07').jisx0301)
assert_equal('H01.01.08', Date.parse('1989-01-08').jisx0301)
assert_equal('H18.09.01', Date.parse('2006-09-01').jisx0301)
assert_equal('H31.04.30', Date.parse('2019-04-30').jisx0301)
assert_equal('R01.05.01', Date.parse('2019-05-01').jisx0301)

%w(M06.01.01
M45.07.29
@@ -414,7 +416,10 @@ def test__different_format
S01.12.25
S64.01.07
H01.01.08
H18.09.01).each do |s|
H18.09.01
H31.04.30
R01.05.01
).each do |s|
assert_equal(s, Date.parse(s).jisx0301)
end

Oops, something went wrong.

0 comments on commit d6387f7

Please sign in to comment.
You can’t perform that action at this time.