uef-lib icon indicating copy to clipboard operation
uef-lib copied to clipboard

Useful Erlang Functions Library

= uef-lib :toc: macro :toclevels: 4

image:https://img.shields.io/hexpm/v/uef.svg?color=yellow["uef-lib on Hex.pm", link="https://hex.pm/packages/uef"] image:https://github.com/DOBRO/uef-lib/workflows/Build/badge.svg?branch=master["Build Status", link="https://github.com/DOBRO/uef-lib/actions/workflows/main.yml?query=branch%3Amaster"] image:https://codecov.io/gh/DOBRO/uef-lib/branch/master/graph/badge.svg["Code coverage", link="https://app.codecov.io/gh/DOBRO/uef-lib"] image:https://img.shields.io/badge/license-Apache%202.0-blue.svg["License", link="LICENSE"]

uef-lib is a Useful Erlang Functions Library that provides modules for manipulating lists, binaries, maps, numbers, date and time. It can be used in OTP applications and contains some functions optimized for performance in specific cases (e.g. for file I/O operations or binary transformations).

Erlang/OTP 19 or higher is required.

See how to link:#build[build] and link:#test-and-dialyze[test].

'''

toc::[]

'''

== Installation

=== For Erlang projects

Add uef-lib as a dependency to your rebar.config file:

[source,erlang]

{deps, [ {uef, "2.6.0"} ]}.

=== For Elixir projects

Add uef-lib as a dependency to your mix.exs file:

[source,elixir]

defp deps do [ {:uef, "~> 2.6.0"} ] end

== Modules

  • link:#module-uef_bin[uef_bin] - for binaries.
  • link:#module-uef_crypt[uef_crypt] - some crypto functions.
  • link:#module-uef_encode[uef_encode] - working with encodings.
  • link:#module-uef_file[uef_file] - working with files.
  • link:#module-uef_format[uef_format] - formatting numbers.
  • link:#module-uef_lists[uef_lists] - lists transformations.
  • link:#module-uef_maps[uef_maps] - functions for maps processing.
  • link:#module-uef_num[uef_num] - helpful functions for numbers.
  • link:#module-uef_time[uef_time] - datetime functions.

== Documentation

=== Module uef_bin

'''

==== uef_bin:chomp/1

[source,erlang]

uef_bin:chomp(Binary1 :: binary()) -> Binary2 :: binary().

Removes all trailing \n and \r characters from Binary1.

Examples:

[source,erlang]

uef_bin:chomp(<<"string\r\n">>). <<"string">>

uef_bin:chomp(<<"string\r\n\r\n">>). <<"string">>

uef_bin:chomp(<<"string\n\n\n\n">>). <<"string">>

uef_bin:chomp(<<"string\r\r\r\r">>). <<"string">>


'''

==== uef_bin:binary_join/2

[source,erlang]

uef_bin:binary_join(ListOfBinaries, Separator) -> Binary.

Joins a list of binaries with separator into a single binary. Returns binary.

Example:

[source,erlang]

uef_bin:binary_join([<<"www">>, <<"example">>, <<"com">>], <<".">>). <<"www.example.com">>


'''

==== uef_bin:repeat/2

[source,erlang]

uef_bin:repeat(Binary1, N) -> Binary2.

Returns binary Binary2 consisting of Binary1 repeated N times.

Examples:

[source,erlang]

uef_bin:repeat(<<"a">>, 10). <<"aaaaaaaaaa">>

uef_bin:repeat(<<"0">>, 3). <<"000">>

uef_bin:repeat(<<0>>, 3). <<0,0,0>>

uef_bin:repeat(<<1,1>>, 3). <<1,1,1,1,1,1>>

uef_bin:repeat(<<"abc">>, 3). <<"abcabcabc">>


'''

==== uef_bin:reverse/1

[source,erlang]

uef_bin:reverse(Binary1) -> Binary2.

Returns a binary in reverse byte order.

Note: this function is not intended to work with UTF-8 binary strings. To get a binary in reverse character order, use link:#uef_binreverse_utf81[uef_bin:reverse_utf8/1] instead.

Examples:

[source,erlang]

uef_bin:reverse(<<"ABCDEFGH">>). <<"HGFEDCBA">>

uef_bin:reverse(<<1,2,3,4,5>>). <<5,4,3,2,1>>

uef_bin:reverse(<<>>). <<>>


'''

==== uef_bin:reverse_utf8/1

[source,erlang]

uef_bin:reverse_utf8(UTF8_Binary1) -> UTF8_Binary2.

Returns a binary in reverse character order. Intended to work with UTF-8 binary strings.

Examples:

[source,erlang]

uef_bin:reverse_utf8(<<"ABCDEFGH">>). <<"HGFEDCBA">>

uef_bin:reverse_utf8(<<1,2,3,4,5>>). <<5,4,3,2,1>>

uef_bin:reverse_utf8(<<"die Straße"/utf8>>). <<"eßartS eid"/utf8>>

uef_bin:reverse_utf8(<<"АБВГДЕЁЖ"/utf8>>) =:= <<"ЖЁЕДГВБА"/utf8>>. true

uef_bin:reverse_utf8(<<1, 2, 3, "АБВГДЕЁЖ"/utf8, 4, 5, 6, 7>>) =:= <<7, 6, 5, 4, "ЖЁЕДГВБА"/utf8, 3, 2, 1>>. true

uef_bin:reverse_utf8(<<"這條街"/utf8>>) =:= <<"街條這"/utf8>>. true

uef_bin:reverse_utf8(<<"こんにちは"/utf8>>) =:= <<"はちにんこ"/utf8>>. true


'''

==== uef_bin:split/2

[source,erlang]

uef_bin:split(Binary, Splitter) -> ListOfBinaries.

Splits binary Binary with splitter Splitter into a list of binaries. Works as http://erlang.org/doc/man/binary.html#split-2[binary:split/2] but is more performant in simple cases.

Examples:

[source,erlang]

uef_bin:split(<<".www.example.com.">>, <<".">>). [<<>>,<<"www">>,<<"example">>,<<"com">>,<<>>]

uef_bin:split(<<"www.example.com">>, <<".">>). [<<"www">>,<<"example">>,<<"com">>]

uef_bin:split(<<"www.example.com">>, <<"A">>). [<<"www.example.com">>]


'''

==== uef_bin:split/3

[source,erlang]

uef_bin:split(Binary, Splitter, 'trim_all') -> ListOfBinaries.

Splits binary Binary with splitter Splitter into a list of binaries. Works as uef_bin:split/2 but removes all epmty (<<>>) chunks. It can be used in simple cases instead of http://erlang.org/doc/man/binary.html#split-3[binary:split/3] for the reason that it's more performant.

Example:

[source,erlang]

uef_bin:split(<<"..www.example.com.">>, <<".">>, trim_all). [<<"www">>,<<"example">>,<<"com">>]


'''

==== uef_bin:replace/3

[source,erlang]

uef_bin:replace(Binary1, Chars, OtherChars) -> Binary2.

Replaces chars Chars with other chars OtherChars in binary Binary1 and returns another binary Binary2. Works as http://erlang.org/doc/man/binary.html#replace-3[binary:replace/3] but more permormant and can be used in simple cases.

Examples:

[source,erlang]

uef_bin:replace(<<"abcdefgbc">>, <<"bc">>, <<"ZZ">>). <<"aZZdefgZZ">>

uef_bin:replace(<<"abcdefgbc">>, <<"d">>, <<"ZZ">>). <<"abcZZefgbc">>


'''

==== uef_bin:replace_chars/3

[source,erlang]

uef_bin:replace_chars(Binary1, ListOfCharsToReplace, OtherChars) -> Binary2.

Replaces chars inluded in list ListOfCharsToReplace with other chars OtherChars in binary Binary1 and returns another binary Binary2.

Examples:

[source,erlang]

uef_bin:replace_chars(<<"..www.example.com.">>, [<<".">>], <<>>). <<"wwwexamplecom">>

uef_bin:replace_chars(<<"..www.example.com.">>, [<<".">>, <<"w">>], <<>>). <<"examplecom">>

'''

==== uef_bin:random_latin_binary/2

[source,erlang]

uef_bin:random_latin_binary(Length, CaseFlag) -> RandomLatinBinary.

Returns a random binary of size Length consisting of latins [a-zA-Z] and digits [0-9]. The second argument CaseFlag corresponds to a letter case, an atom 'lower', 'upper' or 'any'.

Examples:

[source,erlang]

uef_bin:random_latin_binary(10, lower). <<"n0ui89sfsb">>

uef_bin:random_latin_binary(10, upper). <<"S11Y3DHEJI">>

uef_bin:random_latin_binary(10, any). <<"mTa9Lj7KUN">>


'''

==== uef_bin:random_binary_from_chars/2

[source,erlang]

uef_bin:random_binary_from_chars(Length, Chars) -> RandomCharsBinary.

Generates and returns a binary of size Length which consists of the given characters Chars.

Example:

[source,erlang]

uef_bin:random_binary_from_chars(16, <<"ErlangForever">>). <<"eFveerorreravgng">>


'''

==== uef_bin:numeric_prefix/1

[source,erlang]

uef_bin:numeric_prefix(Binary) -> DigitsOnlyOrEmptyBinary.

Returns new binary DigitsOnlyBinary which consists of digits [0-9] wich are at the beginning in the given binary Binary. If Binary does not begin with digit, this function returns empty binary (<<>>).

Examples:

[source,erlang]

uef_bin:numeric_prefix(<<"3456sld1knskjd">>). <<"3456">>

uef_bin:numeric_prefix(<<"ddd3456sld1knskjd">>). <<>>


'''

==== uef_bin:strip_left/2

[source,erlang]

uef_bin:strip_left(Binary1, Chars) -> Binary2.

Types: [source,erlang]

Binary1 :: binary(). Chars :: binary() | integer(). Binary2 :: binary().

Removes leading Chars from Binary1 and returns Binary2.

Examples:

[source,erlang]

uef_bin:strip_left(<<"www.example.com">>, <<"w">>). <<".example.com">>

uef_bin:strip_left(<<"www.example.com">>, <<"ww">>). <<"w.example.com">>

uef_bin:strip_left(<<11, 11, 11, 12, 13, 14>>, 11). <<12,13,14>>

uef_bin:strip_left(<<"ААААБВГДЕЁЖ"/utf8>>, <<"А"/utf8>>) =:= <<"БВГДЕЁЖ"/utf8>>. true

uef_bin:strip_left(<<"這這這這條街"/utf8>>, <<"這"/utf8>>) =:= <<"條街"/utf8>>. true


'''

==== uef_bin:strip_right/2

[source,erlang]

uef_bin:strip_right(Binary1, Chars) -> Binary2.

Types: [source,erlang]

Binary1 :: binary(). Chars :: binary() | integer(). Binary2 :: binary().

Removes trailing Chars from Binary1 and returns Binary2.

Examples:

[source,erlang]

uef_bin:strip_right(<<"example.comwww">>, <<"w">>). <<"example.com">>

uef_bin:strip_right(<<"example.comwww">>, <<"ww">>). <<"example.comw">>

uef_bin:strip_right(<<1, 2, 3, 4, 5, 5, 5>>, 5). <<1,2,3,4>>

uef_bin:strip_right(<<"АБВГДЕЁЖЖЖЖ"/utf8>>, <<"Ж"/utf8>>) =:= <<"АБВГДЕЁ"/utf8>>. true

uef_bin:strip_right(<<"這條街街街街"/utf8>>, <<"街"/utf8>>) =:= <<"這條"/utf8>>. true


'''

==== uef_bin:strip_both/2

[source,erlang]

uef_bin:strip_both(Binary1, Chars) -> Binary2.

Types: [source,erlang]

Binary1 :: binary(). Chars :: binary() | integer(). Binary2 :: binary().

Removes leading and trailing Chars from Binary1 and returns Binary2.

Examples:

[source,erlang]

uef_bin:strip_both(<<"www.example.www">>, <<"w">>). <<".example.">>

uef_bin:strip_both(<<"com.example.com">>, <<"com">>). <<".example.">>

uef_bin:strip_both(<<5,5,5, 1,2,3,4, 5,5,5>>, 5). <<1,2,3,4>>

uef_bin:strip_both(<<"ЖЖЖЖАБВГДЕЁЖЖЖЖ"/utf8>>, <<"Ж"/utf8>>) =:= <<"АБВГДЕЁ"/utf8>>. true

uef_bin:strip_both(<<"街街街街這條街街街街"/utf8>>, <<"街"/utf8>>) =:= <<"這條"/utf8>>. true


'''

=== Module uef_crypt

'''

==== uef_crypt:md5_hex/1

[source,erlang]

uef_crypt:md5_hex(IoData) -> Binary.

Returns binary Binary in hexadecimal form of md5 hash of the argument IoData.

Examples:

[source,erlang]

uef_crypt:md5_hex("abcd"). <<"e2fc714c4727ee9395f324cd2e7f331f">>

uef_crypt:md5_hex(<<"привет"/utf8>>). <<"608333adc72f545078ede3aad71bfe74">>

uef_crypt:md5_hex(["how", ["is", ["it"]], "going", $?]). <<"eb89df06495cef83e3ec185aefe81d0e">>


'''

=== Module uef_encode

'''

==== uef_encode:html_encode_bin/1

[source,erlang]

uef_encode:html_encode_bin(Html) -> EncodedBinary.

Takes argument Html, replaces some unsafe symbols with their appropriate HTML entities and returns binary.

Examples:

[source,erlang]

uef_encode:html_encode_bin("<>&©\n™"). <<"<>&©
™">>

uef_encode:html_encode_bin("♦±Σ"). <<"♦±Σ">>


'''

==== uef_encode:html_encode_list/1

[source,erlang]

uef_encode:html_encode_list(Html) -> EncodedList.

Takes argument Html, replaces some unsafe symbols with their appropriate HTML entities and returns list of binaries.

Examples:

[source,erlang]

uef_encode:html_encode_list("<>&©\n™"). [<<"<">>,<<">">>,<<"&">>,<<"©">>,<<"
">>,<<"™">>]

uef_encode:html_encode_list("♦±Σ"). [<<"♦">>,<<"±">>,<<"Σ">>]


'''

==== uef_encode:win_to_utf8/1

[source,erlang]

uef_encode:win_to_utf8(Binary1251) -> BinaryUtf8.

Converts cp1251 binary to utf-8 binary.

Example:

[source,erlang]

file_1251_to_utf8() -> File1251 = "1251.txt", FileUtf8 = "utf8.txt", {ok, Bin1251} = file:read_file(File1251), BinUtf8 = uef_encode:win_to_utf8(Bin1251), %converting file:write_file(FileUtf8, BinUtf8).

'''

=== Module uef_file


==== uef_file:read_file_info_fast/1

[source,erlang]

uef_file:read_file_info_fast(Filename) -> {ok, FileInfo} | {error, Reason}.

Retrieves information about local file. Returns {ok, FileInfo} if successful, otherwise {error, Reason}. Works as http://erlang.org/doc/man/file.html#read_file_info-2[file:read_file_info/2] but optimized for local files. This is a wrapper of:

file:read_file_info(Filename, [raw, {time, posix}]).

'''

==== uef_file:read_file_fast/1

[source,erlang]

uef_file:read_file_fast(Filename) -> {ok, BinaryData} | {error, Reason}.

Reads contents of local file Filename and returns {ok, BinaryData}, where BinaryData is a binary data object that contains the contents of Filename, or {error, Reason} if an error occurs. This function is optimized for reading contents of local files, as no Erlang process is used. It calls http://erlang.org/doc/man/file.html#open-2[file:open/2] with options [read, raw, binary].

'''

=== Module uef_format

'''

==== uef_format:format_bytes/1

[source,erlang]

uef_format:format_bytes(Bytes) -> FormattedBytes.

The same as uef_format:format_bytes(Bytes, #{}). See link:#uef_formatformat_bytes2[uef_format:format_bytes/2] docs.

Examples:

[source,erlang]

uef_format:format_bytes(1024). <<"1KB">>

uef_format:format_bytes(1000). <<"0KB">>

uef_format:format_bytes(1048576). <<"1MB">>

uef_format:format_bytes(10485760). <<"10MB">>


'''

==== uef_format:format_bytes/2

[source,erlang]

uef_format:format_bytes(Bytes, Options) -> FormattedBytes.

Types:

[source,erlang]

Bytes :: integer().

Options :: #{ units => Units, base => Base, to_type => ToType, sep => Separator }.

Units :: auto | MultiUnits. MultiUnits :: 'KB' | 'MB' | 'GB' | 'TB' | 'PB' | 'EB' | 'ZB' | 'YB'. Base :: 2 | 10. ToType :: bin | int. Separator :: binary().

FormattedBytes :: binary() | integer() | {integer(), MultiUnits}.

Default Options:

[source,erlang]

#{ units => auto, base => 2, to_type => bin, sep => <<>> }.

Converts bytes Bytes to https://en.wikipedia.org/wiki/Megabyte[multiples of bytes]. The datatype of the return value depends on ToType and Units:

  • if ToType is bin, it returns binary();
  • if ToType is int, it returns integer();
  • if ToType is int and Units is auto, tuple {integer(), MultiUnits} is returned.

The value of Base affects the conversion of Bytes to multiples:

  • Base = 2 means that 1KB = 1024 bytes, 1MB = 1048576 bytes, ...;
  • Base = 10 means that 1KB = 1000 bytes, 1MB = 1000000 bytes, ...

If the value of Units is auto, bytes are converted to the most reasonable multiples of bytes.

Separator is a separator between integer value and Units. This option affects the result when ToType is bin.

Examples:

[source,erlang]

uef_format:format_bytes(1000000, #{units => auto, base => 2}). <<"976KB">>

uef_format:format_bytes(1048576, #{units => auto, base => 2}). <<"1MB">>

uef_format:format_bytes(1048576, #{units => 'KB', base => 2}). <<"1024KB">>

uef_format:format_bytes(1048576, #{units => 'KB', base => 10}). <<"1048KB">>

uef_format:format_bytes(1048576, #{units => auto, base => 2, to_type => int}). {1,'MB'}

uef_format:format_bytes(1048576, #{units => 'KB', base => 2, to_type => int}). 1024

uef_format:format_bytes(1048576, #{units => 'KB', to_type => bin, sep => <<" ">>}). <<"1024 KB">>

uef_format:format_bytes(1048576, #{units => 'KB', to_type => bin, sep => <<"|">>}). <<"1024|KB">>


'''

==== uef_format:format_number/3

[source,erlang]

uef_format:format_number(Number, Precision, Decimals) -> FormattedNumber.

The same as uef_format:format_number/4 with #{} as the forth argument. See link:#uef_formatformat_number4[uef_format:format_number/4] docs.

Examples:

[source,erlang]

uef_format:format_number(199.4567, 2, 3). <<"199.460">>

uef_format:format_number(199.4567, 1, 3). <<"199.500">>

uef_format:format_number(199.4567, 0, 4). <<"199.0000">>

uef_format:format_number(199.4567, -1, 2). <<"200.00">>


'''

==== uef_format:format_number/4

[source,erlang]

uef_format:format_number(Number, Precision, Decimals, Options) -> FormattedNumber.

Formats Number by adding thousands separator between each set of 3 digits to the left of the decimal point, substituting Decimals for the decimal point, and rounding to the specified Precision. Returns a binary value.

Types:

[source,erlang]

Number :: number(). Precision :: integer(). Decimals :: non_neg_integer(). FormattedNumber :: binary().

Options is a map:

[source,erlang]

#{ thousands_sep => binary() | string(), % Thousands separator decimal_point => binary() | string(), % Decimal point cur_symbol => binary() | string(), %% Currency symbol cur_pos => 'left' | 'right', % Currency position against price (left or right) cur_sep => binary() | string() % Separator between currency and price }

Note: to get maximum performance use binary values for options thousands_sep, decimal_point, cur_symbol and cur_sep instead of strings.

Examples:

[source,erlang]

uef_format:format_number(1234567890.4567, 2, 2, #{}). <<"1234567890.46">>

uef_format:format_number(1234567890.4567, 2, 2, #{thousands_sep => ",", cur_symbol => "$"}). <<"$1,234,567,890.46">>

uef_format:format_number(1234567890.4567, 2, 2, #{ thousands_sep => ",", cur_symbol => "USD", cur_sep => " ", % whitespace cur_pos => right}). <<"1,234,567,890.46 USD">>

uef_format:format_number(1234567890.4567, 2, 4, #{ thousands_sep => ",", decimal_point => "==", cur_symbol => "USD", cur_sep => " ", cur_pos => left}). <<"USD 1,234,567,890==4600">>

uef_format:format_number(1234567890.4567, 2, 4, #{ thousands_sep => <<",">>, % binary() decimal_point => <<".">>, % binary() cur_symbol => <<"USD">>, % binary() cur_sep => <<" ">>, % binary() cur_pos => left}). <<"USD 1,234,567,890.4600">>


'''

==== uef_format:format_price/1

[source,erlang]

uef_format:format_price(Number) -> FormattedPrice.

Formats Number in price-like style. Returns a binary containing FormattedPrice formatted with a precision of 2 and decimal digits of 2.

The same as uef_format:format_price/2 with a precision of 2 as the second argument. See link:#uef_formatformat_price2[uef_format:format_price/2] docs.

Examples:

[source,erlang]

uef_format:format_price(199). <<"199.00">>

uef_format:format_price(199.9876). <<"199.99">>


'''

==== uef_format:format_price/2

[source,erlang]

uef_format:format_price(Number, Precision) -> FormattedPrice.

Formats Number in price-like style. Returns a binary containing FormattedPrice formatted with a specified precision as the second argument and decimal digits of 2.

The same as uef_format:format_price/3 with #{} as the third argument. See link:#uef_formatformat_price3[uef_format:format_price/3] docs.

Example:

[source,erlang]

uef_format:format_price(1999.9876, 4). <<"1999.99">>


'''

==== uef_format:format_price/3

[source,erlang]

uef_format:format_price(Number, Precision, CurrencySymbol_OR_Options) -> FormattedPrice.

Formats Number in price-like style. Returns a binary containing FormattedPrice formatted with a specified precision as the second argument, decimal digits of 2, and with currency symbol (or options) as the third argument.

If CurrencySymbol_OR_Options is a map the functions works as link:#uef_formatformat_number4[uef_format:format_number/4] with decimal digits of 2 as the third argument and with options as the forth one.

If CurrencySymbol_OR_Options is a binary or a string, the corresponding currency symbol is added to the left.

Examples:

[source,erlang]

uef_format:format_price(1000.8767, 4, #{}). <<"1000.88">>

uef_format:format_price(1000.8767, 4, #{ thousands_sep => ",", cur_symbol => "USD", cur_sep => " ", cur_pos => right}). <<"1,000.88 USD">>

uef_format:format_price(1000.8767, 4, #{ thousands_sep => ",", cur_symbol => <<"руб."/utf8>>, cur_sep => " ", cur_pos => right}). <<49,44,48,48,48,46,56,56,32,209,128,209,131,208,177,46>> % <<"1,000.88 руб."/utf8>>.

uef_format:format_price(1000.8767, 4, "$"). <<"$1000.88">>

uef_format:format_price(99.999, 2, "$"). <<"$100.00">>

uef_format:format_price(99.99, 2, "$"). <<"$99.99">>

uef_format:format_price(99.99, 2, <<"€"/utf8>>). <<226,130,172,57,57,46,57,57>> % <<"€99.99"/utf8>>


'''

=== Module uef_lists

'''

==== uef_lists:split_list_into_chunks/2

[source,erlang]

uef_lists:split_list_into_chunks(List, MaxLen) -> [List1, List2, ..., ListN].

Splits List into list of lists [List1, List2, ..., ListN] where List1, List2, ..., ListN are lists with maximum MaxLen elements.

Examples:

[source,erlang]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 1). [[1],[2],[3],[4],[5],[6],[7],[8]]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 2). [[1,2],[3,4],[5,6],[7,8]]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 3). [[1,2,3],[4,5,6],[7,8]]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 4). [[1,2,3,4],[5,6,7,8]]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 8). [[1,2,3,4,5,6,7,8]]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 9). [[1,2,3,4,5,6,7,8]]

uef_lists:split_list_into_chunks([1,2,3,4,5,6,7,8], 99). [[1,2,3,4,5,6,7,8]]


'''

==== uef_lists:lists_to_list_of_tuples/2

[source,erlang]

uef_lists:lists_to_list_of_tuples(List1, List2) -> List3.

Transforms two lists into one list of two-tuples, where the first element of each tuple is taken from the first list and the second element is taken from the second list one by one.

Examples:

[source,erlang]

uef_lists:lists_to_list_of_tuples([a,b,c], [1,2]). [{a,1},{a,2},{b,1},{b,2},{c,1},{c,2}]

uef_lists:lists_to_list_of_tuples([a,b,c], [1,2,3]). [{a,1},{a,2},{a,3},{b,1},{b,2},{b,3},{c,1},{c,2},{c,3}]


'''

==== uef_lists:lists_to_list_of_tuples/3

[source,erlang]

uef_lists:lists_to_list_of_tuples(List1, List2, List3) -> List4.

Transforms three lists into one list of three-tuples, where the first element of each tuple is taken from the first list, the second element is taken from the second list one by one, and the third element is taken from the third list one by one.

Examples:

[source,erlang]

uef_lists:lists_to_list_of_tuples([a1,b1], [a2,b2], [a3,b3]). [{a1,a2,a3}, {a1,a2,b3}, {a1,b2,a3}, {a1,b2,b3}, {b1,a2,a3}, {b1,a2,b3}, {b1,b2,a3}, {b1,b2,b3}]

uef_lists:lists_to_list_of_tuples([a1,b1], [a2,b2,c2], [a3,b3]). [{a1,a2,a3}, {a1,a2,b3}, {a1,b2,a3}, {a1,b2,b3}, {a1,c2,a3}, {a1,c2,b3}, {b1,a2,a3}, {b1,a2,b3}, {b1,b2,a3}, {b1,b2,b3}, {b1,c2,a3}, {b1,c2,b3}]


'''

==== uef_lists:search/2

[source,erlang]

uef_lists:search(Pred, List) -> {value, Value} | false.

If there is a Value in List such that Pred(Value) returns true, returns {value, Value} for the first such Value, otherwise returns false.

Note: Since OTP 21.0 use BIF lists:search/2 instead.

'''

=== Module uef_maps

'''

==== uef_maps:delete_nested/2

[source,erlang]

uef_maps:delete_nested(Keys, Map1) -> {ok, Map2} | {error, {badkey, SomeKey}} | {error, empty_keys}.

Say, Keys is a list of elements Key1, Key2, ..., KeyN and Map1 has internal structure #{Key1 => #{Key2 => #{... => #{KeyN => ValueN}}}}. The function removes key KeyN, if it exists, and its associated value from the corresponding internal map and updates the entire structure of map Map1 getting new map Map2. There are three possible return values:

  • tuple {ok, Map2} if KeyN was removed;

  • tuple {error, {badkey, SomeKey}} if SomeKey does not exist in the structure of map Map1, where SomeKey is one of the elements of list Keys;

  • tuple {error, empty_keys} if Keys is empty list.

The call fails with a {badmap,Map1} exception if Map1 is not a map, or with a {badlist,Keys} exception if Keys is not a list.

See also: link:#uef_mapsremove_nested2[uef_maps:remove_nested/2], link:#uef_mapstake_nested2[uef_maps:take_nested/2].

Examples:

[source,erlang]

Map1 = #{1 => #{2 => #{3 => val3, 33 => val33}}}. #{1 => #{2 => #{3 => val3,33 => val33}}}

uef_maps:delete_nested([], Map1). {error,empty_keys}

uef_maps:delete_nested([1], Map1). {ok,#{}}

uef_maps:delete_nested([1,2], Map1). {ok,#{1 => #{}}}

uef_maps:delete_nested([1,2,3], Map1). {ok,#{1 => #{2 => #{33 => val33}}}}

uef_maps:delete_nested([-1], Map1). {error,{badkey,-1}}

uef_maps:delete_nested([1,-2], Map1). {error,{badkey,-2}}

uef_maps:delete_nested([1,2,-3], Map1). {error,{badkey,-3}}

uef_maps:delete_nested([1,2,3,4], Map1). {error,{badkey,4}}

uef_maps:delete_nested([1,2,3,4,5], Map1). {error,{badkey,4}} % 4, not 5!


'''

==== uef_maps:find_nested/2

[source,erlang]

uef_maps:find_nested(Keys, Map) -> {ok, Value} | error.

Traverses nested map Map (map of maps) deep through the keys that are elements of list Keys. Returns tuple {ok, Value}, where Value is the value associated with the last element of list Keys, or error if no value is found.

The call fails with a {badmap,Map} exception if Map is not a map, or with a {badlist,Keys} exception if Keys is not a list.

Examples:

[source,erlang]

Value = abc, M3 = #{key4 => Value}, M2 = #{key3 => M3}, M1 = #{key2 => M2}, M0 = #{key1 => M1}. #{key1 => #{key2 => #{key3 => #{key4 => abc}}}} % M0

uef_maps:find_nested([key1], M0). {ok,#{key2 => #{key3 => #{key4 => abc}}}} % {ok, M1}

uef_maps:find_nested([key1,key2], M0). {ok,#{key3 => #{key4 => abc}}} % {ok, M2}

uef_maps:find_nested([key1,key2,key3], M0). {ok,#{key4 => abc}} % {ok, M3}

uef_maps:find_nested([key1,key2,key3,key4], M0). {ok,abc} % {ok, Value}

uef_maps:find_nested([-1], M0). error

uef_maps:find_nested([key1,key2,-3,key4], M0). error

uef_maps:find_nested([key1,key2,key3,-4], M0). error

uef_maps:find_nested([key1,key2,key3,key4,key5], M0). ** exception error: {badmap,abc}


'''

==== uef_maps:get_nested/2

[source,erlang]

uef_maps:get_nested(Keys, Map) -> Value.

Traverses nested map Map (map of maps) deep through the keys that are elements of list Keys. Returns value Value associated with the last element of list Keys.

The call fails with a {badmap,Map} exception if Map is not a map, or with a {badkeys,Keys} exception if no value is found, or with a {badlist,Keys} exception if Keys is not a list.

Examples:

[source,erlang]

Value = abc, M3 = #{key4 => Value}, M2 = #{key3 => M3}, M1 = #{key2 => M2}, M0 = #{key1 => M1}. #{key1 => #{key2 => #{key3 => #{key4 => abc}}}} % M0

uef_maps:get_nested([key1], M0). #{key2 => #{key3 => #{key4 => abc}}} % M1

uef_maps:get_nested([key1,key2], M0). #{key3 => #{key4 => abc}} % M2

uef_maps:get_nested([key1,key2,key3], M0). #{key4 => abc} % M3

uef_maps:get_nested([key1,key2,key3,key4], M0). abc % Value


'''

==== uef_maps:get_nested/3

[source,erlang]

uef_maps:get_nested(Keys, Map, Default) -> Value | Default.

Traverses nested map Map (map of maps) deep through the keys that are elements of list Keys. Returns value Value associated with the last element of list Keys. If no value is found, Default is returned.

The call fails with a {badmap,Map} exception if Map is not a map, or with a {badlist,Keys} exception if Keys is not a list. It does not fail if any internal value associated with any element of list Keys is not a map.

Examples:

[source,erlang]

Value = abc, Default = default, M3 = #{key4 => Value}, M2 = #{key3 => M3}, M1 = #{key2 => M2}, M0 = #{key1 => M1}. #{key1 => #{key2 => #{key3 => #{key4 => abc}}}} % M0.

uef_maps:get_nested([key1,key2,key3,key4], M0, Default). abc % Value

uef_maps:get_nested([key1,key2,key3,-4], M0, Default). default % Default

uef_maps:get_nested([key1,key2,-3,key4], M0, Default). default % Default

uef_maps:get_nested([key1,key2,key3,key4,key5], M0, Default). default % Default anyway. Doesn't fail


'''

==== uef_maps:is_key_nested/2

[source,erlang]

uef_maps:is_key_nested(Keys, Map) -> true | false.

Returns true if map Map contains submaps as values associated with their own key corresponding to the element of list Keys, and returns false otherwise.

The call fails with a {badmap,Map} exception if Map is not a map, or with a {badlist,Keys} exception if Keys is not a list.

Examples:

[source,erlang]

M3 = #{key4 => value}, M2 = #{key3 => M3}, M1 = #{key2 => M2}, M0 = #{key1 => M1}. #{key1 => #{key2 => #{key3 => #{key4 => value}}}} % M0

uef_maps:is_key_nested([key1,key2,key3,key4], M0). true

uef_maps:is_key_nested([key1,key2,key3], M0). true

uef_maps:is_key_nested([key1,key2], M0). true

uef_maps:is_key_nested([key1], M0). true

uef_maps:is_key_nested([], M0). false

uef_maps:is_key_nested([key1,key2,key3,key4,key5], M0). false

uef_maps:is_key_nested([-1,key2,key3,key4], M0). false

uef_maps:is_key_nested([key1,-2,key3,key4], M0). false


'''

==== uef_maps:new_nested/1

[source,erlang]

uef_maps:new_nested(Keys) -> Map.

Same as uef_maps:new_nested(Keys, #{}). See docs of link:#uef_mapsnew_nested2[uef_maps:new_nested/2].

'''

==== uef_maps:new_nested/2

[source,erlang]

uef_maps:new_nested(Keys, Value) -> Map.

Returns new nested map Map with the deepest map #{LastKey => Value}, where LastKey is the last element of list Keys.

The call fails with a {badlist,Keys} exception if Keys is not a list.

Examples:

[source,erlang]

uef_maps:new_nested([], value). #{}

uef_maps:new_nested([key], value). #{key => value}

uef_maps:new_nested([key1, key2], value). #{key1 => #{key2 => value}}

uef_maps:new_nested([key1, key2, key3], value). #{key1 => #{key2 => #{key3 => value}}}


'''

==== uef_maps:put_nested/3

[source,erlang]

uef_maps:put_nested(Keys, Value, Map1) -> Map2.

Say, Keys is a list of elements Key1, Key2, ..., KeyN and Map1 has internal structure #{Key1 => #{Key2 => #{... => #{KeyN => ValueN}}}}. The function associates KeyN with value Value and updates the entire structure of map Map1 returning new map Map2. If some keys from list Keys are not in the structure of map Map1, they will be inserted into the structure of map Map2 in the same order.

The call fails with a {badmap,Map1} exception if Map1 is not a map, or with a {badlist,Keys} exception if Keys is not a list.

See also: link:#uef_mapsupdate_nested3[uef_maps:update_nested/3].

Examples:

[source,erlang]

Map1 = #{1 => #{2 => #{3 => val3}}}. #{1 => #{2 => #{3 => val3}}} % Map1

uef_maps:put_nested([], new_value, Map1). #{1 => #{2 => #{3 => val3}}} % Map1 (empty list of keys)

uef_maps:put_nested([1], new_value, Map1). #{1 => new_value}

uef_maps:put_nested([1,2], new_value, Map1). #{1 => #{2 => new_value}}

uef_maps:put_nested([1,2,3], new_value, Map1). #{1 => #{2 => #{3 => new_value}}}

uef_maps:put_nested([1,2,-3], new_value, Map1). #{1 => #{2 => #{-3 => new_value,3 => val3}}}

uef_maps:put_nested([1,2,3,4], new_value, Map1). #{1 => #{2 => #{3 => #{4 => new_value}}}}

uef_maps:put_nested([-1], new_value, Map1). #{-1 => new_value,1 => #{2 => #{3 => val3}}}

uef_maps:put_nested([1,-2], new_value, Map1). #{1 => #{-2 => new_value,2 => #{3 => val3}}}

uef_maps:put_nested([1,2,-3], new_value, Map1). #{1 => #{2 => #{-3 => new_value,3 => val3}}}

uef_maps:put_nested([1,2,3,-4], new_value, Map1). #{1 => #{2 => #{3 => #{-4 => new_value}}}}


'''

==== uef_maps:remove_nested/2

[source,erlang]

uef_maps:remove_nested(Keys, Map1) -> Map2.

Say, Keys is a list of elements Key1, Key2, ..., KeyN and Map1 has internal structure #{Key1 => #{Key2 => #{... => #{KeyN => ValueN}}}}. The function removes key KeyN, if it exists, and its associated value from the corresponding internal map and updates the entire structure of map Map1 returning new map Map2. If some keys from list Keys are not in the structure of map Map1 the function returns a map without changes.

The call fails with a {badmap,Map1} exception if Map1 is not a map, or with a {badlist,Keys} exception if Keys is not a list.

See also: link:#uef_mapsdelete_nested2[uef_maps:delete_nested/2], link:#uef_mapstake_nested2[uef_maps:take_nested/2].

Examples:

[source,erlang]

Map1 = #{1 => #{2 => #{3 => val3, 33 => val33}}}. #{1 => #{2 => #{3 => val3,33 => val33}}}

uef_maps:remove_nested([], Map1). #{1 => #{2 => #{3 => val3,33 => val33}}} % Map1 (empty list of keys)

uef_maps:remove_nested([1], Map1). #{}

uef_maps:remove_nested([1,2], Map1). #{1 => #{}}

uef_maps:remove_nested([1,2,3], Map1). #{1 => #{2 => #{33 => val33}}}

uef_maps:remove_nested([-1], Map1). #{1 => #{2 => #{3 => val3,33 => val33}}} % Map1

uef_maps:remove_nested([1,-2], Map1). #{1 => #{2 => #{3 => val3,33 => val33}}} % Map1

uef_maps:remove_nested([1,2,-3], Map1). #{1 => #{2 => #{3 => val3,33 => val33}}} % Map1

uef_maps:remove_nested([1,2,3,4], Map1). #{1 => #{2 => #{3 => val3,33 => val33}}} % Map1

uef_maps:remove_nested([1,2,3,4,5], Map1). #{1 => #{2 => #{3 => val3,33 => val33}}} % Map1


'''

==== uef_maps:take_nested/2

[source,erlang]

uef_maps:take_nested(Keys, Map1) -> {Value, Map2} | error.

Say, Keys is a list of elements Key1, Key2, ..., KeyN and Map1 has internal structure #{Key1 => #{Key2 => #{... => #{KeyN => Value}}}}. The function removes key KeyN, if it exists, and its associated value Value from the corresponding internal map and updates the entire structure of map Map1 returning tuple {Value, Map2}. If some keys from list Keys are not in the structure of map Map1 the function returns error.

The call fails with a {badmap,Map1} exception if Map1 is not a map, or with a {badlist,Keys} exception if Keys is not a list.

See also: link:#uef_mapsdelete_nested2[uef_maps:delete_nested/2], link:#uef_mapsremove_nested2[uef_maps:remove_nested/2].

Examples:

[source,erlang]

Map1 = #{1 => #{2 => #{3 => val3, 33 => val33}}}. #{1 => #{2 => #{3 => val3,33 => val33}}}

uef_maps:take_nested([], Map1). error

uef_maps:take_nested([1], Map1). {#{2 => #{3 => val3,33 => val33}},#{}}

uef_maps:take_nested([1,2], Map1). {#{3 => val3,33 => val33},#{1 => #{}}}

uef_maps:take_nested([1,2,3], Map1). {val3,#{1 => #{2 => #{33 => val33}}}}

uef_maps:take_nested([-1], Map1). error

uef_maps:take_nested([1,-2], Map1). error

uef_maps:take_nested([1,2,-3], Map1). error

uef_maps:take_nested([1,2,3,4], Map1). error

uef_maps:take_nested([1,2,3,4,5], Map1). error


'''

==== uef_maps:update_nested/3

[source,erlang]

uef_maps:update_nested(Keys, Value, Map1) -> Map2.

Works similar to link:#uef_mapsput_nested3[uef_maps:put_nested/3] with the difference that it fails with a {badkey,SomeKey} exception if SomeKey does not exist in the structure of map Map1, where SomeKey is one of the elements of list Keys.

The call also fails with a {badmap,Map1} exception if Map1 is not a map, or with a {badlist,Keys} exception if Keys is not a list.

Examples:

[source,erlang]

Map1 = #{1 => #{2 => #{3 => val3}}}. #{1 => #{2 => #{3 => val3}}} % Map1

uef_maps:update_nested([], new_value, Map1). #{1 => #{2 => #{3 => val3}}} % Map1 (empty list of keys)

uef_maps:update_nested([1], new_value, Map1). #{1 => new_value}

uef_maps:update_nested([1,2], new_value, Map1). #{1 => #{2 => new_value}}

uef_maps:update_nested([1,2,3], new_value, Map1). #{1 => #{2 => #{3 => new_value}}}

uef_maps:update_nested([1,2,3,4], new_value, Map1). ** exception error: {badkey,4}

uef_maps:update_nested([1,2,3,4,5], new_value, Map1). ** exception error: {badkey,4} % 4, not 5! because 4 is before

uef_maps:update_nested([-1], new_value, Map1). ** exception error: {badkey,-1}

uef_maps:update_nested([1,-2], new_value, Map1). ** exception error: {badkey,-2}

uef_maps:update_nested([1,2,-3], new_value, Map1). ** exception error: {badkey,-3}

uef_maps:update_nested([1,2,3,-4], new_value, Map1). ** exception error: {badkey,-4}


'''

=== Module uef_num

'''

==== uef_num:ctz/1

[source,erlang]

uef_num:ctz(Integer) -> TrailingZeros.

Counts https://en.wikipedia.org/wiki/Find_first_set[trailing zeros] in the binary representation of a positive integer. Returns the number of zero bits following the least significant one bit.

The call fails with a {badarg,Integer} exception if Integer is not a positive integer.

Examples:

[source,erlang]

uef_num:ctz(2#10001000). 3

uef_num:ctz(7). 0

uef_num:ctz(2#00101010). 1

uef_num:ctz(2#1000000000000000000000000000000000000000000000000000000000000000). 63

uef_num:ctz(2#1111111111111111111111111111111111111111111111111111111111111111). 0

uef_num:ctz(16#FFFFFFFFFFFFFFFF). 0


'''

==== uef_num:lsb_pos/1

[source,erlang]

uef_num:lsb_pos(Integer) -> Position.

Returns the position of the https://en.wikipedia.org/wiki/Bit_numbering[least significant bit] (LSB) in the binary representation of a positive integer.

The call fails with a {badarg,Integer} exception if Integer is not a positive integer.

Examples:

[source,erlang]

uef_num:lsb_pos(2#10001000). 4

uef_num:lsb_pos(7). 1

uef_num:lsb_pos(2#00101010). 2

uef_num:lsb_pos(2#1000000000000000000000000000000000000000000000000000000000000000). 64

uef_num:lsb_pos(2#1111111111111111111111111111111111111111111111111111111111111111). 1

uef_num:lsb_pos(16#FFFFFFFFFFFFFFFF). 1


'''

==== uef_num:msb_pos/1

[source,erlang]

uef_num:msb_pos(Integer) -> Position.

Returns the position of the https://en.wikipedia.org/wiki/Bit_numbering[most significant bit] (MSB) in the binary representation of a positive integer.

The call fails with a {badarg,Integer} exception if Integer is not a positive integer.

Examples:

[source,erlang]

uef_num:msb_pos(2#111). 3

uef_num:msb_pos(7). 3

uef_num:msb_pos(2#0010101). 5

uef_num:msb_pos(2#1000000000000000000000000000000000000000000000000000000000000000). 64

uef_num:msb_pos(2#1111111111111111111111111111111111111111111111111111111111111111). 64

uef_num:msb_pos(16#FFFFFFFFFFFFFFFF). 64


'''

==== uef_num:popcount/1

[source,erlang]

uef_num:popcount(Integer) -> OneBits.

Returns the number of 1's (ones or one-bits) in the https://en.wikipedia.org/wiki/Binary_number#Representation[binary representation] of a non-negative integer. Also known as population count, pop count, popcount, sideways sum, bit summation, or https://en.wikipedia.org/wiki/Hamming_weight[Hamming weight].

The call fails with a {badarg,Integer} exception if Integer is not a non-negative integer.

Examples:

[source,erlang]

uef_num:popcount(7). 3

uef_num:popcount(0). 0

uef_num:popcount(2#1010101). 4

uef_num:popcount(2#1000000000000000000000000000000000000000000000000000000000000000). 1

uef_num:popcount(2#1111111111111111111111111111111111111111111111111111111111111111). 64

uef_num:popcount(16#FFFFFFFFFFFFFFFF). 64


'''

==== uef_num:round_number/2

[source,erlang]

uef_num:round_number(Number, Precision) -> Float.

Rounds the number to the specified precision.

Examples:

[source,erlang]

uef_num:round_number(10, 2). 10.0

uef_num:round_number(123.786, 2). 123.79


'''

==== uef_num:round_price/1

[source,erlang]

uef_num:round_price(Number) -> Float.

Rounds the number to the precision of 2. The same as uef_num:round_number(Number, 2).

'''

=== Module uef_time

'''

==== uef_time:add_seconds/1

[source,erlang]

uef_time:add_seconds(Seconds) -> NewDateTime.

Same as uef_time:add_seconds(erlang:localtime(), Seconds). See docs of link:#uef_timeadd_seconds2[uef_time:add_seconds/2].

Types:

[source,erlang]

Seconds :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_seconds/2

[source,erlang]

uef_time:add_seconds(DateOrDatetime, Seconds) -> NewDateTime.

Adds the number of seconds Seconds to DateOrDatetime and returns a new datetime value.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Seconds :: integer(). NewDateTime :: calendar:datetime().

Examples:

[source,erlang]

uef_time:add_seconds({2019, 1, 1}, 10). {{2019,1,1},{0,0,10}}

uef_time:add_seconds({2019, 1, 1}, -10). {{2018,12,31},{23,59,50}}

uef_time:add_seconds({{2019, 1, 1}, {23, 59, 0}}, 10). {{2019,1,1},{23,59,10}}

uef_time:add_seconds({{2019, 1, 1}, {23, 59, 0}}, -10). {{2019,1,1},{23,58,50}}


'''

==== uef_time:add_minutes/1

[source,erlang]

uef_time:add_minutes(Minutes) -> NewDateTime.

Same as uef_time:add_seconds(Minutes * 60). See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].

Types:

[source,erlang]

Minutes :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_minutes/2

[source,erlang]

uef_time:add_minutes(DateOrDatetime, Minutes) -> NewDateTime.

Adds the number of minutes Minutes to DateOrDatetime and returns a new datetime value.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Minutes :: integer(). NewDateTime :: calendar:datetime().

Examples:

[source,erlang]

uef_time:add_minutes({2019, 1, 1}, 10). {{2019,1,1},{0,10,0}}

uef_time:add_minutes({2019, 1, 1}, -10). {{2018,12,31},{23,50,0}}

uef_time:add_minutes({{2019, 1, 1}, {23, 59, 0}}, 10). {{2019,1,2},{0,9,0}}

uef_time:add_minutes({{2019, 1, 1}, {0, 1, 0}}, -10). {{2018,12,31},{23,51,0}}


'''

==== uef_time:add_hours/1

[source,erlang]

uef_time:add_hours(Hours) -> NewDateTime.

Same as uef_time:add_seconds(Hours * 3600). See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].

Types:

[source,erlang]

Hours :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_hours/2

[source,erlang]

uef_time:add_hours(DateOrDatetime, Hours) -> NewDateTime.

Adds the number of hours Hours to DateOrDatetime and returns a new datetime value.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Hours :: integer(). NewDateTime :: calendar:datetime().

Examples:

[source,erlang]

uef_time:add_hours({2019, 1, 1}, 10). {{2019,1,1},{10,0,0}}

uef_time:add_hours({2019, 1, 1}, -10). {{2018,12,31},{14,0,0}}

uef_time:add_hours({{2019, 1, 1}, {23, 59, 0}}, 10). {{2019,1,2},{9,59,0}}

uef_time:add_hours({{2019, 1, 1}, {0, 1, 0}}, -10). {{2018,12,31},{14,1,0}}


'''

==== uef_time:add_days/1

[source,erlang]

uef_time:add_days(Days) -> NewDateTime.

Same as uef_time:add_seconds(Days * 86400). See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].

Types:

[source,erlang]

Days :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_days/2

[source,erlang]

uef_time:add_days(DateOrDatetime, Days) -> NewDateOrDateTime.

Adds the number of days Days to DateOrDatetime and returns a new date or datetime value. The type of NewDateOrDateTime is the same as the type of DateOrDatetime.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Days :: integer(). NewDateOrDateTime :: calendar:date() | calendar:datetime().

Examples:

[source,erlang]

uef_time:add_days({2019, 1, 1}, 10). {2019,1,11}

uef_time:add_days({2019, 1, 1}, -10). {2018,12,22}

uef_time:add_days({{2019, 1, 1}, {23, 59, 0}}, 10). {{2019,1,11},{23,59,0}}

uef_time:add_days({{2019, 1, 1}, {0, 1, 0}}, -10). {{2018,12,22},{0,1,0}}


'''

==== uef_time:add_weeks/1

[source,erlang]

uef_time:add_weeks(Weeks) -> NewDateTime.

Same as uef_time:add_seconds(Weeks * 604800). See docs of link:#uef_timeadd_seconds1[uef_time:add_seconds/1].

Types:

[source,erlang]

Weeks :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_weeks/2

[source,erlang]

uef_time:add_weeks(DateOrDatetime, Weeks) -> NewDateOrDateTime.

Adds the number of weeks Weeks to DateOrDatetime and returns a new date or datetime value. The type of NewDateOrDateTime is the same as the type of DateOrDatetime.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Weeks :: integer(). NewDateOrDateTime :: calendar:date() | calendar:datetime().

Examples:

[source,erlang]

uef_time:add_weeks({2019, 1, 1}, 4). {2019,1,29}

uef_time:add_weeks({2019, 1, 1}, -4). {2018,12,4}

uef_time:add_weeks({{2019, 1, 1}, {23, 59, 0}}, 4). {{2019,1,29},{23,59,0}}

uef_time:add_weeks({{2019, 1, 1}, {0, 1, 0}}, -4). {{2018,12,4},{0,1,0}}


'''

==== uef_time:add_months/1

[source,erlang]

uef_time:add_months(Months) -> NewDateTime.

Same as uef_time:add_months(erlang:localtime(), Months). See docs of link:#uef_timeadd_months2[uef_time:add_months/2].

Types:

[source,erlang]

Months :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_months/2

[source,erlang]

uef_time:add_months(DateOrDatetime, Months) -> NewDateOrDateTime.

Adds the number of months Months to DateOrDatetime and returns a new date or datetime value. The type of NewDateOrDateTime is the same as the type of DateOrDatetime.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Months :: integer(). NewDateOrDateTime :: calendar:date() | calendar:datetime().

Examples:

[source,erlang]

uef_time:add_months({2019, 1, 31}, 1). {2019,2,28}

uef_time:add_months({2016, 1, 31}, 1). {2016,2,29}

uef_time:add_months({2019, 1, 31}, -1). {2018,12,31}

uef_time:add_months({{2019, 1, 1}, {23, 59, 0}}, 1). {{2019,2,1},{23,59,0}}

uef_time:add_months({{2019, 1, 1}, {0, 1, 0}}, -1). {{2018,12,1},{0,1,0}}


'''

==== uef_time:add_years/1

[source,erlang]

uef_time:add_years(Years) -> NewDateTime.

Same as uef_time:add_years(erlang:localtime(), Years). See docs of link:#uef_timeadd_years2[uef_time:add_years/2].

Types:

[source,erlang]

Years :: integer(). NewDateTime :: calendar:datetime().

'''

==== uef_time:add_years/2

[source,erlang]

uef_time:add_years(DateOrDatetime, Years) -> NewDateOrDateTime.

Adds the number of years Years to DateOrDatetime and returns a new date or datetime value. The type of NewDateOrDateTime is the same as the type of DateOrDatetime.

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). Years :: integer(). NewDateOrDateTime :: calendar:date() | calendar:datetime().

Examples:

[source,erlang]

uef_time:add_years({2019, 1, 31}, 1). {2020,1,31}

uef_time:add_years({2019, 1, 31}, -1). {2018,1,31}

uef_time:add_years({{2019, 1, 1}, {23, 59, 0}}, 1). {{2020,1,1},{23,59,0}}

uef_time:add_years({{2019, 1, 1}, {0, 1, 0}}, -1). {{2018,1,1},{0,1,0}}


'''

==== uef_time:add_time/1

[source,erlang]

uef_time:add_time(Periods) -> NewDateTime.

Same as uef_time:add_time(erlang:localtime(), Periods). See docs of link:#uef_timeadd_time2[uef_time:add_time/2]. NewDateTime is of type calendar:datetime(). See types for Periods in Types section of function uef_time:add_time/2.

'''

==== uef_time:add_time/2

[source,erlang]

uef_time:add_time(DateOrDatetime, Periods) -> NewDateOrDateTime.

Adds one or more periods of time to DateOrDatetime and returns a new date or datetime value. This is a universal function based on functions uef_time:add_seconds/2, uef_time:add_minutes/2, uef_time:add_hours/2, uef_time:add_days/2, uef_time:add_weeks/2, uef_time:add_months/2 and uef_time:add_years/2. The type of NewDateOrDateTime depends on the type of DateOrDatetime and Periods (see Examples).

Types:

[source,erlang]

DateOrDatetime :: calendar:date() | calendar:datetime(). NewDateOrDateTime :: calendar:date() | calendar:datetime().

psecond() :: sec | second | seconds. pminute() :: min | minute | minutes. phour() :: hrs | hour | hours. pday() :: day | days. pmonth() :: month | months. pyear() :: year | years. ptype() :: psecond() | pminute() | phour() | pday() | pmonth() | pyear().

period() :: {integer(), ptype()} | {ptype(), integer()}. periods() :: [period()].

Examples:

[source,erlang]

uef_time:add_time({2000, 1, 1}, [{1, year}, {1, month}, {1, week}, {1, day}, {1, hour}, {1, minute}, {1, second}]). {{2001,2,9},{1,1,1}} % type calendar:datetime()

uef_time:add_time({2000, 1, 1}, [{1, year}, {1, month}, {1, week}, {1, day}]). {2001,2,9} % type calendar:date()

uef_time:add_time({{2000, 1, 1}, {0, 0, 0}}, [{1, year}, {1, month}, {1, week}, {1, day}]). {{2001,2,9},{0,0,0}} % type calendar:datetime()

uef_time:add_time({2000, 1, 1}, [{year, 1}, {month, 1}, {week, 1}, {day, 1}, {hour, 1}, {minute, 1}, {second, 1}]). {{2001,2,9},{1,1,1}}

uef_time:add_time({2000, 1, 1}, [{1, hrs}, {1, min}, {1, sec}]). {{2000,1,1},{1,1,1}}

uef_time:add_time({{2000, 1, 31}, {23, 59, 59}}, [{1, hour}, {1, minute}, {1, second}]). {{2000,2,1},{1,1,0}}

uef_time:add_time({{2000, 1, 31}, {23, 59, 59}}, [{1, second}]). {{2000,2,1},{0,0,0}}

uef_time:add_time({2000, 1, 1}, [{1, years}]) =:= uef_time:add_years({2000, 1, 1}, 1). true

uef_time:add_time({2000, 1, 1}, [{1, month}]) =:= uef_time:add_months({2000, 1, 1}, 1). true


'''

==== uef_time:today/0

[source,erlang]

uef_time:today() -> CurrentDate.

Returns the current date as {Year, Month, Day}. Same as http://erlang.org/doc/man/erlang.html#date-0[erlang:date()]. CurrentDate is of type calendar:date().

'''

==== uef_time:tomorrow/0

[source,erlang]

uef_time:tomorrow() -> TomorrowDate.

Returns tomorrow's date as {Year, Month, Day}. TomorrowDate is of type calendar:date().

'''

==== uef_time:yesterday/0

[source,erlang]

uef_time:yesterday() -> YesterdayDate.

Returns yesterday's date as {Year, Month, Day}. YesterdayDate is of type calendar:date().

'''

==== uef_time:unix_time/0

[source,erlang]

uef_time:unix_time() -> Seconds.

Returns the current number of seconds since 00:00:00 (UTC), 1 January 1970. It also known as Unix time or POSIX time or UNIX Epoch time.

Example:

[source,erlang]

uef_time:unix_time(). 1557670215


'''

==== uef_time:unix_time/1

[source,erlang]

uef_time:unix_time(Datetime) -> Seconds.

Returns the number of seconds elapsed between 00:00:00 (UTC), 1 January 1970 and Datetime. Datetime must be of type calenadr:datetime().

Examples:

[source,erlang]

uef_time:unix_time({{1970,1,1}, {0,0,0}}). 0

uef_time:unix_time({{2000,1,1}, {23,59,59}}). 946771199


'''

==== uef_time:days_diff/1

[source,erlang]

uef_time:days_diff(Date) -> Days.

Returns the difference in days between Date and the current local date provided by function http://erlang.org/doc/man/erlang.html#date-0[erlang:date()]. Date must be of type calendar:date() ({Year, Month, Day}). Days is a positive value if Date is after erlang:date() or a negative value otherwise.

'''

==== uef_time:days_diff/2

[source,erlang]

uef_time:days_diff(Date1, Date2) -> Days.

Returns the difference in days between Date2 and Date1. Date1 and Date2 must be of type calendar:date() ({Year, Month, Day}). Days is a positive value if Date2 is after Date1 or a negative value otherwise.

Examples:

[source,erlang]

uef_time:days_diff({1999, 1, 31}, {2019, 12, 31}). 7639

uef_time:days_diff({2019, 12, 31}, {1999, 1, 31}). -7639


'''

==== uef_time:seconds_diff/1

[source,erlang]

uef_time:seconds_diff(DateTime) -> Seconds.

Returns the difference in seconds between Date and the current local time provided by function http://erlang.org/doc/man/erlang.html#localtime-0[erlang:localtime()]. DateTime must be of type calendar:datetime() ({{Year, Month, Day}, {Hour, Minute, Second}}). Seconds is a positive value if DateTime is after erlang:localtime() or a negative value otherwise.

'''

==== uef_time:seconds_diff/2

[source,erlang]

uef_time:seconds_diff(DateTime1, DateTime2) -> Seconds.

Returns the difference in seconds between DateTime2 and DateTime1. DateTime1 and DateTime2 must be of type calendar:datetime() ({{Year, Month, Day}, {Hour, Minute, Second}}). Seconds is a positive value if DateTime2 is after DateTime1 or a negative value otherwise.

Examples:

[source,erlang]

uef_time:seconds_diff({{1999, 1, 31}, {0, 0, 0}}, {{2019, 12, 31}, {0, 0, 0}}). 660009600

uef_time:seconds_diff({{2019, 12, 31}, {0, 0, 0}}, {{1999, 1, 31}, {0, 0, 0}}). -660009600


'''

== Build

=== Build with GNU make

[source,bash]

make

=== Build with rebar3

[source,bash]

rebar3 compile

== Test and dialyze

=== Test/dialyze with GNU make

[source,bash]

make test

[source,bash]

make dialyzer

[source,bash]

make xref

[source,bash]

make cover

=== Test/dialyze with rebar3

[source,bash]

rebar3 eunit

[source,bash]

rebar3 dialyzer

[source,bash]

rebar3 xref

[source,bash]

rebar3 do eunit, cover

== Build documentation

=== Build docs with GNU make

[source,bash]

make docs

=== Build docs with rebar3

[source,bash]

rebar3 edoc

== Contributing

You are welcome :)