Created
February 6, 2013 06:07
-
-
Save tmm1/4720711 to your computer and use it in GitHub Desktop.
Fix marshal incompatibility between Date/DateTime on 1.8 and 1.9
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'date' | |
class Date | |
if RUBY_VERSION < '1.9' | |
## accept 1.9 marshaled data on 1.8 | |
## based on ext/date/date_core.c d_lite_marshal_dump_old | |
def marshal_load(data) | |
nth, jd, df, sf, of, @sg = data | |
real_jd = | |
if nth == 0 | |
jd | |
else | |
jd + nth * (0xfffffff / 71149239 * 71149239) | |
end | |
if jd == 0 && sf == 0 && of == 0 | |
@ajd = Rational.new!(real_jd * 2 - 1, 2) | |
else | |
df -= 86400 / 2 | |
if df != 0 | |
real_jd += Rational.new!(df, 86400) | |
end | |
if sf != 0 | |
real_jd += Rational.new!(sf, 86400 * 1000000000) | |
end | |
@ajd = real_jd | |
@of = Rational.new!(of, 86400) | |
end | |
end | |
else | |
## accept 1.8 marshaled data on 1.9 | |
## based on ruby/1.8/date.rb Date._load | |
class ::FakeRational | |
def to_r | |
Rational(@numerator, @denominator) | |
end | |
end | |
def self._load(str) | |
ajd, of, sg = Marshal.load(str.gsub("\rRational","\x11FakeRational")) | |
ajd = ajd.to_r if ajd.is_a?(FakeRational) | |
of = of.to_r if of.is_a?(FakeRational) | |
new.marshal_load([ajd, of, sg]) | |
end | |
end | |
end | |
if __FILE__ == $0 | |
require 'test/unit' | |
class MarshalCompatTest < Test::Unit::TestCase | |
def setup | |
# Marshal.dump(Date.today) | |
@date_obj = Date.parse('2013-02-05') | |
@date_18 = "\004\bu:\tDate=\004\b[\bo:\rRational\a:\021@denominatori\a:\017@numeratori\003\021\366Ji\000i\003\031\025#" | |
@date_19 = "\x04\bU:\tDate[\vi\x00i\x03\t{%i\x00i\x00i\x00f\f2299161" | |
# Marshal.dump(DateTime.now) | |
@datetime_obj = DateTime.parse('2013-02-05T19:33:03.123456789-08:00') | |
@datetime_18 = "\004\bu:\rDateTimeV\004\b[\bo:\rRational\a:\021@denominatorl+\b\000\000\305\2051\032:\017@numeratorl+\n\a\241\2477u\035\277\325\003\000o;\000\a;\006i\b;\ai\372i\003\031\025#" | |
@datetime_19 = "\x04\bU:\rDateTime[\vi\x00i\x03\n{%i\x02\xEF1i\x04\x15\xCD[\ai\xFE\x80\x8Ff\f2299161" | |
end | |
def test_decode_date | |
assert_equal @date_obj, Marshal.load(@date_18) | |
assert_equal @date_obj, Marshal.load(@date_19) | |
end | |
def test_decode_date_time | |
assert_equal @datetime_obj, Marshal.load(@datetime_18) | |
assert_equal @datetime_obj, Marshal.load(@datetime_19) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment