aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/doc/src/calendar.xml32
-rw-r--r--lib/stdlib/doc/src/dict.xml8
-rw-r--r--lib/stdlib/doc/src/orddict.xml8
-rw-r--r--lib/stdlib/src/calendar.erl53
-rw-r--r--lib/stdlib/src/escript.erl18
-rw-r--r--lib/stdlib/test/calendar_SUITE.erl22
6 files changed, 126 insertions, 15 deletions
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index 36f0c03162..f90d8308b6 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -63,6 +63,14 @@
given as local time, they must be converted to universal time, in
order to get the correct value of the elapsed time between epochs.
Use of the function <c>time_difference/2</c> is discouraged.</p>
+ <p>There exists different definitions for the week of the year.
+ The calendar module contains a week of the year implementation
+ which conforms to the ISO 8601 standard. Since the week number for
+ a given date can fall on the previous, the current or on the next
+ year it is important to provide the information which year is it
+ together with the week number. The function <c>iso_week_number/0</c>
+ and <c>iso_week_number/1</c> returns a tuple of the year and the
+ week number.</p>
</description>
<section>
@@ -154,6 +162,30 @@ time() = {Hour, Minute, Second}
</desc>
</func>
<func>
+ <name>iso_week_number() -> IsoWeekNumber</name>
+ <fsummary>Compute the iso week number for the actual date</fsummary>
+ <type>
+ <v>IsoWeekNumber = {int(), int()}</v>
+ </type>
+ <desc>
+ <p>This function returns the tuple {Year, WeekNum} representing
+ the iso week number for the actual date. For determining the
+ actual date, the function <c>local_time/0</c> is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>iso_week_number(Date) -> IsoWeekNumber</name>
+ <fsummary>Compute the iso week number for the given date</fsummary>
+ <type>
+ <v>Date = date()</v>
+ <v>IsoWeekNumber = {int(), int()}</v>
+ </type>
+ <desc>
+ <p>This function returns the tuple {Year, WeekNum} representing
+ the iso week number for the given date.</p>
+ </desc>
+ </func>
+ <func>
<name>last_day_of_the_month(Year, Month) -> int()</name>
<fsummary>Compute the number of days in a month</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml
index ebcd2eed09..1695e9d14f 100644
--- a/lib/stdlib/doc/src/dict.xml
+++ b/lib/stdlib/doc/src/dict.xml
@@ -165,8 +165,8 @@ dictionary()
<v>Dict = dictionary()</v>
</type>
<desc>
- <p>This function converts the key/value list <c>List</c> to a
- dictionary.</p>
+ <p>This function converts the <c>Key</c> - <c>Value</c> list
+ <c>List</c> to a dictionary.</p>
</desc>
</func>
<func>
@@ -270,7 +270,7 @@ merge(Fun, D1, D2) ->
<v>Dict1 = Dict2 = dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. An exception is generated if
<c>Key</c> is not present in the dictionary.</p>
</desc>
@@ -285,7 +285,7 @@ merge(Fun, D1, D2) ->
<v>Dict1 = Dict2 = dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. If <c>Key</c> is not present
in the dictionary then <c>Initial</c> will be stored as
the first value. For example <c>append/3</c> could be defined
diff --git a/lib/stdlib/doc/src/orddict.xml b/lib/stdlib/doc/src/orddict.xml
index 08c808f822..9d036f0725 100644
--- a/lib/stdlib/doc/src/orddict.xml
+++ b/lib/stdlib/doc/src/orddict.xml
@@ -172,8 +172,8 @@ ordered_dictionary()
<v>Orddict = ordered_dictionary()</v>
</type>
<desc>
- <p>This function converts the key/value list <c>List</c> to a
- dictionary.</p>
+ <p>This function converts the <c>Key</c> - <c>Value</c> list
+ <c>List</c> to a dictionary.</p>
</desc>
</func>
<func>
@@ -277,7 +277,7 @@ merge(Fun, D1, D2) ->
<v>Orddict1 = Orddict2 = ordered_dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. An exception is generated if
<c>Key</c> is not present in the dictionary.</p>
</desc>
@@ -292,7 +292,7 @@ merge(Fun, D1, D2) ->
<v>Orddict1 = Orddict2 = ordered_dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. If <c>Key</c> is not present
in the dictionary then <c>Initial</c> will be stored as
the first value. For example <c>append/3</c> could be defined
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index ddc0666f77..57b7c28dee 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -28,6 +28,8 @@
gregorian_days_to_date/1,
gregorian_seconds_to_datetime/1,
is_leap_year/1,
+ iso_week_number/0,
+ iso_week_number/1,
last_day_of_the_month/2,
local_time/0,
local_time_to_universal_time/1,
@@ -70,6 +72,7 @@
-type second() :: 0..59.
-type daynum() :: 1..7.
-type ldom() :: 28 | 29 | 30 | 31. % last day of month
+-type weeknum() :: 1..53.
-type t_now() :: {non_neg_integer(),non_neg_integer(),non_neg_integer()}.
@@ -77,6 +80,7 @@
-type t_time() :: {hour(),minute(),second()}.
-type t_datetime() :: {t_date(),t_time()}.
-type t_datetime1970() :: {{year1970(),month(),day()},t_time()}.
+-type t_yearweeknum() :: {year(),weeknum()}.
%%----------------------------------------------------------------------
@@ -172,6 +176,42 @@ is_leap_year1(Year) when Year rem 400 =:= 0 ->
is_leap_year1(_) -> false.
+%%
+%% Calculates the iso week number for the current date.
+%%
+-spec iso_week_number() -> t_yearweeknum().
+iso_week_number() ->
+ {Date, _} = local_time(),
+ iso_week_number(Date).
+
+
+%%
+%% Calculates the iso week number for the given date.
+%%
+-spec iso_week_number(t_date()) -> t_yearweeknum().
+iso_week_number({Year, Month, Day}) ->
+ D = date_to_gregorian_days({Year, Month, Day}),
+ W01_1_Year = gregorian_days_of_iso_w01_1(Year),
+ W01_1_NextYear = gregorian_days_of_iso_w01_1(Year + 1),
+ if W01_1_Year =< D andalso D < W01_1_NextYear ->
+ % Current Year Week 01..52(,53)
+ {Year, (D - W01_1_Year) div 7 + 1};
+ D < W01_1_Year ->
+ % Previous Year 52 or 53
+ PWN = case day_of_the_week(Year - 1, 1, 1) of
+ 4 -> 53;
+ _ -> case day_of_the_week(Year - 1, 12, 31) of
+ 4 -> 53;
+ _ -> 52
+ end
+ end,
+ {Year - 1, PWN};
+ W01_1_NextYear =< D ->
+ % Next Year, Week 01
+ {Year + 1, 1}
+ end.
+
+
%% last_day_of_the_month(Year, Month)
%%
%% Returns the number of days in a month.
@@ -377,6 +417,19 @@ dty(Y, D1, D2) when D1 < D2 ->
dty(Y, _D1, D2) ->
{Y, D2}.
+%%
+%% The Gregorian days of the iso week 01 day 1 for a given year.
+%%
+-spec gregorian_days_of_iso_w01_1(year()) -> non_neg_integer().
+gregorian_days_of_iso_w01_1(Year) ->
+ D0101 = date_to_gregorian_days(Year, 1, 1),
+ DOW = day_of_the_week(Year, 1, 1),
+ if DOW =< 4 ->
+ D0101 - DOW + 1;
+ true ->
+ D0101 + 7 - DOW + 1
+ end.
+
%% year_day_to_date(Year, DayOfYear) = {Month, DayOfMonth}
%%
%% Note: 1 is the first day of the month.
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 7cb02afb11..0d2d23180a 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -31,7 +31,7 @@
%%-----------------------------------------------------------------------
--type mode() :: 'compile' | 'debug' | 'interpret' | 'run'.
+-type mode() :: 'native' | 'compile' | 'debug' | 'interpret' | 'run'.
-type source() :: 'archive' | 'beam' | 'text'.
-record(state, {file :: file:filename(),
@@ -304,7 +304,11 @@ parse_and_run(File, Args, Options) ->
false ->
case lists:member("i", Options) of
true -> interpret;
- false -> Mode
+ false ->
+ case lists:member("n", Options) of
+ true -> native;
+ false -> Mode
+ end
end
end
end,
@@ -321,6 +325,14 @@ parse_and_run(File, Args, Options) ->
_Other ->
fatal("There were compilation errors.")
end;
+ native ->
+ case compile:forms(FormsOrBin, [report,native]) of
+ {ok, Module, BeamBin} ->
+ {module, Module} = code:load_binary(Module, File, BeamBin),
+ run(Module, Args);
+ _Other ->
+ fatal("There were compilation errors.")
+ end;
debug ->
case compile:forms(FormsOrBin, [report, debug_info]) of
{ok,Module,BeamBin} ->
@@ -664,7 +676,7 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
{attribute,Ln,mode,NewMode} ->
S2 = S#state{mode = NewMode},
if
- NewMode =:= compile; NewMode =:= interpret; NewMode =:= debug ->
+ NewMode =:= compile; NewMode =:= interpret; NewMode =:= debug; NewMode =:= native ->
epp_parse_file(Epp, S2, [Form | Forms]);
true ->
Args = lists:flatten(io_lib:format("illegal mode attribute: ~p", [NewMode])),
diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index 81b0299118..8192d035ca 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.erl
@@ -28,7 +28,8 @@
day_of_the_week_calibrate/1,
leap_years/1,
last_day_of_the_month/1,
- local_time_to_universal_time_dst/1]).
+ local_time_to_universal_time_dst/1,
+ iso_week_number/1]).
-define(START_YEAR, 1947).
-define(END_YEAR, 2012).
@@ -38,7 +39,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[gregorian_days, gregorian_seconds, day_of_the_week,
day_of_the_week_calibrate, leap_years,
- last_day_of_the_month, local_time_to_universal_time_dst].
+ last_day_of_the_month, local_time_to_universal_time_dst, iso_week_number].
groups() ->
[].
@@ -55,7 +56,6 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
-
gregorian_days(doc) ->
"Tests that date_to_gregorian_days and gregorian_days_to_date "
"are each others inverses from ?START_YEAR-01-01 up to ?END_YEAR-01-01. "
@@ -170,6 +170,15 @@ local_time_to_universal_time_dst_x(Config) when is_list(Config) ->
{comment,"Bug in mktime() in this OS"}
end.
+iso_week_number(doc) ->
+ "Test the iso week number calculation for all three possibilities."
+ " When the date falls on the last week of the previous year,"
+ " when the date falls on a week within the given year and finally,"
+ " when the date falls on the first week of the next year.";
+iso_week_number(suite) ->
+ [];
+iso_week_number(Config) when is_list(Config) ->
+ ?line check_iso_week_number().
%%
%% LOCAL FUNCTIONS
@@ -259,7 +268,12 @@ check_last_day_of_the_month({SYr, SMon}, {EYr, EMon}) when SYr < EYr ->
check_last_day_of_the_month(_, _) ->
ok.
-
+%% check_iso_week_number
+%%
+check_iso_week_number() ->
+ ?line {2004, 53} = calendar:iso_week_number({2005, 1, 1}),
+ ?line {2007, 1} = calendar:iso_week_number({2007, 1, 1}),
+ ?line {2009, 1} = calendar:iso_week_number({2008, 12, 29}).