summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJoseph HALTER <[email protected]>2012-02-22 22:17:33 +0100
committerSean Duckett <[email protected]>2012-03-07 14:45:01 -0600
commit7c4d091a9aae49d25ef2e5313dbfcfc6e2f46790 (patch)
treed0dc3691526ba66df16035da7d86025902d8ed4c
parentc5c938b5f8f2dadf0c3192c1a21e6995d691c555 (diff)
downloadcaxlsx-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.rb1
-rw-r--r--lib/axlsx/workbook/worksheet/cell.rb9
-rw-r--r--lib/axlsx/workbook/worksheet/converter.rb21
-rw-r--r--test/workbook/worksheet/tc_converter.rb69
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