renamed the API methods, updated the README
This commit is contained in:
45
README.md
45
README.md
@@ -1,11 +1,27 @@
|
|||||||
ezic
|
ezic
|
||||||
====
|
====
|
||||||
ezic is a set of erlang utilities for the Olsen timezone database files.
|
ezic is a set of erlang utilities for the Olsen timezone database files. See the [tz database](http://www.twinsun.com/tz/tz-link.htm) page for more information.
|
||||||
|
|
||||||
see the [tz database](http://www.twinsun.com/tz/tz-link.htm) page for more information.
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
* `ezic:localtime(TimeZone) -> datetime()`
|
||||||
|
* `ezic:utc_to_time(universal_datetime(), TimeZone) -> local_datetime()`
|
||||||
|
* `ezic:utc_from_time(local_datetime(), TimeZone) -> universal_datetime()`
|
||||||
|
* `ezic:zone_convert(from_datetime(), TimeZoneFrom, TimeZoneTo) -> to_datetime()`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Admin API
|
||||||
|
-------
|
||||||
|
|
||||||
|
* `ezic:load("/path/to/tzdata") -> ok`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Setup
|
||||||
-----
|
-----
|
||||||
|
|
||||||
# download the timezone data files
|
# download the timezone data files
|
||||||
@@ -22,25 +38,26 @@ Usage
|
|||||||
2> ezic:localtime("Australia/Adelaide").
|
2> ezic:localtime("Australia/Adelaide").
|
||||||
|
|
||||||
|
|
||||||
API
|
|
||||||
---
|
|
||||||
|
|
||||||
* `ezic:load(Folder)`
|
|
||||||
* `ezic:localtime(TimeZone) -> datetime()`
|
|
||||||
* `ezic:time(datetime(), TimeZone) -> datetime()`
|
|
||||||
* `ezic:time2time(datetime(), TimeZoneFrom, TimeZoneTo) -> datetime()`
|
|
||||||
|
|
||||||
|
|
||||||
Purpose
|
Purpose
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The [recommended way](http://www.erlang.org/pipermail/erlang-questions/2006-December/024291.html) of handling timezones in erlang involves setting the system environment variable `TZ` to the desired timezone, then calling erlang time functions. This technique is probably sufficient for many purposes, but it has a few key issues:
|
The [recommended way](http://www.erlang.org/pipermail/erlang-questions/2006-December/024291.html) of handling timezones in erlang involves setting the system environment variable `TZ` to the desired timezone, then calling erlang time functions. This technique has a few key issues:
|
||||||
|
|
||||||
* it only works on *nix systems,
|
* it only works on *nix systems,
|
||||||
* it depends on your system's timezone data (preventing customization), and
|
* it depends on your system's timezone data (preventing custom timezone hackery), and
|
||||||
* you can create race conditions if you aren't careful
|
* you can create race conditions if you aren't careful
|
||||||
|
|
||||||
A pure erlang solution avoids all of these pitfalls, hence this project.
|
A self-containted erlang solution would avoid these pitfalls, but to be fair, it introduces a few others:
|
||||||
|
|
||||||
|
* you (the admin) are responsible for updating the timezone database yourself
|
||||||
|
* ezic has not yet been battle tested
|
||||||
|
|
||||||
|
I think both of these issues will disappear over time, so I opted to write ezic.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
83
src/ezic.erl
83
src/ezic.erl
@@ -1,7 +1,8 @@
|
|||||||
-module(ezic).
|
-module(ezic).
|
||||||
-include("include/ezic.hrl").
|
-include("include/ezic.hrl").
|
||||||
|
|
||||||
-export([localtime/1, time2time/3]).
|
-export([localtime/1, utc_to_local/2, utc_from_local/2, zone_convert/3]).
|
||||||
|
|
||||||
-export([load/1, dev_start/0, test/0]).
|
-export([load/1, dev_start/0, test/0]).
|
||||||
|
|
||||||
|
|
||||||
@@ -10,36 +11,37 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% API
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
localtime(TzName) ->
|
localtime(TzName) ->
|
||||||
time(erlang:universaltime(), TzName).
|
utc_to_local(erlang:universaltime(), TzName).
|
||||||
|
|
||||||
|
|
||||||
time(Datetime, TzName) ->
|
utc_to_local(Datetime, TzName) ->
|
||||||
|
{ok, Zone, Rule}= current(Datetime, TzName),
|
||||||
|
SecDiff= offset(Zone, Rule),
|
||||||
|
date_add(Datetime, SecDiff).
|
||||||
|
|
||||||
|
|
||||||
Zones= ezic_db:zones(TzName),
|
utc_from_local(Datetime, TzName) ->
|
||||||
% ?debug("All Zones: ~p", [Zones]),
|
{ok, Zone, Rule}= current(Datetime, TzName),
|
||||||
CZone= ezic_zone:current(Datetime, Zones),
|
SecDiff= offset(Zone, Rule),
|
||||||
% ?debug("Current Zone: ~p", [CZone]),
|
date_subtract(Datetime, SecDiff).
|
||||||
|
|
||||||
RuleName= CZone#zone.rule,
|
|
||||||
Rules= ezic_db:rules(RuleName),
|
|
||||||
% ?debug("All Rules: ~p", [Rules]),
|
|
||||||
CRule= ezic_rule:current(Datetime, Rules),
|
|
||||||
% ?debug("Current Rule: ~p", [CRule]),
|
|
||||||
|
|
||||||
OffsetSec= ezic_zone:offset_sec(CZone),
|
|
||||||
DSTSec= ezic_rule:dst_sec(CRule),
|
|
||||||
|
|
||||||
SecDiff= OffsetSec + DSTSec,
|
|
||||||
?gs2dt(?dt2gs(Datetime) + SecDiff).
|
|
||||||
|
|
||||||
|
|
||||||
|
zone_convert(Datetime, FromTimeZone, ToTimeZone) ->
|
||||||
time2time(_DateTime, _FromTimeZone, _ToTimeZone) ->
|
UTC= utc_from_local(Datetime, FromTimeZone),
|
||||||
void.
|
utc_to_local(UTC, ToTimeZone).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% DEV API
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -57,3 +59,40 @@ test() ->
|
|||||||
io:format("~s: ~p~n", [TZ, localtime(TZ)])
|
io:format("~s: ~p~n", [TZ, localtime(TZ)])
|
||||||
end,
|
end,
|
||||||
["Asia/Tokyo", "America/New_York", "America/Los_Angeles", "America/Jamaica", "Australia/Adelaide"]).
|
["Asia/Tokyo", "America/New_York", "America/Los_Angeles", "America/Jamaica", "Australia/Adelaide"]).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% PRIVATE
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
|
current(Datetime, TzName) ->
|
||||||
|
Zones= ezic_db:zones(TzName),
|
||||||
|
% ?debug("All Zones: ~p", [Zones]),
|
||||||
|
CZone= ezic_zone:current(Datetime, Zones),
|
||||||
|
% ?debug("Current Zone: ~p", [CZone]),
|
||||||
|
|
||||||
|
RuleName= CZone#zone.rule,
|
||||||
|
Rules= ezic_db:rules(RuleName),
|
||||||
|
% ?debug("All Rules: ~p", [Rules]),
|
||||||
|
CRule= ezic_rule:current(Datetime, Rules),
|
||||||
|
% ?debug("Current Rule: ~p", [CRule]),
|
||||||
|
{ok, CZone, CRule}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
offset(Zone, Rule) ->
|
||||||
|
OffsetSec= ezic_zone:offset_sec(Zone),
|
||||||
|
DSTSec= ezic_rule:dst_sec(Rule),
|
||||||
|
OffsetSec + DSTSec.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
date_add(Datetime, SecDiff) ->
|
||||||
|
?gs2dt(?dt2gs(Datetime) + SecDiff).
|
||||||
|
|
||||||
|
date_subtract(Datetime, SecDiff) ->
|
||||||
|
?gs2dt(?dt2gs(Datetime) - SecDiff).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user