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

Fixing datetime convert code #117

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
7 changes: 0 additions & 7 deletions config/config.exs

This file was deleted.

1 change: 0 additions & 1 deletion lib/xlsxir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ defmodule Xlsxir do
use Application

def start(_type, _args) do

children = [
%{id: Xlsxir.StateManager, start: {Xlsxir.StateManager, :start_link, []}, type: :worker}
]
Expand Down
46 changes: 28 additions & 18 deletions lib/xlsxir/convert_date.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,27 @@ defmodule Xlsxir.ConvertDate do
{1975, 4, 30}
"""
def from_serial(serial) do
f_serial = serial
|> convert_char_number
|> is_float
|> case do
false -> List.to_integer(serial)
true -> serial
|> List.to_float()
|> Float.floor
|> round
end
f_serial =
serial
|> convert_char_number
|> is_float
|> case do
false ->
List.to_integer(serial)

true ->
serial
|> List.to_float()
|> Float.floor()
|> round
end

# Convert to gregorian days and get date from that
gregorian = f_serial - 2 + # adjust two days for first and last day since base year
date_to_days({1900, 1, 1}) # Add days in base year 1900
# adjust two days for first and last day since base year
# Add days in base year 1900
gregorian =
f_serial - 2 +
date_to_days({1900, 1, 1})

gregorian
|> days_to_date
Expand All @@ -50,11 +57,14 @@ defmodule Xlsxir.ConvertDate do
str
|> String.match?(~r/[.eE]/)
|> case do
false -> List.to_integer(number)
true -> case Float.parse(str) do
{f, _} -> f
_ -> raise "Invalid Float"
end
end
false ->
List.to_integer(number)

true ->
case Float.parse(str) do
{f, _} -> f
_ -> raise "Invalid Float"
end
end
end
end
21 changes: 14 additions & 7 deletions lib/xlsxir/convert_datetime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,29 @@ defmodule Xlsxir.ConvertDateTime do
~N[2012-12-18 14:26:00]
"""
def from_charlist('0'), do: {0, 0, 0}

def from_charlist(charlist) do
charlist
|> List.to_float
|> List.to_float()
|> from_float
end

def from_float(n) when is_float(n) do
n = if n > 59, do: n - 1, else: n # Lotus bug
# Lotus bug
n = if n > 59, do: n - 1, else: n
convert_from_serial(n)
end

defp convert_from_serial(time) when is_float(time) and time >= 0 and time < 1.0 do
{hours, min_fraction} = split_float(time * 24)
{minutes, sec_fraction} = split_float(min_fraction * 60)
{seconds, _} = split_float(sec_fraction * 60)
total_seconds = (time * 86400) |> Float.round(2) |> trunc()

hours = div(total_seconds, 60 * 60)
minutes = div(total_seconds - hours * 60 * 60, 60)
seconds = total_seconds - hours * 60 * 60 - minutes * 60

{hours, minutes, seconds}
end

defp convert_from_serial(n) when is_float(n) do
{whole_days, fractional_day} = split_float(n)
{hours, minutes, seconds} = convert_from_serial(fractional_day)
Expand All @@ -48,9 +53,11 @@ defmodule Xlsxir.ConvertDateTime do
end

defp split_float(f) do
whole = f
|> Float.floor
whole =
f
|> Float.floor()
|> round

{whole, f - whole}
end
end
25 changes: 15 additions & 10 deletions lib/xlsxir/parse_string.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,27 @@ defmodule Xlsxir.ParseString do
%__MODULE__{tid: GenServer.call(Xlsxir.StateManager, :new_table)}
end

def sax_event_handler({:startElement,_,'si',_,_}, %__MODULE__{tid: tid, index: index}), do: %__MODULE__{tid: tid, index: index}
def sax_event_handler({:startElement, _, 'si', _, _}, %__MODULE__{tid: tid, index: index}),
do: %__MODULE__{tid: tid, index: index}

def sax_event_handler({:startElement,_,'family',_,_}, state) do
def sax_event_handler({:startElement, _, 'family', _, _}, state) do
%{state | family: true}
end

def sax_event_handler({:characters, value},
%__MODULE__{family_string: fam_str} = state) do
value = value |> to_string
%{state | family_string: fam_str <> value}
def sax_event_handler(
{:characters, value},
%__MODULE__{family_string: fam_str} = state
) do
value = value |> to_string
%{state | family_string: fam_str <> value}
end

def sax_event_handler({:endElement,_,'si',_},
%__MODULE__{family_string: fam_str, tid: tid, index: index} = state) do
:ets.insert(tid, {index, fam_str})
%{state | index: index + 1}
def sax_event_handler(
{:endElement, _, 'si', _},
%__MODULE__{family_string: fam_str, tid: tid, index: index} = state
) do
:ets.insert(tid, {index, fam_str})
%{state | index: index + 1}
end

def sax_event_handler(_, state), do: state
Expand Down
88 changes: 50 additions & 38 deletions lib/xlsxir/unzip.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
defmodule Xlsxir.Unzip do

alias Xlsxir.XmlFile

@moduledoc """
Expand Down Expand Up @@ -39,7 +38,7 @@ defmodule Xlsxir.Unzip do
path = String.to_charlist(path)

case valid_extract_request?(path, index) do
:ok -> {:ok, path}
:ok -> {:ok, path}
{:error, reason} -> {:error, reason}
end
end
Expand Down Expand Up @@ -68,47 +67,57 @@ defmodule Xlsxir.Unzip do

def validate_path_all_indexes(path) do
path = String.to_charlist(path)

case :zip.list_dir(path) do
{:ok, file_list} ->
indexes = file_list
|> Enum.filter(fn (file) ->
case file do
{:zip_file, filename, _, _, _, _} ->
filename |> to_string |> String.starts_with?("xl/worksheets/sheet")
_ ->
nil
end
end)
|> Enum.map(fn ({:zip_file, filename, _, _, _, _}) ->
index = filename
|> to_string
|> String.replace_prefix("xl/worksheets/sheet", "")
|> String.replace_suffix(".xml", "")
|> String.to_integer
index - 1
end)
|> Enum.sort
{:ok, file_list} ->
indexes =
file_list
|> Enum.filter(fn file ->
case file do
{:zip_file, filename, _, _, _, _} ->
filename |> to_string |> String.starts_with?("xl/worksheets/sheet")

_ ->
nil
end
end)
|> Enum.map(fn {:zip_file, filename, _, _, _, _} ->
index =
filename
|> to_string
|> String.replace_prefix("xl/worksheets/sheet", "")
|> String.replace_suffix(".xml", "")
|> String.to_integer()

index - 1
end)
|> Enum.sort()

{:ok, indexes}
{:error, _reason} -> {:error, @filetype_error}

{:error, _reason} ->
{:error, @filetype_error}
end
end

defp valid_extract_request?(path, index) do
case :zip.list_dir(path) do
{:ok, file_list} -> search_file_list(file_list, index)
{:ok, file_list} -> search_file_list(file_list, index)
{:error, _reason} -> {:error, @filetype_error}
end
end

defp search_file_list(file_list, index) do
sheet = 'xl/worksheets/sheet#{index + 1}.xml'
results = file_list
|> Enum.map(fn file ->
case file do
{:zip_file, ^sheet, _, _, _, _} -> :ok
_ -> nil
end
end)
sheet = 'xl/worksheets/sheet#{index + 1}.xml'

results =
file_list
|> Enum.map(fn file ->
case file do
{:zip_file, ^sheet, _, _, _, _} -> :ok
_ -> nil
end
end)

if Enum.member?(results, :ok) do
:ok
Expand Down Expand Up @@ -144,14 +153,17 @@ defmodule Xlsxir.Unzip do
|> to_charlist
|> extract_from_zip(file_list, to)
|> case do
{:error, reason} -> {:error, reason}
{:ok, []} -> {:error, @xml_not_found_error}
{:ok, files_list} -> {:ok, build_xml_files(files_list)}
end
{:error, reason} -> {:error, reason}
{:ok, []} -> {:error, @xml_not_found_error}
{:ok, files_list} -> {:ok, build_xml_files(files_list)}
end
end

defp extract_from_zip(path, file_list, :memory), do: :zip.extract(path, [{:file_list, file_list}, :memory])
defp extract_from_zip(path, file_list, {:file, dest_path}), do: :zip.extract(path, [{:file_list, file_list}, {:cwd, dest_path}])
defp extract_from_zip(path, file_list, :memory),
do: :zip.extract(path, [{:file_list, file_list}, :memory])

defp extract_from_zip(path, file_list, {:file, dest_path}),
do: :zip.extract(path, [{:file_list, file_list}, {:cwd, dest_path}])

defp build_xml_files(files_list) do
files_list
Expand All @@ -165,6 +177,6 @@ defmodule Xlsxir.Unzip do

# When extracting to temp file
defp build_xml_file(file_path) do
%XmlFile{name: Path.basename(file_path), path: to_string(file_path)}
%XmlFile{name: Path.basename(file_path), path: to_string(file_path)}
end
end
4 changes: 2 additions & 2 deletions lib/xlsxir/xlsx_file.ex
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ defmodule Xlsxir.XlsxFile do

defp fill_empty_cells_at_end(tid, end_column, index) when is_integer(index) do
build_and_replace(tid, end_column, index)
nex_index= :ets.next(tid, index)
nex_index = :ets.next(tid, index)
fill_empty_cells_at_end(tid, end_column, nex_index)
end

Expand All @@ -133,7 +133,7 @@ defmodule Xlsxir.XlsxFile do
empty_cells = Xlsxir.ParseWorksheet.fill_empty_cells(from, to, index, [])
new_cells = cells ++ empty_cells

true = :ets.insert(tid, {index, new_cells})
true = :ets.insert(tid, {index, new_cells})
end

@doc """
Expand Down
2 changes: 1 addition & 1 deletion lib/xlsxir/xml_file.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Xlsxir.XmlFile do
(located in the `path` field)
"""

defstruct [name: nil, path: nil, content: nil]
defstruct name: nil, path: nil, content: nil

@doc """
Open an XmlFile
Expand Down
31 changes: 15 additions & 16 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ defmodule Xlsxir.Mixfile do

def project do
[
app: :xlsxir,
version: "1.6.4",
name: "Xlsxir",
source_url: "https://github.com/jsonkenl/xlsxir",
elixir: "~> 1.4",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
description: description(),
package: package(),
deps: deps(),
docs: [main: "overview", extras: ["CHANGELOG.md", "NUMBER_STYLES.md", "OVERVIEW.md"]]
app: :xlsxir,
version: "1.6.4",
name: "Xlsxir",
source_url: "https://github.com/jsonkenl/xlsxir",
elixir: "~> 1.4",
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
description: description(),
package: package(),
deps: deps(),
docs: [main: "overview", extras: ["CHANGELOG.md", "NUMBER_STYLES.md", "OVERVIEW.md"]]
]
end

Expand All @@ -27,7 +27,7 @@ defmodule Xlsxir.Mixfile do
defp deps do
[
{:ex_doc, "~> 0.19", only: :dev, runtime: false},
#{:earmark, github: "pragdave/earmark", override: true, only: :dev},
# {:earmark, github: "pragdave/earmark", override: true, only: :dev},
{:erlsom, "~> 1.5"}
]
end
Expand All @@ -43,10 +43,9 @@ defmodule Xlsxir.Mixfile do
maintainers: ["Jason Kennell"],
licenses: ["MIT License"],
links: %{
"Github" => "https://github.com/jsonkenl/xlsxir",
"Change Log" => "https://hexdocs.pm/xlsxir/changelog.html"
}
"Github" => "https://github.com/jsonkenl/xlsxir",
"Change Log" => "https://hexdocs.pm/xlsxir/changelog.html"
}
]
end

end