Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strftime_spec.rb SPEC test fails in "returns the timezone with %Z" #3303

Closed
tdaitx opened this issue Sep 2, 2015 · 1 comment · Fixed by #3331
Closed

strftime_spec.rb SPEC test fails in "returns the timezone with %Z" #3303

tdaitx opened this issue Sep 2, 2015 · 1 comment · Fixed by #3331

Comments

@tdaitx
Copy link
Contributor

tdaitx commented Sep 2, 2015

In certain cases Time#zone and Time#strftime("%Z") might not match, causing "returns the timezone with %Z" in spec/ruby/core/time/strftime_spec.rb to fail.

How to reproduce

One of such cases happens when running joda-time <= 2.8.0 and OpenJDK 8u60 or earlier.

Due to a change in OpenJDK 8u60, Java's DateTimeUtils.getZoneStrings() is now returning 7 elements instead of just 5, causing joda-time DefaultNameFormatter.getName() to return null. In effect causing joda-time DateTimeZone.getShortName() or DateTimeZone.getName() to return TZ in [+-]hh:mm format instead of the abbreviation name. The issue was reported in JodaOrg/joda-time#288 and JodaOrg/joda-time#291.

To reproduce simply run:

$ JAVA_HOME=<jdk8u60 home> ./bin/jruby spec/mspec/bin/mspec run spec/ruby/core/time/strftime_spec.rb

with joda-time <= 2.8.0.

Current result:

Requires OpenJDK 8u60 (or earlier) and joda-time <= 2.8.0.

Time.strftime("%Z") returns the TZ in_"[+-]hh:mm_ format (as if "%z" was given), while Time.zone returns the TZ abbreviation name.

$ ./bin/jruby spec/mspec/bin/mspec run spec/ruby/core/time/strftime_spec.rb 
jruby 1.7.21 (1.9.3p551) 2015-09-01 fffffff on OpenJDK 64-Bit Server VM 1.8.0_66-internal-b01 +jit [linux-amd64]

1)
Time#strftime returns the timezone with %Z FAILED
Expected "-03:00"
 to equal "BRT"

/build/jruby-shb6eX/jruby-1.7.21/spec/ruby/core/time/strftime_spec.rb:238:in `(root)'
org/jruby/RubyBasicObject.java:1574:in `instance_eval'
org/jruby/RubyEnumerable.java:1412:in `all?'
org/jruby/RubyFixnum.java:275:in `times'
org/jruby/RubyArray.java:1613:in `each'
/build/jruby-shb6eX/jruby-1.7.21/spec/ruby/core/time/strftime_spec.rb:4:in `(root)'
org/jruby/RubyKernel.java:1059:in `load'
org/jruby/RubyBasicObject.java:1574:in `instance_eval'
org/jruby/RubyArray.java:1613:in `each'

Expected result:

The spec states that Time#zone and Time#strftime("%Z") should always match. Also, Time.strftime documentation states that %Z - Time zone abbreviation name.

Background, why Time#zone and Time#strftime differs

JRuby's Time#zone has additional code to be able to handle a [+-]hh:mm return by DateTimeZone.getShortName() when compared to Time#strftime("%Z").

RubyTime.zone() [890-908]

        String zone = dt.getZone().getShortName(dt.getMillis());

        Matcher offsetMatcher = TIME_OFFSET_PATTERN.matcher(zone);

        if (offsetMatcher.matches()) {
            boolean minus_p = offsetMatcher.group(1).toString().equals("-");
            int hourOffset  = Integer.valueOf(offsetMatcher.group(2));

            if (zone.equals("+00:00")) {
                zone = "GMT";
            } else {
                // try non-localized time zone name
                zone = dt.getZone().getNameKey(dt.getMillis());
                if (zone == null) {
                    char sign = minus_p ? '+' : '-';
                    zone = "GMT" + sign + hourOffset;
                }
            }
        }

RubyDateFormatter.format() [489-491] and
RubyDateFormat.format() [622-624]

                case FORMAT_ZONE_ID:
                    output = dt.getZone().getShortName(dt.getMillis());
                    break;

Some code from RubyTime.zone() offsetMatcher should be refactored (or copied) into RubyDateFormatter.format() and RubyDateFormat.format() FORMAT_ZONE_ID clauses.

@headius
Copy link
Member

headius commented Sep 3, 2015

Fixed in 1.7.22 and 9.0.1.0.

@headius headius closed this as completed Sep 3, 2015
@headius headius added this to the JRuby 1.7.22 milestone Sep 3, 2015
tdaitx added a commit to tdaitx/jruby that referenced this issue Sep 4, 2015
According to the spec "%Z" and RubyTime#zone should behave the
same. This fix reuses RubyTime#zone to avoid code duplication.
tdaitx added a commit to tdaitx/jruby that referenced this issue Sep 15, 2015
According to the spec "%Z" and Time#zone should behave the
same. This fix makes use of RubyTime.getRubyTimeZoneName
to closely mimic RubyTime.zone behavior.

Note that it is still possible to fail the above spec when the
RubyTime object is created with a numeric TZ relative to UTC
(thus setting isTzRelative to true) because there is no way
to reproduce this particular behavior from within
RubyDateFormatter.
tdaitx added a commit to tdaitx/jruby that referenced this issue Sep 15, 2015
According to the spec "%Z" and Time#zone should behave the
same. This fix makes use of RubyTime.getRubyTimeZoneName
to closely mimic RubyTime.zone behavior.

Note that it is still possible to fail the above spec when the
RubyTime object is created with a numeric TZ relative to UTC
(thus setting isTzRelative to true) because there is no way
to reproduce this particular behavior from within
RubyDateFormatter.
tdaitx added a commit to tdaitx/jruby that referenced this issue Sep 16, 2015
According to the spec "%Z" and Time#zone should behave the
same. This fix makes use of RubyTime.getRubyTimeZoneName
to closely mimic RubyTime.zone behavior.

Note that it is still possible to fail the above spec when the
RubyTime object is created with a numeric TZ relative to UTC
(thus setting isTzRelative to true) because there is no way
to reproduce this particular behavior from within
RubyDateFormatter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants