|
@@ -74,7 +74,7 @@ format(DateTime, FormatString) ->
|
|
|
%% replacing atom with a stub function (it's easier to do it this way)
|
|
|
format(FormatString, TransFun, Locale) when is_binary(FormatString) ->
|
|
|
format(binary_to_list(FormatString), TransFun, Locale);
|
|
|
-format(FormatString, none, Locale) ->
|
|
|
+format(FormatString, none, _Locale) ->
|
|
|
format(FormatString, fun stub_tran/2, <<>>);
|
|
|
format(FormatString, TransFun, Locale) ->
|
|
|
{Date, Time} = erlang:localtime(),
|
|
@@ -82,12 +82,12 @@ format(FormatString, TransFun, Locale) ->
|
|
|
|
|
|
format(DateTime, FormatString, TransFun, Locale) when is_binary(FormatString) ->
|
|
|
format(DateTime, binary_to_list(FormatString), TransFun, Locale);
|
|
|
-format(DateTime, FormatString, none, Locale) ->
|
|
|
+format(DateTime, FormatString, none, _Locale) ->
|
|
|
format(DateTime, FormatString, fun stub_tran/2, <<>>);
|
|
|
format({{_,_,_} = Date,{_,_,_} = Time}, FormatString, TransFun, Locale) ->
|
|
|
replace_tags(Date, Time, FormatString, TransFun, Locale );
|
|
|
|
|
|
-format({_,_,_} = Date, FormatString, none, Locale) ->
|
|
|
+format({_,_,_} = Date, FormatString, none, _Locale) ->
|
|
|
replace_tags(Date, {0,0,0}, FormatString, fun stub_tran/2, <<>>);
|
|
|
format({_,_,_} = Date, FormatString, TransFun, Locale) ->
|
|
|
replace_tags(Date, {0,0,0}, FormatString, TransFun, Locale);
|
|
@@ -100,8 +100,14 @@ replace_tags(Date, Time, Input, TransFun, Locale) ->
|
|
|
replace_tags(_Date, _Time, [], Out, _State, _TransFun, _Locale) ->
|
|
|
lists:reverse(Out);
|
|
|
replace_tags(Date, Time, [C|Rest], Out, noslash, TransFun, Locale) when ?TAG_SUPPORTED(C) ->
|
|
|
- replace_tags(Date, Time, Rest,
|
|
|
- lists:reverse(tag_to_value(C, Date, Time, TransFun, Locale)) ++ Out, noslash, TransFun, Locale);
|
|
|
+ case tag_to_value(C, Date, Time, TransFun, Locale) of
|
|
|
+ V when is_binary(V) -> replace_tags(Date, Time, Rest,
|
|
|
+ [V] ++ Out, noslash,
|
|
|
+ TransFun, Locale);
|
|
|
+ V when is_list(V) -> replace_tags(Date, Time, Rest,
|
|
|
+ lists:reverse(V) ++ Out,
|
|
|
+ noslash, TransFun, Locale)
|
|
|
+ end;
|
|
|
replace_tags(Date, Time, [$\\|Rest], Out, noslash, TransFun, Locale) ->
|
|
|
replace_tags(Date, Time, Rest, Out, slash, TransFun, Locale);
|
|
|
replace_tags(Date, Time, [C|Rest], Out, slash, TransFun, Locale) ->
|
|
@@ -115,15 +121,19 @@ replace_tags(Date, Time, [C|Rest], Out, _State, TransFun, Locale) ->
|
|
|
%%-----------------------------------------------------------
|
|
|
|
|
|
%% 'a.m.' or 'p.m.'
|
|
|
-tag_to_value($a, _, {H, _, _}, TransFun, Locale) when H > 11 -> "p.m.";
|
|
|
-tag_to_value($a, _, _, TransFun, Locale) -> "a.m.";
|
|
|
+tag_to_value($a, _, {H, _, _}, TransFun, Locale) when H > 11 ->
|
|
|
+ erlang:apply(TransFun, ["p.m.", Locale]);
|
|
|
+tag_to_value($a, _, _, TransFun, Locale) ->
|
|
|
+ erlang: apply(TransFun, ["a.m.", Locale]);
|
|
|
|
|
|
%% 'AM' or 'PM'
|
|
|
-tag_to_value($A, _, {H, _, _}, TransFun, Locale) when H > 11 -> "PM";
|
|
|
-tag_to_value($A, _, _, TransFun, Locale) -> "AM";
|
|
|
+tag_to_value($A, _, {H, _, _}, TransFun, Locale) when H > 11 ->
|
|
|
+ erlang:apply(TransFun, ["PM", Locale]);
|
|
|
+tag_to_value($A, _, _, TransFun, Locale) ->
|
|
|
+ erlang:apply(TransFun, ["AM", Locale]);
|
|
|
|
|
|
%% Swatch Internet time
|
|
|
-tag_to_value($B, _, _, TransFun, Locale) ->
|
|
|
+tag_to_value($B, _, _, _TransFun, _Locale) ->
|
|
|
""; %% NotImplementedError
|
|
|
|
|
|
%% ISO 8601 Format.
|
|
@@ -152,37 +162,39 @@ tag_to_value($f, Date, Time, TransFun, Locale) ->
|
|
|
++ ":" ++ tag_to_value($i, Date, Time, TransFun, Locale);
|
|
|
|
|
|
%% Hour, 12-hour format without leading zeros; i.e. '1' to '12'
|
|
|
-tag_to_value($g, _, {H,_,_}, TransFun, Locale) ->
|
|
|
+tag_to_value($g, _, {H,_,_}, _TransFun, _Locale) ->
|
|
|
integer_to_list(hour_24to12(H));
|
|
|
|
|
|
%% Hour, 24-hour format without leading zeros; i.e. '0' to '23'
|
|
|
-tag_to_value($G, _, {H,_,_}, TransFun, Locale) ->
|
|
|
+tag_to_value($G, _, {H,_,_}, _TransFun, _Locale) ->
|
|
|
integer_to_list(H);
|
|
|
|
|
|
%% Hour, 12-hour format; i.e. '01' to '12'
|
|
|
-tag_to_value($h, _, {H,_,_}, TransFun, Locale) ->
|
|
|
+tag_to_value($h, _, {H,_,_}, _TransFun, _Locale) ->
|
|
|
integer_to_list_zerofill(hour_24to12(H));
|
|
|
|
|
|
%% Hour, 24-hour format; i.e. '00' to '23'
|
|
|
-tag_to_value($H, _, {H,_,_}, TransFun, Locale) ->
|
|
|
+tag_to_value($H, _, {H,_,_}, _TransFun, _Locale) ->
|
|
|
integer_to_list_zerofill(H);
|
|
|
|
|
|
%% Minutes; i.e. '00' to '59'
|
|
|
-tag_to_value($i, _, {_,M,_}, TransFun, Locale) ->
|
|
|
+tag_to_value($i, _, {_,M,_}, _TransFun, _Locale) ->
|
|
|
integer_to_list_zerofill(M);
|
|
|
|
|
|
%% Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off
|
|
|
%% if they're zero and the strings 'midnight' and 'noon' if appropriate.
|
|
|
%% Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
|
|
|
%% Proprietary extension.
|
|
|
-tag_to_value($P, _, {0, 0, _}, TransFun, Locale) -> "midnight";
|
|
|
-tag_to_value($P, _, {12, 0, _}, TransFun, Locale) -> "noon";
|
|
|
+tag_to_value($P, _, {0, 0, _}, TransFun, Locale) ->
|
|
|
+ erlang:apply(TransFun, ["midnight", Locale]);
|
|
|
+tag_to_value($P, _, {12, 0, _}, TransFun, Locale) ->
|
|
|
+ erlang:apply(TransFun, ["noon", Locale]);
|
|
|
tag_to_value($P, Date, Time, TransFun, Locale) ->
|
|
|
tag_to_value($f, Date, Time, TransFun, Locale)
|
|
|
++ " " ++ tag_to_value($a, Date, Time, TransFun, Locale);
|
|
|
|
|
|
%% Seconds; i.e. '00' to '59'
|
|
|
-tag_to_value($s, _, {_,_,S}, TransFun, Locale) ->
|
|
|
+tag_to_value($s, _, {_,_,S}, _TransFun, _Locale) ->
|
|
|
integer_to_list_zerofill(S);
|
|
|
|
|
|
%%-----------------------------------------------------------
|
|
@@ -191,71 +203,87 @@ tag_to_value($s, _, {_,_,S}, TransFun, Locale) ->
|
|
|
|
|
|
%% Month, textual, 3 letters, lowercase; e.g. 'jan'
|
|
|
tag_to_value($b, {_,M,_}, _, TransFun, Locale) ->
|
|
|
- string:sub_string(monthname(M), 1, 3);
|
|
|
+ erlang:apply(TransFun,[string:sub_string(monthname(M), 1, 3), Locale]);
|
|
|
|
|
|
%% Day of the month, 2 digits with leading zeros; i.e. '01' to '31'
|
|
|
-tag_to_value($d, {_, _, D}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($d, {_, _, D}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list_zerofill(D);
|
|
|
|
|
|
%% Day of the week, textual, 3 letters; e.g. 'Fri'
|
|
|
tag_to_value($D, Date, _, TransFun, Locale) ->
|
|
|
Dow = calendar:day_of_the_week(Date),
|
|
|
- ucfirst(string:sub_string(dayname(Dow), 1, 3));
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(string:sub_string(dayname(Dow), 1, 3)),
|
|
|
+ Locale ]);
|
|
|
|
|
|
%% Month, textual, long, alternative; e.g. 'Listopada'
|
|
|
-tag_to_value($F, {_,M,_}, _, TransFun, Locale) ->
|
|
|
- ucfirst(monthname(M));
|
|
|
+tag_to_value($E, {_,M,_}, _, TransFun, Locale) ->
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(monthname(M)),
|
|
|
+ {Locale, <<"alt. month">>}]);
|
|
|
|
|
|
|
|
|
%% Month, textual, long; e.g. 'January'
|
|
|
tag_to_value($F, {_,M,_}, _, TransFun, Locale) ->
|
|
|
- ucfirst(monthname(M));
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(monthname(M)),
|
|
|
+ Locale]);
|
|
|
|
|
|
%% '1' if Daylight Savings Time, '0' otherwise.
|
|
|
-tag_to_value($I, _, _, TransFun, Locale) ->
|
|
|
+tag_to_value($I, _, _, _TransFun, _Locale) ->
|
|
|
"TODO";
|
|
|
|
|
|
%% Day of the month without leading zeros; i.e. '1' to '31'
|
|
|
-tag_to_value($j, {_, _, D}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($j, {_, _, D}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(D);
|
|
|
|
|
|
%% Day of the week, textual, long; e.g. 'Friday'
|
|
|
tag_to_value($l, Date, _, TransFun, Locale) ->
|
|
|
- ucfirst(dayname(calendar:day_of_the_week(Date)));
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(dayname(calendar:day_of_the_week(Date))),
|
|
|
+ Locale]);
|
|
|
|
|
|
%% Boolean for whether it is a leap year; i.e. True or False
|
|
|
-tag_to_value($L, {Y,_,_}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($L, {Y,_,_}, _, _TransFun, _Locale) ->
|
|
|
case calendar:is_leap_year(Y) of
|
|
|
true -> "True";
|
|
|
_ -> "False"
|
|
|
end;
|
|
|
|
|
|
%% Month; i.e. '01' to '12'
|
|
|
-tag_to_value($m, {_, M, _}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($m, {_, M, _}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list_zerofill(M);
|
|
|
|
|
|
%% Month, textual, 3 letters; e.g. 'Jan'
|
|
|
tag_to_value($M, {_,M,_}, _, TransFun, Locale) ->
|
|
|
- ucfirst(string:sub_string(monthname(M), 1, 3));
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(string:sub_string(monthname(M), 1, 3)),
|
|
|
+ Locale]);
|
|
|
|
|
|
%% Month without leading zeros; i.e. '1' to '12'
|
|
|
-tag_to_value($n, {_, M, _}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($n, {_, M, _}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(M);
|
|
|
|
|
|
%% Month abbreviation in Associated Press style. Proprietary extension.
|
|
|
tag_to_value($N, {_,M,_}, _, TransFun, Locale) when M =:= 9 ->
|
|
|
%% Special case - "Sept."
|
|
|
- ucfirst(string:sub_string(monthname(M), 1, 4)) ++ ".";
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(string:sub_string(monthname(M), 1, 4)) ++ ".",
|
|
|
+ {Locale, <<"abbrev. month">>}]);
|
|
|
tag_to_value($N, {_,M,_}, _, TransFun, Locale) when M < 3 orelse M > 7 ->
|
|
|
%% Jan, Feb, Aug, Oct, Nov, Dec are all
|
|
|
%% abbreviated with a full-stop appended.
|
|
|
- ucfirst(string:sub_string(monthname(M), 1, 3)) ++ ".";
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(string:sub_string(monthname(M), 1, 3)) ++ ".",
|
|
|
+ {Locale, <<"abbrev. month">>}]);
|
|
|
tag_to_value($N, {_,M,_}, _, TransFun, Locale) ->
|
|
|
%% The rest are the fullname.
|
|
|
- ucfirst(monthname(M));
|
|
|
+ erlang:apply(TransFun, [
|
|
|
+ ucfirst(monthname(M)),
|
|
|
+ {Locale, <<"abbrev. month">>}]);
|
|
|
|
|
|
%% Difference to Greenwich time in hours; e.g. '+0200'
|
|
|
-tag_to_value($O, Date, Time, TransFun, Locale) ->
|
|
|
+tag_to_value($O, Date, Time, _TransFun, _Locale) ->
|
|
|
Diff = utc_diff(Date, Time),
|
|
|
Offset = if
|
|
|
Diff < 0 ->
|
|
@@ -266,68 +294,68 @@ tag_to_value($O, Date, Time, TransFun, Locale) ->
|
|
|
lists:flatten(Offset);
|
|
|
|
|
|
%% RFC 2822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'
|
|
|
-tag_to_value($r, Date, Time, TransFun, Locale) ->
|
|
|
+tag_to_value($r, Date, Time, _TransFun, _Locale) ->
|
|
|
% afaik, date should not be translated in case RFC format is specified.
|
|
|
replace_tags(Date, Time, "D, j M Y H:i:s O", fun stub_tran/2, <<>> );
|
|
|
|
|
|
%% English ordinal suffix for the day of the month, 2 characters;
|
|
|
%% i.e. 'st', 'nd', 'rd' or 'th'
|
|
|
-tag_to_value($S, {_, _, D}, _, TransFun, Locale) when
|
|
|
+tag_to_value($S, {_, _, D}, _, _TransFun, _Locale) when
|
|
|
D rem 100 =:= 11 orelse
|
|
|
D rem 100 =:= 12 orelse
|
|
|
D rem 100 =:= 13 -> "th";
|
|
|
-tag_to_value($S, {_, _, D}, _, TransFun, Locale) when D rem 10 =:= 1 -> "st";
|
|
|
-tag_to_value($S, {_, _, D}, _, TransFun, Locale) when D rem 10 =:= 2 -> "nd";
|
|
|
-tag_to_value($S, {_, _, D}, _, TransFun, Locale) when D rem 10 =:= 3 -> "rd";
|
|
|
-tag_to_value($S, _, _, TransFun, Locale) -> "th";
|
|
|
+tag_to_value($S, {_, _, D}, _, _TransFun, _Locale) when D rem 10 =:= 1 -> "st";
|
|
|
+tag_to_value($S, {_, _, D}, _, _TransFun, _Locale) when D rem 10 =:= 2 -> "nd";
|
|
|
+tag_to_value($S, {_, _, D}, _, _TransFun, _Locale) when D rem 10 =:= 3 -> "rd";
|
|
|
+tag_to_value($S, _, _, _TransFun, _Locale) -> "th";
|
|
|
|
|
|
%% Number of days in the given month; i.e. '28' to '31'
|
|
|
-tag_to_value($t, {Y,M,_}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($t, {Y,M,_}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(calendar:last_day_of_the_month(Y,M));
|
|
|
|
|
|
%% Time zone of this machine; e.g. 'EST' or 'MDT'
|
|
|
-tag_to_value($T, _, _, TransFun, Locale) ->
|
|
|
+tag_to_value($T, _, _, _TransFun, _Locale) ->
|
|
|
"TODO";
|
|
|
|
|
|
%% Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)
|
|
|
-tag_to_value($U, Date, Time, TransFun, Locale) ->
|
|
|
+tag_to_value($U, Date, Time, _TransFun, _Locale) ->
|
|
|
EpochSecs = calendar:datetime_to_gregorian_seconds({Date, Time})
|
|
|
- calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}),
|
|
|
integer_to_list(EpochSecs);
|
|
|
|
|
|
%% Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)
|
|
|
-tag_to_value($w, Date, _, TransFun, Locale) ->
|
|
|
+tag_to_value($w, Date, _, _TransFun, _Locale) ->
|
|
|
%% Note: calendar:day_of_the_week returns
|
|
|
%% 1 | .. | 7. Monday = 1, Tuesday = 2, ..., Sunday = 7
|
|
|
integer_to_list(calendar:day_of_the_week(Date) rem 7);
|
|
|
|
|
|
%% ISO-8601 week number of year, weeks starting on Monday
|
|
|
-tag_to_value($W, {Y,M,D}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($W, {Y,M,D}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(year_weeknum(Y,M,D));
|
|
|
|
|
|
%% Year, 2 digits; e.g. '99'
|
|
|
-tag_to_value($y, {Y, _, _}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($y, {Y, _, _}, _, _TransFun, _Locale) ->
|
|
|
string:sub_string(integer_to_list(Y), 3);
|
|
|
|
|
|
%% Year, 4 digits; e.g. '1999'
|
|
|
-tag_to_value($Y, {Y, _, _}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($Y, {Y, _, _}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(Y);
|
|
|
|
|
|
%% Day of the year; i.e. '0' to '365'
|
|
|
-tag_to_value($z, {Y,M,D}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($z, {Y,M,D}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(day_of_year(Y,M,D));
|
|
|
|
|
|
%% Time zone offset in seconds (i.e. '-43200' to '43200'). The offset for
|
|
|
%% timezones west of UTC is always negative, and for those east of UTC is
|
|
|
%% always positive.
|
|
|
-tag_to_value($Z, _, _, TransFun, Locale) ->
|
|
|
+tag_to_value($Z, _, _, _TransFun, _Locale) ->
|
|
|
"TODO";
|
|
|
|
|
|
%% o – the ISO 8601 year number
|
|
|
-tag_to_value($o, {Y,M,D}, _, TransFun, Locale) ->
|
|
|
+tag_to_value($o, {Y,M,D}, _, _TransFun, _Locale) ->
|
|
|
integer_to_list(weeknum_year(Y,M,D));
|
|
|
|
|
|
-tag_to_value(C, Date, Time, TransFun, Locale) ->
|
|
|
+tag_to_value(C, Date, Time, _TransFun, _Locale) ->
|
|
|
io:format("Unimplemented tag : ~p [Date : ~p] [Time : ~p]",
|
|
|
[C, Date, Time]),
|
|
|
"".
|
|
@@ -418,4 +446,7 @@ ucfirst([First | Rest]) when First >= $a, First =< $z ->
|
|
|
ucfirst(Other) ->
|
|
|
Other.
|
|
|
|
|
|
-stub_tran(A,_) -> A.
|
|
|
+stub_tran(A,_) ->
|
|
|
+ % userful for test debuggging
|
|
|
+ % io:format("calling stub translation!!!",[]),
|
|
|
+ A.
|