diff options
| author | Joseph HALTER <[email protected]> | 2012-02-22 22:17:33 +0100 |
|---|---|---|
| committer | Sean Duckett <[email protected]> | 2012-03-07 14:45:01 -0600 |
| commit | 7c4d091a9aae49d25ef2e5313dbfcfc6e2f46790 (patch) | |
| tree | d0dc3691526ba66df16035da7d86025902d8ed4c | |
| parent | c5c938b5f8f2dadf0c3192c1a21e6995d691c555 (diff) | |
| download | caxlsx-7c4d091a9aae49d25ef2e5313dbfcfc6e2f46790.tar.gz caxlsx-7c4d091a9aae49d25ef2e5313dbfcfc6e2f46790.zip | |
Extract date and time to serial converting and put serious tests on it
| -rw-r--r-- | lib/axlsx/workbook/workbook.rb | 1 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cell.rb | 9 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/converter.rb | 21 | ||||
| -rw-r--r-- | test/workbook/worksheet/tc_converter.rb | 69 |
4 files changed, 93 insertions, 7 deletions
diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index 51f38b50..c19c3521 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- module Axlsx +require 'axlsx/workbook/worksheet/converter.rb' require 'axlsx/workbook/worksheet/cell.rb' require 'axlsx/workbook/worksheet/row.rb' require 'axlsx/workbook/worksheet/worksheet.rb' diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 160fc6c8..167dfc97 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -316,15 +316,10 @@ module Axlsx end elsif @type == :date # TODO: See if this is subject to the same restriction as Time below - epoc = Workbook.date1904 ? Date.new(1904) : Date.new(1900) - v = (@value-epoc).to_f + v = Converter.date_to_serial @value, Workbook.date1904 xml.c(:r => r, :s => style) { xml.v v } elsif @type == :time - # Using hardcoded offsets here as some operating systems will not except a 'negative' offset from the ruby epoc. - epoc1900 = -2209021200 #Time.local(1900, 1, 1) - epoc1904 = -2082877200 #Time.local(1904, 1, 1) - epoc = Workbook.date1904 ? epoc1904 : epoc1900 - v = ((@value.localtime.to_f - epoc) /60.0/60.0/24.0).to_f + v = Converter.time_to_serial @value, Workbook.date1904 xml.c(:r => r, :s => style) { xml.v v } elsif @type == :boolean xml.c(:r => r, :s => style, :t => :b) { xml.v value } diff --git a/lib/axlsx/workbook/worksheet/converter.rb b/lib/axlsx/workbook/worksheet/converter.rb new file mode 100644 index 00000000..8df08f34 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/converter.rb @@ -0,0 +1,21 @@ +# encoding: UTF-8 +require "date" + +module Axlsx + class Converter + def date_to_serial(date, date1904=false) + epoc = date1904 ? Date.new(1904) : Date.new(1899, 12, 30) + (date-epoc).to_f + end + + def time_to_serial(time, date1904=false) + # Using hardcoded offsets here as some operating systems will not except + # a 'negative' offset from the ruby epoc. + epoc1900 = -2209161600 # Time.utc(1899, 12, 30).to_i + epoc1904 = -2082844800 # Time.utc(1904, 1, 1).to_i + seconds_per_day = 86400 # 60*60*24 + epoc = date1904 ? epoc1904 : epoc1900 + (time.to_f - epoc)/seconds_per_day + end + end +end diff --git a/test/workbook/worksheet/tc_converter.rb b/test/workbook/worksheet/tc_converter.rb new file mode 100644 index 00000000..3919382a --- /dev/null +++ b/test/workbook/worksheet/tc_converter.rb @@ -0,0 +1,69 @@ +require 'test/unit' +require 'axlsx.rb' + +class TestConverter < Test::Unit::TestCase + def setup + @converter = Axlsx::Converter.new + @margin_of_error = 0.000_001 + end + + def test_date_to_serial_1900 + { # examples taken straight from the spec + "1893-08-05" => -2338.0, + "1900-01-01" => 2.0, + "1910-02-03" => 3687.0, + "2006-02-01" => 38749.0, + "9999-12-31" => 2958465.0, + }.each do |date_string, expected| + serial = @converter.date_to_serial Date.parse(date_string) + assert_equal serial, expected + end + end + + def test_date_to_serial_1904 + { # examples taken straight from the spec + "1893-08-05" => -3800.0, + "1904-01-01" => 0.0, + "1910-02-03" => 2225.0, + "2006-02-01" => 37287.0, + "9999-12-31" => 2957003.0, + }.each do |date_string, expected| + serial = @converter.date_to_serial Date.parse(date_string), true + assert_equal serial, expected + end + end + + def test_time_to_serial_1900 + { # examples taken straight from the spec + "1893-08-05T00:00:01Z" => -2337.999989, + "1899-12-28T18:00:00Z" => -1.25, + "1910-02-03T10:05:54Z" => 3687.4207639, + "1900-01-01T12:00:00Z" => 2.5, # wrongly indicated as 1.5 in the spec! + "9999-12-31T23:59:59Z" => 2958465.9999884, + }.each do |time_string, expected| + serial = @converter.time_to_serial Time.parse(time_string) + assert_in_delta serial, expected, @margin_of_error + end + end + + def test_time_to_serial_1904 + { # examples taken straight from the spec + "1893-08-05T00:00:01Z" => -3799.999989, + "1910-02-03T10:05:54Z" => 2225.4207639, + "1904-01-01T12:00:00Z" => 0.5000000, + "9999-12-31T23:59:59Z" => 2957003.9999884, + }.each do |time_string, expected| + serial = @converter.time_to_serial Time.parse(time_string), true + assert_in_delta serial, expected, @margin_of_error + end + end + + def test_timezone + utc = Time.utc 2012 # January 1st, 2012 at 0:00 UTC + local = Time.new 2012, 1, 1, 1, 0, 0, 3600 # January 1st, 2012 at 1:00 GMT+1 + assert_equal local, utc + assert_equal @converter.time_to_serial(local), @converter.time_to_serial(utc) + assert_equal @converter.time_to_serial(local, true), @converter.time_to_serial(utc, true) + end + +end |
