[libs] import the c++ date library

pull/1205/head
Tim Stack 9 months ago
parent c796a66273
commit 97e43bc76f

@ -94,6 +94,8 @@ Features:
* Added a log format for Redis.
* The `:eval` command will now treat its argument(s) as a
script, allowing multiple commands to be executed.
* Added a `timezone()` SQL function for converting a timestamp
to a target timezone.
Bug Fixes:
* Binary data piped into stdin should now be treated the same

@ -31,7 +31,7 @@ AC_SUBST(abssrcdir)
AC_PROG_CXX
CPPFLAGS="$CPPFLAGS -D_ISOC99_SOURCE -D__STDC_LIMIT_MACROS -D_GNU_SOURCE"
CPPFLAGS="$CPPFLAGS -D_ISOC99_SOURCE -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -DUSE_OS_TZDB=1 -DHAS_REMOTE_API=0"
AC_ARG_ENABLE([debug],
AS_HELP_STRING([--enable-debug],
@ -327,6 +327,7 @@ AC_CONFIG_FILES([src/tailer/Makefile])
AC_CONFIG_FILES([src/yajl/Makefile])
AC_CONFIG_FILES([src/yajlpp/Makefile])
AC_CONFIG_FILES([src/third-party/base64/lib/Makefile])
AC_CONFIG_FILES([src/third-party/date/src/Makefile])
AC_CONFIG_FILES([src/third-party/scnlib/src/Makefile])
AC_CONFIG_FILES([test/Makefile])

@ -635,6 +635,17 @@ add_library(
third-party/CLI/TypeTools.hpp
third-party/CLI/ConfigFwd.hpp
third-party/date/include/date/tz_private.h
third-party/date/include/date/ios.h
third-party/date/include/date/ptz.h
third-party/date/include/date/solar_hijri.h
third-party/date/include/date/date.h
third-party/date/include/date/julian.h
third-party/date/include/date/chrono_io.h
third-party/date/include/date/iso_week.h
third-party/date/include/date/tz.h
third-party/date/include/date/islamic.h
third-party/intervaltree/IntervalTree.h
third-party/md4c/md4c.h
@ -647,6 +658,7 @@ set(lnav_SRCS lnav.cc)
target_include_directories(diag PUBLIC . fmtlib ${CMAKE_CURRENT_BINARY_DIR}
third-party
third-party/base64/include
third-party/date/include
third-party/rapidyaml
)

@ -6,6 +6,7 @@ CXXFLAGS =
SUBDIRS = \
fmtlib \
third-party/base64/lib \
third-party/date/src \
third-party/scnlib/src \
pcrepp \
base \
@ -126,6 +127,7 @@ AM_CPPFLAGS = \
-I$(srcdir)/fmtlib \
-I$(srcdir)/third-party \
-I$(srcdir)/third-party/base64/include \
-I$(srcdir)/third-party/date/include \
-I$(srcdir)/third-party/rapidyaml \
-I$(top_srcdir)/src/third-party/scnlib/include \
-Wall \
@ -142,6 +144,7 @@ LDADD = \
base/libbase.a \
formats/logfmt/liblogfmt.a \
fmtlib/libcppfmt.a \
third-party/date/src/libdatepp.a \
third-party/scnlib/src/libscnlib.a \
pcrepp/libpcrepp.a \
pugixml/libpugixml.a \

File diff suppressed because it is too large Load Diff

@ -177,6 +177,11 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2(text_for
"<!--" ([^\x00*]|"-"+[^\x00>])* "-"{2,} ">" {
RET(DT_COMMENT);
}
"#[" "="* "[" ([^\x00\]]|"]" [^=\]])* "]" "="* "]" {
RET(DT_COMMENT);
}
[a-qstv-zA-QSTV-Z]"'" {
CAPTURE(DT_WORD);
}

@ -241,6 +241,20 @@
----
.. _convert_time_to:
:convert-time-to *zone*
^^^^^^^^^^^^^^^^^^^^^^^
Convert the focused timestamp to the given timezone
**Parameters**
* **zone\*** --- The timezone name
----
.. _create_logline_table:
:create-logline-table *table-name*

@ -503,7 +503,7 @@ anonymize(*value*)
Aback, 10.0.0.1
**See Also**
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -800,7 +800,7 @@ char(*X*)
HI
**See Also**
:ref:`anonymize`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -833,7 +833,7 @@ charindex(*needle*, *haystack*, *\[start\]*)
0
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -937,7 +937,7 @@ date(*timestring*, *modifier*)
2017-04-04
**See Also**
:ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`
:ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`timezone`
----
@ -976,7 +976,7 @@ datetime(*timestring*, *modifier*)
2017-04-04 21:37:22
**See Also**
:ref:`date`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`
:ref:`date`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`timezone`
----
@ -1001,7 +1001,7 @@ decode(*value*, *algorithm*)
curl
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1145,7 +1145,7 @@ encode(*value*, *algorithm*)
Hello%2C%20World%21
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1177,7 +1177,7 @@ endswith(*str*, *suffix*)
0
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1232,7 +1232,7 @@ extract(*str*)
{"col_0":1.0,"col_1":2.0}
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1458,7 +1458,7 @@ group_concat(*X*, *\[sep\]*)
hw,gw
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1482,7 +1482,7 @@ group_spooky_hash(*str*)
4e7a190aead058cb123c94290f29c34a
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1498,7 +1498,7 @@ gunzip(*b*)
* **b** --- The blob to decompress
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1514,7 +1514,7 @@ gzip(*value*)
* **value** --- The value to compress
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1567,7 +1567,7 @@ humanize_duration(*secs*)
1s500
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`date`, :ref:`datetime`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`julianday`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`strftime`, :ref:`substr`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`date`, :ref:`datetime`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`julianday`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`strftime`, :ref:`substr`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`timezone`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1591,7 +1591,7 @@ humanize_file_size(*value*)
10.0MB
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -1639,7 +1639,7 @@ instr(*haystack*, *needle*)
2
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2353,7 +2353,7 @@ julianday(*timestring*, *modifier*)
2457848.400949074
**See Also**
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`timezone`
----
@ -2448,7 +2448,7 @@ leftstr(*str*, *N*)
abc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2472,7 +2472,7 @@ length(*str*)
3
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2662,7 +2662,7 @@ logfmt2json(*str*)
{"foo":1,"bar":2,"name":"Rolo Tomassi"}
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2686,7 +2686,7 @@ lower(*str*)
abc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2718,7 +2718,7 @@ ltrim(*str*, *\[chars\]*)
c
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2875,7 +2875,7 @@ padc(*str*, *len*)
abcdef ghi
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2907,7 +2907,7 @@ padl(*str*, *len*)
abcdef
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2939,7 +2939,7 @@ padr(*str*, *len*)
abcdefghi
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -2970,7 +2970,7 @@ parse_url(*url*)
{"scheme":"https","username":"alice","password":null,"host":"[fe80::14ff:4ee5:1215:2fb2]","port":null,"path":"/","query":null,"parameters":null,"fragment":null}
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3068,7 +3068,7 @@ printf(*format*, *X*)
value: 00011
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3092,7 +3092,7 @@ proper(*str*)
Hello, World!
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3287,7 +3287,7 @@ regexp_capture(*string*, *pattern*)
1 2 <NULL> 3 8 9 2
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3315,7 +3315,7 @@ regexp_capture_into_json(*string*, *pattern*, *\[options\]*)
1 {"col_0⋯l_1":2}
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3354,7 +3354,7 @@ regexp_match(*re*, *str*)
{"num":123,"str":"four"}
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_replace`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_replace`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3387,7 +3387,7 @@ regexp_replace(*str*, *re*, *repl*)
<123> <abc>
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_match`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_match`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3420,7 +3420,7 @@ replace(*str*, *old*, *replacement*)
zbc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3445,7 +3445,7 @@ replicate(*str*, *N*)
abcabcabc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3469,7 +3469,7 @@ reverse(*str*)
cba
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3501,7 +3501,7 @@ rightstr(*str*, *N*)
abc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3597,7 +3597,7 @@ rtrim(*str*, *\[chars\]*)
a
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3687,7 +3687,7 @@ sparkline(*value*, *\[upper\]*)
▁▂▃▄▅▆▇█
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3732,7 +3732,7 @@ spooky_hash(*str*)
f96b3d9c1a19f4394c97a1b79b1880df
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3846,7 +3846,7 @@ startswith(*str*, *prefix*)
0
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3871,7 +3871,7 @@ strfilter(*source*, *include*)
bcbc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -3911,7 +3911,7 @@ strftime(*format*, *timestring*, *modifier*)
Julian day: 2457848.400949074
**See Also**
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`timezone`
----
@ -3958,7 +3958,7 @@ substr(*str*, *start*, *\[size\]*)
b
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -4021,7 +4021,7 @@ time(*timestring*, *modifier*)
21:37:22
**See Also**
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`timediff`, :ref:`timeslice`
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`timediff`, :ref:`timeslice`, :ref:`timezone`
----
@ -4053,7 +4053,7 @@ timediff(*time1*, *time2*)
86400
**See Also**
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timeslice`
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timeslice`, :ref:`timezone`
----
@ -4098,7 +4098,32 @@ timeslice(*time*, *slice*)
2017-02⋯:00.000 3
**See Also**
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff`
:ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff`, :ref:`timezone`
----
.. _timezone:
timezone(*tz*, *ts*)
^^^^^^^^^^^^^^^^^^^^
Convert a timestamp to the given timezone
**Parameters**
* **tz\*** --- The target timezone
* **ts\*** --- The source timestamp
**Examples**
To convert a time to America/Los_Angeles:
.. code-block:: custsqlite
;SELECT timezone('America/Los_Angeles', '2022-03-02T10:00')
2022-03-02T02:00:00.000000-0800
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`date`, :ref:`datetime`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`julianday`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`strftime`, :ref:`substr`, :ref:`time`, :ref:`timediff`, :ref:`timeslice`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -4165,7 +4190,7 @@ trim(*str*, *\[chars\]*)
abc
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -4218,7 +4243,7 @@ unicode(*X*)
97
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath`
----
@ -4256,7 +4281,7 @@ unparse_url(*obj*)
https://example.com/
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`upper`, :ref:`xpath`
----
@ -4280,7 +4305,7 @@ upper(*str*)
ABC
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`xpath`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`xpath`
----
@ -4323,7 +4348,7 @@ xpath(*xpath*, *xmldoc*)
Hello ★ /abc/def/text() {} Hello ★
**See Also**
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`
:ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture_into_json`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`timezone`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`
----

@ -83,6 +83,7 @@
#include "bound_tags.hh"
#include "breadcrumb_curses.hh"
#include "CLI/CLI.hpp"
#include "date/tz.h"
#include "dump_internals.hh"
#include "environ_vtab.hh"
#include "file_converter_manager.hh"
@ -1249,6 +1250,12 @@ looper()
log_pipe_err(errpipe[0]);
lnav_behavior lb;
{
log_info("BEGIN loading tzdb");
date::get_tzdb();
log_info("END loading tzdb");
}
ui_periodic_timer::singleton();
auto mouse_i = injector::get<xterm_mouse&>();

@ -54,6 +54,7 @@
#include "command_executor.hh"
#include "config.h"
#include "curl_looper.hh"
#include "date/tz.h"
#include "db_sub_source.hh"
#include "field_overlay_source.hh"
#include "fmt/printf.h"
@ -325,6 +326,54 @@ com_unix_time(exec_context& ec,
return Ok(retval);
}
static Result<std::string, lnav::console::user_message>
com_convert_time_to(exec_context& ec,
std::string cmdline,
std::vector<std::string>& args)
{
std::string retval;
if (args.empty()) {
args.emplace_back("timezone");
return Ok(retval);
}
if (args.size() == 1) {
return ec.make_error("expecting a timezone name");
}
auto* tc = *lnav_data.ld_view_stack.top();
auto* lss = dynamic_cast<logfile_sub_source*>(tc->get_sub_source());
if (lss != nullptr) {
if (lss->text_line_count() == 0) {
return ec.make_error("no log messages to examine");
}
auto ll = lss->find_line(lss->at(tc->get_selection()));
try {
auto* tz = date::locate_zone(args[1]);
auto utime = std::chrono::system_clock::from_time_t(ll->get_time());
auto ztime = date::make_zoned(tz, utime);
auto etime = std::chrono::duration_cast<std::chrono::seconds>(
ztime.get_local_time().time_since_epoch());
char ftime[128];
sql_strftime(
ftime, sizeof(ftime), etime.count(), ll->get_millis(), 'T');
retval = ftime;
} catch (const std::runtime_error& e) {
return ec.make_error(FMT_STRING("Unable to get timezone: {} -- {}"),
args[1],
e.what());
}
} else {
return ec.make_error(
":convert-time-to is only supported for the LOG view");
}
return Ok(retval);
}
static Result<std::string, lnav::console::user_message>
com_current_time(exec_context& ec,
std::string cmdline,
@ -503,7 +552,10 @@ com_goto(exec_context& ec, std::string cmdline, std::vector<std::string>& args)
alb.append("^");
if (unmatched_size > 1) {
alb.append(unmatched_size - 2, '-').append("^");
if (unmatched_size > 2) {
alb.append(unmatched_size - 2, '-');
}
alb.append("^");
}
alb.append(" unrecognized input");
}
@ -5110,6 +5162,7 @@ command_prompt(std::vector<std::string>& args)
add_tag_possibilities();
add_file_possibilities();
add_recent_netlocs_possibilities();
add_tz_possibilities(ln_mode_t::COMMAND);
auto* ta = dynamic_cast<text_anchors*>(tc->get_sub_source());
if (ta != nullptr) {
@ -5382,6 +5435,13 @@ readline_context::command_t STD_COMMANDS[] = {
.with_parameter(help_text("seconds", "The epoch timestamp to convert")
.with_format(help_parameter_format_t::HPF_INTEGER))
.with_example({"To convert the epoch time 1490191111", "1490191111"})},
{
"convert-time",
com_convert_time_to,
help_text(":convert-time-to")
.with_summary("Convert the focused timestamp to the given timezone")
.with_parameter(help_text("zone", "The timezone name")),
},
{"current-time",
com_current_time,

@ -216,6 +216,14 @@ to_json(const lnav::console::user_message& um)
to_json(gen, snip.s_content);
}
}
root_map.gen("notes");
{
yajlpp_array notes_array(gen);
for (const auto& note : um.um_notes) {
to_json(gen, note);
}
}
root_map.gen("help");
to_json(gen, um.um_help);
}
@ -318,6 +326,9 @@ static const typed_json_path_container<console::user_message>
yajlpp::property_handler("snippets#")
.for_field(&console::user_message::um_snippets)
.with_children(snippet_handlers),
yajlpp::property_handler("notes#")
.for_field(&console::user_message::um_notes)
.with_children(attr_line_handlers),
yajlpp::property_handler("help")
.for_child(&console::user_message::um_help)
.with_children(attr_line_handlers),

@ -36,6 +36,7 @@
#include "base/opt_util.hh"
#include "config.h"
#include "data_parser.hh"
#include "date/tz.h"
#include "lnav.hh"
#include "lnav_config.hh"
#include "service_tags.hh"
@ -508,3 +509,16 @@ add_recent_netlocs_possibilities()
recent_refs.rr_netlocs.end());
rc->add_possibility(ln_mode_t::COMMAND, "recent-netlocs", netlocs);
}
void
add_tz_possibilities(ln_mode_t context)
{
auto* rc = lnav_data.ld_rl_view;
log_info("BEGIN tz poss");
rc->clear_possibilities(context, "timezone");
for (const auto& tz : date::get_tzdb().zones) {
rc->add_possibility(context, "timezone", tz.name());
}
log_info("END tz poss");
}

@ -79,6 +79,7 @@ void add_config_possibilities();
void add_tag_possibilities();
void add_file_possibilities();
void add_recent_netlocs_possibilities();
void add_tz_possibilities(ln_mode_t context);
extern struct sqlite_metadata_callbacks lnav_sql_meta_callbacks;

@ -423,7 +423,7 @@ setup_highlights(highlight_map_t& hm)
hm[{highlight_source_t::INTERNAL, "0.comment"}]
= highlighter(
xpcre_compile(
R"((?<=[\s;])//.*|/\*.*\*/|\(\*.*\*\)|^#\s*(?!include|if|ifndef|elif|else|endif|error|pragma|define|undef).*|dnl.*)"))
R"((?<=[\s;]|^)//.*|/\*.*\*/|\(\*.*\*\)|^\s*#(?!\s*(?:include|if|ifndef|elif|else|endif|error|pragma|define|undef)\b).*|dnl.*)"))
.with_nestable(false)
.with_role(role_t::VCR_COMMENT);
hm[{highlight_source_t::INTERNAL, "z.comment"}]
@ -464,7 +464,7 @@ setup_highlights(highlight_map_t& hm)
hm[{highlight_source_t::INTERNAL, "cpp"}]
= highlighter(
xpcre_compile(
R"(^#\s*(?:include|ifdef|ifndef|if|else|elif|error|endif|define|undef|pragma))"))
R"(^#\s*(?:include|ifdef|ifndef|if|else|elif|error|endif|define|undef|pragma)\b)"))
.with_nestable(false)
.with_text_format(text_format_t::TF_C_LIKE)
.with_text_format(text_format_t::TF_JAVA)

@ -0,0 +1,34 @@
#ifndef CHRONO_IO_H
#define CHRONO_IO_H
// The MIT License (MIT)
//
// Copyright (c) 2016, 2017 Howard Hinnant
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Our apologies. When the previous paragraph was written, lowercase had not yet
// been invented (that would involve another several millennia of evolution).
// We did not mean to shout.
// This functionality has moved to "date.h"
#include "date.h"
#endif // CHRONO_IO_H

File diff suppressed because it is too large Load Diff

@ -0,0 +1,50 @@
//
// ios.h
// DateTimeLib
//
// The MIT License (MIT)
//
// Copyright (c) 2016 Alexander Kormanovsky
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef ios_hpp
#define ios_hpp
#if __APPLE__
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE
# include <string>
namespace date
{
namespace iOSUtils
{
std::string get_tzdata_path();
std::string get_current_timezone();
} // namespace iOSUtils
} // namespace date
# endif // TARGET_OS_IPHONE
#else // !__APPLE__
# define TARGET_OS_IPHONE 0
#endif // !__APPLE__
#endif // ios_hpp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,861 @@
#ifndef PTZ_H
#define PTZ_H
// The MIT License (MIT)
//
// Copyright (c) 2017 Howard Hinnant
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// This header allows Posix-style time zones as specified for TZ here:
// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
//
// Posix::time_zone can be constructed with a posix-style string and then used in
// a zoned_time like so:
//
// zoned_time<system_clock::duration, Posix::time_zone> zt{"EST5EDT,M3.2.0,M11.1.0",
// system_clock::now()};
// or:
//
// Posix::time_zone tz{"EST5EDT,M3.2.0,M11.1.0"};
// zoned_time<system_clock::duration, Posix::time_zone> zt{tz, system_clock::now()};
//
// If the rule set is missing (everything starting with ','), then the rule is that the
// alternate offset is never enabled.
//
// Note, Posix-style time zones are not recommended for all of the reasons described here:
// https://stackoverflow.com/tags/timezone/info
//
// They are provided here as a non-trivial custom time zone example, and if you really
// have to have Posix time zones, you're welcome to use this one.
#include "date/tz.h"
#include <cctype>
#include <ostream>
#include <string>
namespace Posix
{
namespace detail
{
#if HAS_STRING_VIEW
using string_t = std::string_view;
#else // !HAS_STRING_VIEW
using string_t = std::string;
#endif // !HAS_STRING_VIEW
class rule;
void throw_invalid(const string_t& s, unsigned i, const string_t& message);
unsigned read_date(const string_t& s, unsigned i, rule& r);
unsigned read_name(const string_t& s, unsigned i, std::string& name);
unsigned read_signed_time(const string_t& s, unsigned i, std::chrono::seconds& t);
unsigned read_unsigned_time(const string_t& s, unsigned i, std::chrono::seconds& t);
unsigned read_unsigned(const string_t& s, unsigned i, unsigned limit, unsigned& u,
const string_t& message = string_t{});
class rule
{
enum {off, J, M, N};
date::month m_;
date::weekday wd_;
unsigned short n_ : 14;
unsigned short mode_ : 2;
std::chrono::duration<std::int32_t> time_ = std::chrono::hours{2};
public:
rule() : mode_(off) {}
bool ok() const {return mode_ != off;}
date::local_seconds operator()(date::year y) const;
std::string to_string() const;
friend std::ostream& operator<<(std::ostream& os, const rule& r);
friend unsigned read_date(const string_t& s, unsigned i, rule& r);
friend bool operator==(const rule& x, const rule& y);
};
inline
bool
operator==(const rule& x, const rule& y)
{
if (x.mode_ != y.mode_)
return false;
switch (x.mode_)
{
case rule::J:
case rule::N:
return x.n_ == y.n_;
case rule::M:
return x.m_ == y.m_ && x.n_ == y.n_ && x.wd_ == y.wd_;
default:
return true;
}
}
inline
bool
operator!=(const rule& x, const rule& y)
{
return !(x == y);
}
inline
date::local_seconds
rule::operator()(date::year y) const
{
using date::local_days;
using date::January;
using date::days;
using date::last;
using sec = std::chrono::seconds;
date::local_seconds t;
switch (mode_)
{
case J:
t = local_days{y/January/0} + days{n_ + (y.is_leap() && n_ > 59)} + sec{time_};
break;
case M:
t = (n_ == 5 ? local_days{y/m_/wd_[last]} : local_days{y/m_/wd_[n_]}) + sec{time_};
break;
case N:
t = local_days{y/January/1} + days{n_} + sec{time_};
break;
default:
assert(!"rule called with bad mode");
}
return t;
}
inline
std::string
rule::to_string() const
{
using namespace std::chrono;
auto print_offset = [](seconds off)
{
std::string nm;
if (off != hours{2})
{
date::hh_mm_ss<seconds> offset{off};
nm = '/';
nm += std::to_string(offset.hours().count());
if (offset.minutes() != minutes{0} || offset.seconds() != seconds{0})
{
nm += ':';
if (offset.minutes() < minutes{10})
nm += '0';
nm += std::to_string(offset.minutes().count());
if (offset.seconds() != seconds{0})
{
nm += ':';
if (offset.seconds() < seconds{10})
nm += '0';
nm += std::to_string(offset.seconds().count());
}
}
}
return nm;
};
std::string nm;
switch (mode_)
{
case rule::J:
nm = 'J';
nm += std::to_string(n_);
break;
case rule::M:
nm = 'M';
nm += std::to_string(static_cast<unsigned>(m_));
nm += '.';
nm += std::to_string(n_);
nm += '.';
nm += std::to_string(wd_.c_encoding());
break;
case rule::N:
nm = std::to_string(n_);
break;
default:
break;
}
nm += print_offset(time_);
return nm;
}
inline
std::ostream&
operator<<(std::ostream& os, const rule& r)
{
switch (r.mode_)
{
case rule::J:
os << 'J' << r.n_ << date::format(" %T", r.time_);
break;
case rule::M:
if (r.n_ == 5)
os << r.m_/r.wd_[date::last];
else
os << r.m_/r.wd_[r.n_];
os << date::format(" %T", r.time_);
break;
case rule::N:
os << r.n_ << date::format(" %T", r.time_);
break;
default:
break;
}
return os;
}
} // namespace detail
class time_zone
{
std::string std_abbrev_;
std::string dst_abbrev_ = {};
std::chrono::seconds offset_;
std::chrono::seconds save_ = std::chrono::hours{1};
detail::rule start_rule_;
detail::rule end_rule_;
public:
explicit time_zone(const detail::string_t& name);
template <class Duration>
date::sys_info get_info(date::sys_time<Duration> st) const;
template <class Duration>
date::local_info get_info(date::local_time<Duration> tp) const;
template <class Duration>
date::sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys(date::local_time<Duration> tp) const;
template <class Duration>
date::sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_sys(date::local_time<Duration> tp, date::choose z) const;
template <class Duration>
date::local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
to_local(date::sys_time<Duration> tp) const;
friend std::ostream& operator<<(std::ostream& os, const time_zone& z);
const time_zone* operator->() const {return this;}
std::string name() const;
friend bool operator==(const time_zone& x, const time_zone& y);
private:
date::sys_seconds get_start(date::year y) const;
date::sys_seconds get_prev_start(date::year y) const;
date::sys_seconds get_next_start(date::year y) const;
date::sys_seconds get_end(date::year y) const;
date::sys_seconds get_prev_end(date::year y) const;
date::sys_seconds get_next_end(date::year y) const;
date::sys_info contant_offset() const;
};
inline
date::sys_seconds
time_zone::get_start(date::year y) const
{
return date::sys_seconds{(start_rule_(y) - offset_).time_since_epoch()};
}
inline
date::sys_seconds
time_zone::get_prev_start(date::year y) const
{
return date::sys_seconds{(start_rule_(--y) - offset_).time_since_epoch()};
}
inline
date::sys_seconds
time_zone::get_next_start(date::year y) const
{
return date::sys_seconds{(start_rule_(++y) - offset_).time_since_epoch()};
}
inline
date::sys_seconds
time_zone::get_end(date::year y) const
{
return date::sys_seconds{(end_rule_(y) - (offset_ + save_)).time_since_epoch()};
}
inline
date::sys_seconds
time_zone::get_prev_end(date::year y) const
{
return date::sys_seconds{(end_rule_(--y) - (offset_ + save_)).time_since_epoch()};
}
inline
date::sys_seconds
time_zone::get_next_end(date::year y) const
{
return date::sys_seconds{(end_rule_(++y) - (offset_ + save_)).time_since_epoch()};
}
date::sys_info
time_zone::contant_offset() const
{
using date::year;
using date::sys_info;
using date::sys_days;
using date::January;
using date::December;
using date::last;
sys_info r;
r.begin = sys_days{year::min()/January/1};
r.end = sys_days{year::max()/December/last};
r.abbrev = std_abbrev_;
r.offset = offset_;
return r;
}
inline
time_zone::time_zone(const detail::string_t& s)
{
using detail::read_name;
using detail::read_signed_time;
using detail::throw_invalid;
auto i = read_name(s, 0, std_abbrev_);
i = read_signed_time(s, i, offset_);
offset_ = -offset_;
if (i != s.size())
{
i = read_name(s, i, dst_abbrev_);
if (i != s.size())
{
if (s[i] != ',')
{
i = read_signed_time(s, i, save_);
save_ = -save_ - offset_;
}
if (i != s.size())
{
if (s[i] != ',')
throw_invalid(s, i, "Expecting end of string or ',' to start rule");
++i;
i = read_date(s, i, start_rule_);
if (i == s.size() || s[i] != ',')
throw_invalid(s, i, "Expecting ',' and then the ending rule");
++i;
i = read_date(s, i, end_rule_);
if (i != s.size())
throw_invalid(s, i, "Found unexpected trailing characters");
}
}
}
}
template <class Duration>
date::sys_info
time_zone::get_info(date::sys_time<Duration> st) const
{
using date::sys_info;
using date::year_month_day;
using date::sys_days;
using date::floor;
using date::ceil;
using date::days;
using date::year;
using date::January;
using date::December;
using date::last;
using std::chrono::minutes;
sys_info r{};
r.offset = offset_;
if (start_rule_.ok())
{
auto y = year_month_day{floor<days>(st)}.year();
auto start = get_start(y);
auto end = get_end(y);
if (start <= end) // (northern hemisphere)
{
if (start <= st && st < end)
{
r.begin = start;
r.end = end;
r.offset += save_;
r.save = ceil<minutes>(save_);
r.abbrev = dst_abbrev_;
}
else if (st < start)
{
r.begin = get_prev_end(y);
r.end = start;
r.abbrev = std_abbrev_;
}
else // st >= end
{
r.begin = end;
r.end = get_next_start(y);
r.abbrev = std_abbrev_;
}
}
else // end < start (southern hemisphere)
{
if (end <= st && st < start)
{
r.begin = end;
r.end = start;
r.abbrev = std_abbrev_;
}
else if (st < end)
{
r.begin = get_prev_start(y);
r.end = end;
r.offset += save_;
r.save = ceil<minutes>(save_);
r.abbrev = dst_abbrev_;
}
else // st >= start
{
r.begin = start;
r.end = get_next_end(y);
r.offset += save_;
r.save = ceil<minutes>(save_);
r.abbrev = dst_abbrev_;
}
}
}
else
r = contant_offset();
return r;
}
template <class Duration>
date::local_info
time_zone::get_info(date::local_time<Duration> tp) const
{
using date::local_info;
using date::year_month_day;
using date::days;
using date::sys_days;
using date::sys_seconds;
using date::year;
using date::ceil;
using date::January;
using date::December;
using date::last;
using std::chrono::seconds;
using std::chrono::minutes;
local_info r{};
using date::floor;
if (start_rule_.ok())
{
auto y = year_month_day{floor<days>(tp)}.year();
auto start = get_start(y);
auto end = get_end(y);
auto utcs = sys_seconds{floor<seconds>(tp - offset_).time_since_epoch()};
auto utcd = sys_seconds{floor<seconds>(tp - (offset_ + save_)).time_since_epoch()};
auto northern = start <= end;
if ((utcs < start) != (utcd < start))
{
if (northern)
r.first.begin = get_prev_end(y);
else
r.first.begin = end;
r.first.end = start;
r.first.offset = offset_;
r.first.abbrev = std_abbrev_;
r.second.begin = start;
if (northern)
r.second.end = end;
else
r.second.end = get_next_end(y);
r.second.abbrev = dst_abbrev_;
r.second.offset = offset_ + save_;
r.second.save = ceil<minutes>(save_);
r.result = save_ > seconds{0} ? local_info::nonexistent
: local_info::ambiguous;
}
else if ((utcs < end) != (utcd < end))
{
if (northern)
r.first.begin = start;
else
r.first.begin = get_prev_start(y);
r.first.end = end;
r.first.offset = offset_ + save_;
r.first.save = ceil<minutes>(save_);
r.first.abbrev = dst_abbrev_;
r.second.begin = end;
if (northern)
r.second.end = get_next_start(y);
else
r.second.end = start;
r.second.abbrev = std_abbrev_;
r.second.offset = offset_;
r.result = save_ > seconds{0} ? local_info::ambiguous
: local_info::nonexistent;
}
else
r.first = get_info(utcs);
}
else
r.first = contant_offset();
return r;
}
template <class Duration>
date::sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
time_zone::to_sys(date::local_time<Duration> tp) const
{
using date::local_info;
using date::sys_time;
using date::ambiguous_local_time;
using date::nonexistent_local_time;
auto i = get_info(tp);
if (i.result == local_info::nonexistent)
throw nonexistent_local_time(tp, i);
else if (i.result == local_info::ambiguous)
throw ambiguous_local_time(tp, i);
return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
}
template <class Duration>
date::sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
time_zone::to_sys(date::local_time<Duration> tp, date::choose z) const
{
using date::local_info;
using date::sys_time;
using date::choose;
auto i = get_info(tp);
if (i.result == local_info::nonexistent)
{
return i.first.end;
}
else if (i.result == local_info::ambiguous)
{
if (z == choose::latest)
return sys_time<Duration>{tp.time_since_epoch()} - i.second.offset;
}
return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
}
template <class Duration>
date::local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
time_zone::to_local(date::sys_time<Duration> tp) const
{
using date::local_time;
using std::chrono::seconds;
using LT = local_time<typename std::common_type<Duration, seconds>::type>;
auto i = get_info(tp);
return LT{(tp + i.offset).time_since_epoch()};
}
inline
std::ostream&
operator<<(std::ostream& os, const time_zone& z)
{
using date::operator<<;
os << '{';
os << z.std_abbrev_ << ", " << z.dst_abbrev_ << date::format(", %T, ", z.offset_)
<< date::format("%T, [", z.save_) << z.start_rule_ << ", " << z.end_rule_ << ")}";
return os;
}
inline
std::string
time_zone::name() const
{
using namespace date;
using namespace std::chrono;
auto nm = std_abbrev_;
auto print_offset = [](seconds off)
{
std::string nm;
hh_mm_ss<seconds> offset{-off};
if (offset.is_negative())
nm += '-';
nm += std::to_string(offset.hours().count());
if (offset.minutes() != minutes{0} || offset.seconds() != seconds{0})
{
nm += ':';
if (offset.minutes() < minutes{10})
nm += '0';
nm += std::to_string(offset.minutes().count());
if (offset.seconds() != seconds{0})
{
nm += ':';
if (offset.seconds() < seconds{10})
nm += '0';
nm += std::to_string(offset.seconds().count());
}
}
return nm;
};
nm += print_offset(offset_);
if (!dst_abbrev_.empty())
{
nm += dst_abbrev_;
if (save_ != hours{1})
nm += print_offset(offset_+save_);
if (start_rule_.ok())
{
nm += ',';
nm += start_rule_.to_string();
nm += ',';
nm += end_rule_.to_string();
}
}
return nm;
}
inline
bool
operator==(const time_zone& x, const time_zone& y)
{
return x.std_abbrev_ == y.std_abbrev_ &&
x.dst_abbrev_ == y. dst_abbrev_ &&
x.offset_ == y.offset_ &&
x.save_ == y.save_ &&
x.start_rule_ == y.start_rule_ &&
x.end_rule_ == y.end_rule_;
}
inline
bool
operator!=(const time_zone& x, const time_zone& y)
{
return !(x == y);
}
namespace detail
{
inline
void
throw_invalid(const string_t& s, unsigned i, const string_t& message)
{
throw std::runtime_error(std::string("Invalid time_zone initializer.\n") +
std::string(message) + ":\n" +
std::string(s) + '\n' +
"\x1b[1;32m" +
std::string(i, '~') + '^' +
std::string(i < s.size() ? s.size()-i-1 : 0, '~') +
"\x1b[0m");
}
inline
unsigned
read_date(const string_t& s, unsigned i, rule& r)
{
using date::month;
using date::weekday;
if (i == s.size())
throw_invalid(s, i, "Expected rule but found end of string");
if (s[i] == 'J')
{
++i;
unsigned n;
i = read_unsigned(s, i, 3, n, "Expected to find the Julian day [1, 365]");
r.mode_ = rule::J;
r.n_ = n;
}
else if (s[i] == 'M')
{
++i;
unsigned m;
i = read_unsigned(s, i, 2, m, "Expected to find month [1, 12]");
if (i == s.size() || s[i] != '.')
throw_invalid(s, i, "Expected '.' after month");
++i;
unsigned n;
i = read_unsigned(s, i, 1, n, "Expected to find week number [1, 5]");
if (i == s.size() || s[i] != '.')
throw_invalid(s, i, "Expected '.' after weekday index");
++i;
unsigned wd;
i = read_unsigned(s, i, 1, wd, "Expected to find day of week [0, 6]");
r.mode_ = rule::M;
r.m_ = month{m};
r.wd_ = weekday{wd};
r.n_ = n;
}
else if (std::isdigit(s[i]))
{
unsigned n;
i = read_unsigned(s, i, 3, n);
r.mode_ = rule::N;
r.n_ = n;
}
else
throw_invalid(s, i, "Expected 'J', 'M', or a digit to start rule");
if (i != s.size() && s[i] == '/')
{
++i;
std::chrono::seconds t;
i = read_unsigned_time(s, i, t);
r.time_ = t;
}
return i;
}
inline
unsigned
read_name(const string_t& s, unsigned i, std::string& name)
{
if (i == s.size())
throw_invalid(s, i, "Expected a name but found end of string");
if (s[i] == '<')
{
++i;
while (true)
{
if (i == s.size())
throw_invalid(s, i,
"Expected to find closing '>', but found end of string");
if (s[i] == '>')
break;
name.push_back(s[i]);
++i;
}
++i;
}
else
{
while (i != s.size() && std::isalpha(s[i]))
{
name.push_back(s[i]);
++i;
}
}
if (name.size() < 3)
throw_invalid(s, i, "Found name to be shorter than 3 characters");
return i;
}
inline
unsigned
read_signed_time(const string_t& s, unsigned i,
std::chrono::seconds& t)
{
if (i == s.size())
throw_invalid(s, i, "Expected to read signed time, but found end of string");
bool negative = false;
if (s[i] == '-')
{
negative = true;
++i;
}
else if (s[i] == '+')
++i;
i = read_unsigned_time(s, i, t);
if (negative)
t = -t;
return i;
}
inline
unsigned
read_unsigned_time(const string_t& s, unsigned i, std::chrono::seconds& t)
{
using std::chrono::seconds;
using std::chrono::minutes;
using std::chrono::hours;
if (i == s.size())
throw_invalid(s, i, "Expected to read unsigned time, but found end of string");
unsigned x;
i = read_unsigned(s, i, 2, x, "Expected to find hours [0, 24]");
t = hours{x};
if (i != s.size() && s[i] == ':')
{
++i;
i = read_unsigned(s, i, 2, x, "Expected to find minutes [0, 59]");
t += minutes{x};
if (i != s.size() && s[i] == ':')
{
++i;
i = read_unsigned(s, i, 2, x, "Expected to find seconds [0, 59]");
t += seconds{x};
}
}
return i;
}
inline
unsigned
read_unsigned(const string_t& s, unsigned i, unsigned limit, unsigned& u,
const string_t& message)
{
if (i == s.size() || !std::isdigit(s[i]))
throw_invalid(s, i, message);
u = static_cast<unsigned>(s[i] - '0');
unsigned count = 1;
for (++i; count < limit && i != s.size() && std::isdigit(s[i]); ++i, ++count)
u = u * 10 + static_cast<unsigned>(s[i] - '0');
return i;
}
} // namespace detail
} // namespace Posix
namespace date
{
template <>
struct zoned_traits<Posix::time_zone>
{
#if HAS_STRING_VIEW
static
Posix::time_zone
locate_zone(std::string_view name)
{
return Posix::time_zone{name};
}
#else // !HAS_STRING_VIEW
static
Posix::time_zone
locate_zone(const std::string& name)
{
return Posix::time_zone{name};
}
static
Posix::time_zone
locate_zone(const char* name)
{
return Posix::time_zone{name};
}
#endif // !HAS_STRING_VIEW
};
} // namespace date
#endif // PTZ_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,316 @@
#ifndef TZ_PRIVATE_H
#define TZ_PRIVATE_H
// The MIT License (MIT)
//
// Copyright (c) 2015, 2016 Howard Hinnant
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Our apologies. When the previous paragraph was written, lowercase had not yet
// been invented (that would involve another several millennia of evolution).
// We did not mean to shout.
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
#include "tz.h"
#else
#include "date.h"
#include <vector>
#endif
namespace date
{
namespace detail
{
#if !USE_OS_TZDB
enum class tz {utc, local, standard};
//forward declare to avoid warnings in gcc 6.2
class MonthDayTime;
std::istream& operator>>(std::istream& is, MonthDayTime& x);
std::ostream& operator<<(std::ostream& os, const MonthDayTime& x);
class MonthDayTime
{
private:
struct pair
{
#if defined(_MSC_VER) && (_MSC_VER < 1900)
pair() : month_day_(date::jan / 1), weekday_(0U) {}
pair(const date::month_day& month_day, const date::weekday& weekday)
: month_day_(month_day), weekday_(weekday) {}
#endif
date::month_day month_day_;
date::weekday weekday_;
};
enum Type {month_day, month_last_dow, lteq, gteq};
Type type_{month_day};
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
union U
#else
struct U
#endif
{
date::month_day month_day_;
date::month_weekday_last month_weekday_last_;
pair month_day_weekday_;
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
U() : month_day_{date::jan/1} {}
#else
U() :
month_day_(date::jan/1),
month_weekday_last_(date::month(0U), date::weekday_last(date::weekday(0U)))
{}
#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
U& operator=(const date::month_day& x);
U& operator=(const date::month_weekday_last& x);
U& operator=(const pair& x);
} u;
std::chrono::hours h_{0};
std::chrono::minutes m_{0};
std::chrono::seconds s_{0};
tz zone_{tz::local};
public:
MonthDayTime() = default;
MonthDayTime(local_seconds tp, tz timezone);
MonthDayTime(const date::month_day& md, tz timezone);
date::day day() const;
date::month month() const;
tz zone() const {return zone_;}
void canonicalize(date::year y);
sys_seconds
to_sys(date::year y, std::chrono::seconds offset, std::chrono::seconds save) const;
sys_days to_sys_days(date::year y) const;
sys_seconds to_time_point(date::year y) const;
int compare(date::year y, const MonthDayTime& x, date::year yx,
std::chrono::seconds offset, std::chrono::minutes prev_save) const;
friend std::istream& operator>>(std::istream& is, MonthDayTime& x);
friend std::ostream& operator<<(std::ostream& os, const MonthDayTime& x);
};
// A Rule specifies one or more set of datetimes without using an offset.
// Multiple dates are specified with multiple years. The years in effect
// go from starting_year_ to ending_year_, inclusive. starting_year_ <=
// ending_year_. save_ is in effect for times from the specified time
// onward, including the specified time. When the specified time is
// local, it uses the save_ from the chronologically previous Rule, or if
// there is none, 0.
//forward declare to avoid warnings in gcc 6.2
class Rule;
bool operator==(const Rule& x, const Rule& y);
bool operator<(const Rule& x, const Rule& y);
bool operator==(const Rule& x, const date::year& y);
bool operator<(const Rule& x, const date::year& y);
bool operator==(const date::year& x, const Rule& y);
bool operator<(const date::year& x, const Rule& y);
bool operator==(const Rule& x, const std::string& y);
bool operator<(const Rule& x, const std::string& y);
bool operator==(const std::string& x, const Rule& y);
bool operator<(const std::string& x, const Rule& y);
std::ostream& operator<<(std::ostream& os, const Rule& r);
class Rule
{
private:
std::string name_;
date::year starting_year_{0};
date::year ending_year_{0};
MonthDayTime starting_at_;
std::chrono::minutes save_{0};
std::string abbrev_;
public:
Rule() = default;
explicit Rule(const std::string& s);
Rule(const Rule& r, date::year starting_year, date::year ending_year);
const std::string& name() const {return name_;}
const std::string& abbrev() const {return abbrev_;}
const MonthDayTime& mdt() const {return starting_at_;}
const date::year& starting_year() const {return starting_year_;}
const date::year& ending_year() const {return ending_year_;}
const std::chrono::minutes& save() const {return save_;}
static void split_overlaps(std::vector<Rule>& rules);
friend bool operator==(const Rule& x, const Rule& y);
friend bool operator<(const Rule& x, const Rule& y);
friend bool operator==(const Rule& x, const date::year& y);
friend bool operator<(const Rule& x, const date::year& y);
friend bool operator==(const date::year& x, const Rule& y);
friend bool operator<(const date::year& x, const Rule& y);
friend bool operator==(const Rule& x, const std::string& y);
friend bool operator<(const Rule& x, const std::string& y);
friend bool operator==(const std::string& x, const Rule& y);
friend bool operator<(const std::string& x, const Rule& y);
friend std::ostream& operator<<(std::ostream& os, const Rule& r);
private:
date::day day() const;
date::month month() const;
static void split_overlaps(std::vector<Rule>& rules, std::size_t i, std::size_t& e);
static bool overlaps(const Rule& x, const Rule& y);
static void split(std::vector<Rule>& rules, std::size_t i, std::size_t k,
std::size_t& e);
};
inline bool operator!=(const Rule& x, const Rule& y) {return !(x == y);}
inline bool operator> (const Rule& x, const Rule& y) {return y < x;}
inline bool operator<=(const Rule& x, const Rule& y) {return !(y < x);}
inline bool operator>=(const Rule& x, const Rule& y) {return !(x < y);}
inline bool operator!=(const Rule& x, const date::year& y) {return !(x == y);}
inline bool operator> (const Rule& x, const date::year& y) {return y < x;}
inline bool operator<=(const Rule& x, const date::year& y) {return !(y < x);}
inline bool operator>=(const Rule& x, const date::year& y) {return !(x < y);}
inline bool operator!=(const date::year& x, const Rule& y) {return !(x == y);}
inline bool operator> (const date::year& x, const Rule& y) {return y < x;}
inline bool operator<=(const date::year& x, const Rule& y) {return !(y < x);}
inline bool operator>=(const date::year& x, const Rule& y) {return !(x < y);}
inline bool operator!=(const Rule& x, const std::string& y) {return !(x == y);}
inline bool operator> (const Rule& x, const std::string& y) {return y < x;}
inline bool operator<=(const Rule& x, const std::string& y) {return !(y < x);}
inline bool operator>=(const Rule& x, const std::string& y) {return !(x < y);}
inline bool operator!=(const std::string& x, const Rule& y) {return !(x == y);}
inline bool operator> (const std::string& x, const Rule& y) {return y < x;}
inline bool operator<=(const std::string& x, const Rule& y) {return !(y < x);}
inline bool operator>=(const std::string& x, const Rule& y) {return !(x < y);}
struct zonelet
{
enum tag {has_rule, has_save, is_empty};
std::chrono::seconds gmtoff_;
tag tag_ = has_rule;
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
union U
#else
struct U
#endif
{
std::string rule_;
std::chrono::minutes save_;
~U() {}
U() {}
U(const U&) {}
U& operator=(const U&) = delete;
} u;
std::string format_;
date::year until_year_{0};
MonthDayTime until_date_;
sys_seconds until_utc_;
local_seconds until_std_;
local_seconds until_loc_;
std::chrono::minutes initial_save_{0};
std::string initial_abbrev_;
std::pair<const Rule*, date::year> first_rule_{nullptr, date::year::min()};
std::pair<const Rule*, date::year> last_rule_{nullptr, date::year::max()};
~zonelet();
zonelet();
zonelet(const zonelet& i);
zonelet& operator=(const zonelet&) = delete;
};
#else // USE_OS_TZDB
struct ttinfo
{
std::int32_t tt_gmtoff;
unsigned char tt_isdst;
unsigned char tt_abbrind;
unsigned char pad[2];
};
static_assert(sizeof(ttinfo) == 8, "");
struct expanded_ttinfo
{
std::chrono::seconds offset;
std::string abbrev;
bool is_dst;
};
struct transition
{
sys_seconds timepoint;
const expanded_ttinfo* info;
transition(sys_seconds tp, const expanded_ttinfo* i = nullptr)
: timepoint(tp)
, info(i)
{}
friend
std::ostream&
operator<<(std::ostream& os, const transition& t)
{
using date::operator<<;
os << t.timepoint << "Z ";
if (t.info->offset >= std::chrono::seconds{0})
os << '+';
os << make_time(t.info->offset);
if (t.info->is_dst > 0)
os << " daylight ";
else
os << " standard ";
os << t.info->abbrev;
return os;
}
};
#endif // USE_OS_TZDB
} // namespace detail
} // namespace date
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#include "tz.h"
#endif
#endif // TZ_PRIVATE_H

@ -0,0 +1,19 @@
noinst_HEADERS = \
../include/date/tz_private.h \
../include/date/ios.h \
../include/date/ptz.h \
../include/date/solar_hijri.h \
../include/date/date.h \
../include/date/julian.h \
../include/date/chrono_io.h \
../include/date/iso_week.h \
../include/date/tz.h \
../include/date/islamic.h
noinst_LIBRARIES = libdatepp.a
AM_CPPFLAGS = -I$(srcdir)/../include
libdatepp_a_SOURCES = \
tz.cpp

@ -34,9 +34,12 @@
#include <string.h>
#include "base/attr_line.builder.hh"
#include "base/date_time_scanner.hh"
#include "base/humanize.time.hh"
#include "config.h"
#include "date/tz.h"
#include "ptimec.hh"
#include "relative_time.hh"
#include "sql_util.hh"
#include "vtab_module.hh"
@ -185,6 +188,74 @@ sql_humanize_duration(double value)
return humanize::time::duration::from_tv(tv).to_string();
}
static nonstd::optional<std::string>
sql_timezone(std::string tz_str, string_fragment ts_str)
{
thread_local date_time_scanner dts;
struct timeval tv;
exttm tm1;
auto scan_end
= dts.scan(ts_str.data(), ts_str.length(), nullptr, &tm1, tv, false);
if (scan_end == nullptr) {
auto um = lnav::console::user_message::error(
attr_line_t("unrecognized timestamp: ").append(ts_str));
throw um;
}
size_t matched_size = scan_end - ts_str.data();
auto ts_remaining = ts_str.substr(matched_size);
if (!ts_remaining.empty()) {
auto um
= lnav::console::user_message::error(
attr_line_t("invalid timestamp: ").append(ts_str))
.with_reason(attr_line_t("the leading part of the timestamp "
"was matched, however, the trailing "
"text ")
.append_quoted(ts_remaining)
.append(" was not"))
.with_note(attr_line_t("input matched time format ")
.append_quoted(
PTIMEC_FORMATS[dts.dts_fmt_lock].pf_fmt))
.with_help("fix the timestamp or remove the trailing text");
auto ts_attr = attr_line_t().append(ts_str);
attr_line_builder alb(ts_attr);
alb.append("\n").append(matched_size, ' ');
{
auto attr_guard = alb.with_attr(VC_ROLE.value(role_t::VCR_COMMENT));
alb.append("^");
if (ts_remaining.length() > 1) {
if (ts_remaining.length() > 2) {
alb.append(ts_remaining.length() - 2, '-');
}
alb.append("^");
}
alb.append(" unrecognized input");
}
log_debug("wtf %s", ts_attr.get_string().c_str());
um.with_note(ts_attr);
throw um;
}
thread_local std::string last_tz;
thread_local const date::time_zone* tz;
if (tz_str != last_tz) {
tz = date::locate_zone(tz_str);
}
auto stime = std::chrono::time_point_cast<std::chrono::microseconds>(
std::chrono::system_clock::from_time_t(tv.tv_sec));
stime += std::chrono::microseconds{tv.tv_usec};
auto ztime = date::make_zoned(tz, stime);
auto retval = date::format("%FT%T%z", ztime);
return retval;
}
int
time_extension_functions(struct FuncDef** basic_funcs,
struct FuncDefAgg** agg_funcs)
@ -255,6 +326,18 @@ time_extension_functions(struct FuncDef** basic_funcs,
"SELECT humanize_duration(1.5)",
})),
sqlite_func_adapter<decltype(&sql_timezone), sql_timezone>::builder(
help_text("timezone", "Convert a timestamp to the given timezone")
.sql_function()
.with_parameter({"tz", "The target timezone"})
.with_parameter({"ts", "The source timestamp"})
.with_tags({"datetime", "string"})
.with_example({
"To convert a time to America/Los_Angeles",
"SELECT timezone('America/Los_Angeles', "
"'2022-03-02T10:00')",
})),
{nullptr},
};

@ -113,6 +113,7 @@ LDADD = \
$(top_builddir)/src/base/libbase.a \
$(top_builddir)/src/pugixml/libpugixml.a \
$(top_builddir)/src/third-party/base64/lib/libbase64.a \
$(top_builddir)/src/third-party/date/src/libdatepp.a \
$(top_builddir)/src/third-party/scnlib/src/libscnlib.a \
$(READLINE_LIBS) \
$(CURSES_LIB) \

@ -1072,12 +1072,16 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_sql_time_func.sh_4035ee76938269e9247f9a696927a9ac18cce80a.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_42f0fc1a154b0d79b4f6e846f283426be498040f.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_42f0fc1a154b0d79b4f6e846f283426be498040f.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_4364c7f5354fe108874dd22571115e012303e001.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_4364c7f5354fe108874dd22571115e012303e001.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_4b96fe71bc2d18955e3625b765a6095ab1f7a75d.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_4b96fe71bc2d18955e3625b765a6095ab1f7a75d.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_53b76b094e47691b5bca106142ee470e82e8e420.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_53b76b094e47691b5bca106142ee470e82e8e420.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_6288a9e690d381602b2be5665cc1cd3552733bc2.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_6288a9e690d381602b2be5665cc1cd3552733bc2.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_63f22db8689c238d51c9b9efe9837147ea5318e6.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_63f22db8689c238d51c9b9efe9837147ea5318e6.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_652bbd00b5159e22d94970ab1e882997d14b5777.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_652bbd00b5159e22d94970ab1e882997d14b5777.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_6832a58259168622af8b3370b0c89534f98f3f9f.err \
@ -1086,14 +1090,24 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_sql_time_func.sh_72862ec9c8f261a8507d237eb673c7ddfaafd898.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_7797302b63d73234c9ec9f0405c7c0a748daf8e9.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_7797302b63d73234c9ec9f0405c7c0a748daf8e9.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_7ae9dbbb69dbc50ee6a34afc03d2579f09363068.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_7ae9dbbb69dbc50ee6a34afc03d2579f09363068.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_9569ab40cb2e51c60f818a6c2729c60d86565e7e.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_9569ab40cb2e51c60f818a6c2729c60d86565e7e.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_9e649c4bc10f4d178519983358f7092e9c5dfe71.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_9e649c4bc10f4d178519983358f7092e9c5dfe71.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_b0257ced663fc444801a5e6cba89c3053acca11e.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_b0257ced663fc444801a5e6cba89c3053acca11e.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_b3c00f049fdeb551a9165c281630e36359832d1f.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_b3c00f049fdeb551a9165c281630e36359832d1f.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_b5f9ec3ea8b4551fd40017398d74c524fb54ebc9.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_b5f9ec3ea8b4551fd40017398d74c524fb54ebc9.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_c1d7dc8a4bd3b8cb86a2f893f58a56f0f6ea1bc3.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_c1d7dc8a4bd3b8cb86a2f893f58a56f0f6ea1bc3.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_c5a5fc2edb54d10f1475afa7fed0b62bc05e1dc6.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_c5a5fc2edb54d10f1475afa7fed0b62bc05e1dc6.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_c7fc60392a2e52b163da1e1dde6978c16f415a9e.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_c7fc60392a2e52b163da1e1dde6978c16f415a9e.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_dbe786c096d5a7a5e1d05311b929f1427d8bac79.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_dbe786c096d5a7a5e1d05311b929f1427d8bac79.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_f3b1ea49779117bf45f85ad5615fdc5e89193db6.err \

@ -820,6 +820,13 @@ For support questions, email:
:convert-time-to zone
══════════════════════════════════════════════════════════════════════
Convert the focused timestamp to the given timezone
Parameter
zone The timezone name
:create-logline-table table-name
══════════════════════════════════════════════════════════════════════
Create an SQL table using the top line of the log view as a
@ -1903,8 +1910,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Example
#1 To anonymize an IP address:
;SELECT anonymize('Hello, 192.168.1.2') 
@ -2094,8 +2101,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Example
#1 To get a string with the code points 0x48 and 0x49:
;SELECT char(0x48, 0x49) 
@ -2120,8 +2127,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To search for the string 'abc' within 'abcabc' and starting at position 2:
;SELECT charindex('abc', 'abcabc', 2) 
@ -2179,7 +2186,7 @@ For support questions, email:
value to the left.
See Also
datetime(), humanize_duration(), julianday(), strftime(), time(),
timediff(), timeslice()
timediff(), timeslice(), timezone()
Examples
#1 To get the date portion of the timestamp '2017-01-02T03:04:05':
;SELECT date('2017-01-02T03:04:05') 
@ -2204,7 +2211,7 @@ For support questions, email:
value to the left.
See Also
date(), humanize_duration(), julianday(), strftime(), time(),
timediff(), timeslice()
timediff(), timeslice(), timezone()
Examples
#1 To get the date and time portion of the timestamp '2017-01-02T03:04:05':
;SELECT datetime('2017-01-02T03:04:05') 
@ -2235,8 +2242,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Example
#1 To decode the URI-encoded string '%63%75%72%6c':
;SELECT decode('%63%75%72%6c', 'uri') 
@ -2321,8 +2328,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To base64-encode 'Hello, World!':
;SELECT encode('Hello, World!', 'base64') 
@ -2351,8 +2358,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To test if the string 'notbad.jpg' ends with '.jpg':
;SELECT endswith('notbad.jpg', '.jpg') 
@ -2392,8 +2399,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To extract key/value pairs from a string:
;SELECT extract('foo=1 bar=2 name="Rolo Tomassi"') 
@ -2544,7 +2551,8 @@ For support questions, email:
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(),
substr(), trim(), unicode(), unparse_url(), upper(), xpath()
substr(), timezone(), trim(), unicode(), unparse_url(), upper(),
xpath()
Examples
#1 To concatenate the values of the column 'ex_procname' from the table
'lnav_example_log':
@ -2574,7 +2582,8 @@ For support questions, email:
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(),
substr(), trim(), unicode(), unparse_url(), upper(), xpath()
substr(), timezone(), trim(), unicode(), unparse_url(), upper(),
xpath()
Example
#1 To produce a hash of all of the values of 'column1':
;SELECT group_spooky_hash(column1) FROM (VALUES ('abc'), ('123'))
@ -2594,8 +2603,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
gzip(value, ...)
══════════════════════════════════════════════════════════════════════
@ -2610,8 +2619,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
hex(X)
══════════════════════════════════════════════════════════════════════
@ -2640,8 +2649,8 @@ For support questions, email:
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), strftime(), substr(), time(),
timediff(), timeslice(), trim(), unicode(), unparse_url(), upper(),
xpath()
timediff(), timeslice(), timezone(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Examples
#1 To format a duration:
;SELECT humanize_duration(15 * 60) 
@ -2665,7 +2674,8 @@ For support questions, email:
proper(), regexp_capture(), regexp_capture_into_json(), regexp_match(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(),
substr(), trim(), unicode(), unparse_url(), upper(), xpath()
substr(), timezone(), trim(), unicode(), unparse_url(), upper(),
xpath()
Example
#1 To format an amount:
;SELECT humanize_file_size(10 * 1024 * 1024) 
@ -2702,8 +2712,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Example
#1 To test get the position of 'b' in the string 'abc':
;SELECT instr('abc', 'b') 
@ -3205,7 +3215,7 @@ For support questions, email:
value to the left.
See Also
date(), datetime(), humanize_duration(), strftime(), time(),
timediff(), timeslice()
timediff(), timeslice(), timezone()
Examples
#1 To get the julian day from the timestamp '2017-01-02T03:04:05':
;SELECT julianday('2017-01-02T03:04:05') 
@ -3280,8 +3290,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Examples
#1 To get the first character of the string 'abc':
;SELECT leftstr('abc', 1) 
@ -3306,8 +3316,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Example
#1 To get the length of the string 'abc':
;SELECT length('abc') 
@ -3427,8 +3437,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Example
#1 To extract key/value pairs from a log message:
;SELECT logfmt2json('foo=1 bar=2 name="Rolo Tomassi"')
@ -3449,8 +3459,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Example
#1 To lowercase the string 'AbC':
;SELECT lower('AbC') 
@ -3472,8 +3482,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Examples
#1 To trim the leading space characters from the string ' abc':
;SELECT ltrim(' abc') 
@ -3581,8 +3591,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Examples
#1 To pad the string 'abc' to a length of six characters:
;SELECT padc('abc', 6) || 'def' 
@ -3608,8 +3618,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Examples
#1 To pad the string 'abc' to a length of six characters:
;SELECT padl('abc', 6) 
@ -3635,8 +3645,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Examples
#1 To pad the string 'abc' to a length of six characters:
;SELECT padr('abc', 6) || 'def' 
@ -3674,8 +3684,8 @@ For support questions, email:
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), unparse_url(),
upper(), xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
unparse_url(), upper(), xpath()
Examples
#1 To parse the URL 'https://example.com/search?q=hello%20world':
;SELECT parse_url('https://example.com/search?q=hello%20world')
@ -3741,8 +3751,8 @@ For support questions, email:
parse_url(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Examples
#1 To substitute 'World' into the string 'Hello, %s!':
;SELECT printf('Hello, %s!', 'World') 
@ -3770,8 +3780,8 @@ For support questions, email:
parse_url(), printf(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Example
#1 To capitalize the words in the string 'hello, world!':
;SELECT proper('hello, world!') 
@ -3901,8 +3911,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), substr(), trim(), unicode(), unparse_url(), upper(),
xpath()
strfilter(), substr(), timezone(), trim(), unicode(), unparse_url(),
upper(), xpath()
Example
#1 To extract the key/value pairs 'a'/1 and 'b'/2 from the string 'a=1; b=2':
;SELECT * FROM regexp_capture('a=1; b=2', '(\w+)=(\d+)')
@ -3935,7 +3945,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(), regexp_match(),
regexp_replace(), replace(), replicate(), reverse(), rightstr(),
rtrim(), sparkline(), spooky_hash(), startswith(), strfilter(),
substr(), trim(), unicode(), unparse_url(), upper(), xpath()
substr(), timezone(), trim(), unicode(), unparse_url(), upper(),
xpath()
Example
#1 To extract the key/value pairs 'a'/1 and 'b'/2 from the string 'a=1; b=2':
;SELECT * FROM regexp_capture_into_json('a=1; b=2', '(\w+)=(\d+)')
@ -3957,8 +3968,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_replace(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To capture the digits from the string '123':
;SELECT regexp_match('(\d+)', '123') 
@ -3992,8 +4003,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_match(), replace(),
replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To replace the word at the start of the string 'Hello, World!' with 'Goodbye':
;SELECT regexp_replace('Hello, World!', '^(\w+)', 'Goodbye')
@ -4022,8 +4033,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To replace the string 'x' with 'z' in 'abc':
;SELECT replace('abc', 'x', 'z') 
@ -4048,8 +4059,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), reverse(), rightstr(), rtrim(), sparkline(), spooky_hash(),
startswith(), strfilter(), substr(), trim(), unicode(), unparse_url(),
upper(), xpath()
startswith(), strfilter(), substr(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Example
#1 To repeat the string 'abc' three times:
;SELECT replicate('abc', 3) 
@ -4069,8 +4080,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Example
#1 To reverse the string 'abc':
;SELECT reverse('abc') 
@ -4092,8 +4103,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rtrim(), sparkline(), spooky_hash(),
startswith(), strfilter(), substr(), trim(), unicode(), unparse_url(),
upper(), xpath()
startswith(), strfilter(), substr(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Examples
#1 To get the last character of the string 'abc':
;SELECT rightstr('abc', 1) 
@ -4160,8 +4171,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To trim the space characters from the end of the string 'abc ':
;SELECT rtrim('abc ') 
@ -4229,8 +4240,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), spooky_hash(),
startswith(), strfilter(), substr(), trim(), unicode(), unparse_url(),
upper(), xpath()
startswith(), strfilter(), substr(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Examples
#1 To get the unicode block element for the value 32 in the range of 0-128:
;SELECT sparkline(32, 128) 
@ -4254,8 +4265,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
startswith(), strfilter(), substr(), trim(), unicode(), unparse_url(),
upper(), xpath()
startswith(), strfilter(), substr(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Examples
#1 To produce a hash for the string 'Hello, World!':
;SELECT spooky_hash('Hello, World!') 
@ -4336,8 +4347,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), strfilter(), substr(), trim(), unicode(), unparse_url(),
upper(), xpath()
spooky_hash(), strfilter(), substr(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Examples
#1 To test if the string 'foobar' starts with 'foo':
;SELECT startswith('foobar', 'foo') 
@ -4363,7 +4374,7 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), substr(), trim(), unicode(),
spooky_hash(), startswith(), substr(), timezone(), trim(), unicode(),
unparse_url(), upper(), xpath()
Example
#1 To get the 'b', 'c', and 'd' characters from the string 'abcabc':
@ -4385,7 +4396,7 @@ For support questions, email:
value to the left.
See Also
date(), datetime(), humanize_duration(), julianday(), time(),
timediff(), timeslice()
timediff(), timeslice(), timezone()
Examples
#1 To get the year from the timestamp '2017-01-02T03:04:05':
;SELECT strftime('%Y', '2017-01-02T03:04:05') 
@ -4423,8 +4434,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), trim(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), timezone(), trim(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To get the substring starting at the second character until the end of the string
'abc':
@ -4473,7 +4484,7 @@ For support questions, email:
value to the left.
See Also
date(), datetime(), humanize_duration(), julianday(), strftime(),
timediff(), timeslice()
timediff(), timeslice(), timezone()
Examples
#1 To get the time portion of the timestamp '2017-01-02T03:04:05':
;SELECT time('2017-01-02T03:04:05') 
@ -4496,7 +4507,7 @@ For support questions, email:
time2 The timestamp to subtract from the first
See Also
date(), datetime(), humanize_duration(), julianday(), strftime(),
time(), timeslice()
time(), timeslice(), timezone()
Examples
#1 To get the difference between two timestamps:
;SELECT timediff('2017-02-03T04:05:06', '2017-02-03T04:05:00')
@ -4516,7 +4527,7 @@ For support questions, email:
slice The size of the time slices
See Also
date(), datetime(), humanize_duration(), julianday(), strftime(),
time(), timediff()
time(), timediff(), timezone()
Examples
#1 To get the timestamp rounded down to the start of the ten minute slice:
;SELECT timeslice('2017-01-01T05:05:00', '10m') 
@ -4533,6 +4544,29 @@ For support questions, email:
timezone(tz, ts)
══════════════════════════════════════════════════════════════════════
Convert a timestamp to the given timezone
Parameters
tz The target timezone
ts The source timestamp
See Also
anonymize(), char(), charindex(), date(), datetime(), decode(),
encode(), endswith(), extract(), group_concat(), group_spooky_hash(),
gunzip(), gzip(), humanize_duration(), humanize_duration(),
humanize_file_size(), instr(), julianday(), leftstr(), length(),
logfmt2json(), lower(), ltrim(), padc(), padl(), padr(), parse_url(),
printf(), proper(), regexp_capture(), regexp_capture_into_json(),
regexp_match(), regexp_replace(), replace(), replicate(), reverse(),
rightstr(), rtrim(), sparkline(), spooky_hash(), startswith(),
strfilter(), strftime(), substr(), time(), timediff(), timeslice(),
trim(), unicode(), unparse_url(), upper(), xpath()
Example
#1 To convert a time to America/Los_Angeles:
;SELECT timezone('America/Los_Angeles', '2022-03-02T10:00')
total(X)
══════════════════════════════════════════════════════════════════════
Returns the sum of the values in the group as a floating-point.
@ -4573,8 +4607,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), unicode(),
unparse_url(), upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(),
unicode(), unparse_url(), upper(), xpath()
Examples
#1 To trim spaces from the start and end of the string ' abc ':
;SELECT trim(' abc ') 
@ -4616,7 +4650,7 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(),
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unparse_url(), upper(), xpath()
Example
#1 To get the unicode code point for the first character of 'abc':
@ -4645,8 +4679,8 @@ For support questions, email:
parse_url(), parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
upper(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), upper(), xpath()
Example
#1 To unparse the object '{"scheme": "https", "host": "example.com"}':
;SELECT unparse_url('{"scheme": "https", "host": "example.com"}')
@ -4667,8 +4701,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), xpath()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), xpath()
Example
#1 To uppercase the string 'aBc':
;SELECT upper('aBc') 
@ -4698,8 +4732,8 @@ For support questions, email:
parse_url(), printf(), proper(), regexp_capture(),
regexp_capture_into_json(), regexp_match(), regexp_replace(),
replace(), replicate(), reverse(), rightstr(), rtrim(), sparkline(),
spooky_hash(), startswith(), strfilter(), substr(), trim(), unicode(),
unparse_url(), upper()
spooky_hash(), startswith(), strfilter(), substr(), timezone(), trim(),
unicode(), unparse_url(), upper()
Examples
#1 To select the XML nodes on the path '/abc/def':
;SELECT * FROM xpath('/abc/def', '<abc><def a="b">Hello</def><def>Bye</def></abc>')

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to readlink(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":48},{"start":17,"end":21,"type":"role","value":47},{"start":8,"end":22,"type":"role","value":61}]},"reason":{"str":"unable to stat path: non-existent-link -- No such file or directory","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to readlink(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":48},{"start":17,"end":21,"type":"role","value":47},{"start":8,"end":22,"type":"role","value":61}]},"reason":{"str":"unable to stat path: non-existent-link -- No such file or directory","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to realpath(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":48},{"start":17,"end":21,"type":"role","value":47},{"start":8,"end":22,"type":"role","value":61}]},"reason":{"str":"Could not get real path for non-existent-path -- No such file or directory","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to realpath(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":48},{"start":17,"end":21,"type":"role","value":47},{"start":8,"end":22,"type":"role","value":61}]},"reason":{"str":"Could not get real path for non-existent-path -- No such file or directory","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"invalid JSON","attrs":[]},"reason":{"str":"parse error: premature EOF\n [123, true\n (right here) ------^","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"invalid JSON","attrs":[]},"reason":{"str":"parse error: premature EOF\n [123, true\n (right here) ------^","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to json_contains(json, value) failed","attrs":[{"start":8,"end":21,"type":"role","value":48},{"start":22,"end":26,"type":"role","value":47},{"start":28,"end":33,"type":"role","value":47},{"start":8,"end":34,"type":"role","value":61}]},"reason":{"str":"parse error: premature EOF\n [\"hi\", \"bye\", \"solong]\n (right here) ------^","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to json_contains(json, value) failed","attrs":[{"start":8,"end":21,"type":"role","value":48},{"start":22,"end":26,"type":"role","value":47},{"start":28,"end":33,"type":"role","value":47},{"start":8,"end":34,"type":"role","value":61}]},"reason":{"str":"parse error: premature EOF\n [\"hi\", \"bye\", \"solong]\n (right here) ------^","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to json_concat(json, value, ...) failed","attrs":[{"start":8,"end":19,"type":"role","value":48},{"start":20,"end":24,"type":"role","value":47},{"start":26,"end":31,"type":"role","value":47},{"start":8,"end":37,"type":"role","value":61}]},"reason":{"str":"Invalid JSON: parse error: premature EOF\n [null,\n (right here) ------^","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to json_concat(json, value, ...) failed","attrs":[{"start":8,"end":19,"type":"role","value":48},{"start":20,"end":24,"type":"role","value":47},{"start":26,"end":31,"type":"role","value":47},{"start":8,"end":37,"type":"role","value":61}]},"reason":{"str":"Invalid JSON: parse error: premature EOF\n [null,\n (right here) ------^","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"invalid JSON","attrs":[]},"reason":{"str":"parse error: premature EOF\n [null, true, 20, 30, 40\n (right here) ------^","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"invalid JSON","attrs":[]},"reason":{"str":"parse error: premature EOF\n [null, true, 20, 30, 40\n (right here) ------^","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"unexpected JSON value","attrs":[]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"123","attrs":[{"start":0,"end":-1,"type":"role","value":41}]}}],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":60},{"start":23,"end":29,"type":"role","value":48},{"start":33,"end":41,"type":"role","value":48},{"start":45,"end":53,"type":"role","value":48},{"start":57,"end":61,"type":"role","value":48},{"start":65,"end":69,"type":"role","value":48},{"start":73,"end":77,"type":"role","value":48},{"start":81,"end":86,"type":"role","value":48},{"start":90,"end":100,"type":"role","value":48},{"start":100,"end":101,"type":"role","value":48},{"start":105,"end":113,"type":"role","value":48}]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"unexpected JSON value","attrs":[]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"123","attrs":[{"start":0,"end":-1,"type":"role","value":41}]}}],"notes":[],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":60},{"start":23,"end":29,"type":"role","value":48},{"start":33,"end":41,"type":"role","value":48},{"start":45,"end":53,"type":"role","value":48},{"start":57,"end":61,"type":"role","value":48},{"start":65,"end":69,"type":"role","value":48},{"start":73,"end":77,"type":"role","value":48},{"start":81,"end":86,"type":"role","value":48},{"start":90,"end":100,"type":"role","value":48},{"start":100,"end":101,"type":"role","value":48},{"start":105,"end":113,"type":"role","value":48}]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"warning","message":{"str":"unexpected value for property “/unknown”","attrs":[{"start":33,"end":41,"type":"role","value":48}]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"{\"unknown\":\"abc\"}","attrs":[{"start":0,"end":-1,"type":"role","value":41}]}}],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":60},{"start":23,"end":29,"type":"role","value":48},{"start":33,"end":41,"type":"role","value":48},{"start":45,"end":53,"type":"role","value":48},{"start":57,"end":61,"type":"role","value":48},{"start":65,"end":69,"type":"role","value":48},{"start":73,"end":77,"type":"role","value":48},{"start":81,"end":86,"type":"role","value":48},{"start":90,"end":100,"type":"role","value":48},{"start":100,"end":101,"type":"role","value":48},{"start":105,"end":113,"type":"role","value":48}]}}
error: sqlite3_exec failed -- lnav-error:{"level":"warning","message":{"str":"unexpected value for property “/unknown”","attrs":[{"start":33,"end":41,"type":"role","value":48}]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"{\"unknown\":\"abc\"}","attrs":[{"start":0,"end":-1,"type":"role","value":41}]}}],"notes":[],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":60},{"start":23,"end":29,"type":"role","value":48},{"start":33,"end":41,"type":"role","value":48},{"start":45,"end":53,"type":"role","value":48},{"start":57,"end":61,"type":"role","value":48},{"start":65,"end":69,"type":"role","value":48},{"start":73,"end":77,"type":"role","value":48},{"start":81,"end":86,"type":"role","value":48},{"start":90,"end":100,"type":"role","value":48},{"start":100,"end":101,"type":"role","value":48},{"start":105,"end":113,"type":"role","value":48}]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"warning","message":{"str":"unexpected value for property “/#”","attrs":[{"start":33,"end":35,"type":"role","value":48}]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"[1, 2, 3]","attrs":[{"start":0,"end":-1,"type":"role","value":41}]}}],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":60},{"start":23,"end":29,"type":"role","value":48},{"start":33,"end":41,"type":"role","value":48},{"start":45,"end":53,"type":"role","value":48},{"start":57,"end":61,"type":"role","value":48},{"start":65,"end":69,"type":"role","value":48},{"start":73,"end":77,"type":"role","value":48},{"start":81,"end":86,"type":"role","value":48},{"start":90,"end":100,"type":"role","value":48},{"start":100,"end":101,"type":"role","value":48},{"start":105,"end":113,"type":"role","value":48}]}}
error: sqlite3_exec failed -- lnav-error:{"level":"warning","message":{"str":"unexpected value for property “/#”","attrs":[{"start":33,"end":35,"type":"role","value":48}]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"[1, 2, 3]","attrs":[{"start":0,"end":-1,"type":"role","value":41}]}}],"notes":[],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":60},{"start":23,"end":29,"type":"role","value":48},{"start":33,"end":41,"type":"role","value":48},{"start":45,"end":53,"type":"role","value":48},{"start":57,"end":61,"type":"role","value":48},{"start":65,"end":69,"type":"role","value":48},{"start":73,"end":77,"type":"role","value":48},{"start":81,"end":86,"type":"role","value":48},{"start":90,"end":100,"type":"role","value":48},{"start":100,"end":101,"type":"role","value":48},{"start":105,"end":113,"type":"role","value":48}]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to regexp_match(re, str) failed","attrs":[{"start":8,"end":20,"type":"role","value":48},{"start":21,"end":23,"type":"role","value":47},{"start":25,"end":28,"type":"role","value":47},{"start":8,"end":29,"type":"role","value":61}]},"reason":{"str":"regular expression does not have any captures","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to regexp_match(re, str) failed","attrs":[{"start":8,"end":20,"type":"role","value":48},{"start":21,"end":23,"type":"role","value":47},{"start":25,"end":28,"type":"role","value":47},{"start":8,"end":29,"type":"role","value":61}]},"reason":{"str":"regular expression does not have any captures","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"invalid URL: https://example.com:100000","attrs":[{"start":13,"end":39,"type":"role","value":52}]},"reason":{"str":"Port number was not a decimal number between 0 and 65535","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"invalid URL: https://example.com:100000","attrs":[{"start":13,"end":39,"type":"role","value":52}]},"reason":{"str":"Port number was not a decimal number between 0 and 65535","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"“(” is not a valid regular expression","attrs":[]},"reason":{"str":"missing closing parenthesis","attrs":[]},"snippets":[{"source":"pattern","line":0,"content":{"str":"(\n ^ missing closing parenthesis","attrs":[{"start":0,"end":1,"type":"role","value":3},{"start":0,"end":1,"type":"style","value":2359296},{"start":0,"end":1,"type":"role","value":5},{"start":3,"end":5,"type":"role","value":5},{"start":5,"end":32,"type":"role","value":5},{"start":0,"end":-1,"type":"role","value":41}]}}],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"“(” is not a valid regular expression","attrs":[]},"reason":{"str":"missing closing parenthesis","attrs":[]},"snippets":[{"source":"pattern","line":0,"content":{"str":"(\n ^ missing closing parenthesis","attrs":[{"start":0,"end":1,"type":"role","value":3},{"start":0,"end":1,"type":"style","value":2359296},{"start":0,"end":1,"type":"role","value":5},{"start":3,"end":5,"type":"role","value":5},{"start":5,"end":32,"type":"role","value":5},{"start":0,"end":-1,"type":"role","value":41}]}}],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":48},{"start":18,"end":22,"type":"role","value":47},{"start":24,"end":29,"type":"role","value":47},{"start":8,"end":30,"type":"role","value":61}]},"reason":{"str":"unable to parse time slice value: blah -- Unrecognized input","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":48},{"start":18,"end":22,"type":"role","value":47},{"start":24,"end":29,"type":"role","value":47},{"start":8,"end":30,"type":"role","value":61}]},"reason":{"str":"unable to parse time slice value: blah -- Unrecognized input","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -0,0 +1,4 @@
✘ error: call to timezone(tz, ts) failed
reason: bad-zone not found in timezone database
--> command-option:1
| ;SELECT timezone('bad-zone', '2022-03-02T10:20:30.400-0700')

@ -0,0 +1,2 @@
Row 0:
Column timezone('America/Los_Angeles', '2022-04-02T10:20:30.400-0700'): 2022-04-02T10:20:30.400000-0700

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":48},{"start":18,"end":22,"type":"role","value":47},{"start":24,"end":29,"type":"role","value":47},{"start":8,"end":30,"type":"role","value":61}]},"reason":{"str":"no time slice value given","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":48},{"start":18,"end":22,"type":"role","value":47},{"start":24,"end":29,"type":"role","value":47},{"start":8,"end":30,"type":"role","value":61}]},"reason":{"str":"no time slice value given","attrs":[]},"snippets":[],"notes":[],"help":{"str":"","attrs":[]}}

@ -0,0 +1,2 @@
Row 0:
Column timezone('UTC', '2022-03-02T10:20:30.400-0700'): 2022-03-02T17:20:30.400000+0000

@ -0,0 +1,2 @@
Row 0:
Column timezone('America/New_York', '2022-03-02T10:20:30.400-0700'): 2022-03-02T12:20:30.400000-0500

@ -0,0 +1,8 @@
✘ error: invalid timestamp: 2022-03-02T10:20:30.400bad
reason: the leading part of the timestamp was matched, however, the trailing text “bad” was not
--> command-option:1
| ;SELECT timezone('UTC', '2022-03-02T10:20:30.400bad')
= note: input matched time format “%Y-%m-%dT%H:%M:%S”
= note: 2022-03-02T10:20:30.400bad
^-^ unrecognized input
= help: fix the timestamp or remove the trailing text

@ -0,0 +1,2 @@
Row 0:
Column timezone('America/Los_Angeles', '2022-03-02T10:20:30.400-0700'): 2022-03-02T09:20:30.400000-0800

@ -0,0 +1,2 @@
Row 0:
Column timezone('America/Los_Angeles', '2022-03-02T10:00'): 2022-03-02T02:00:00.000000-0800

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"Invalid XPath expression","attrs":[]},"reason":{"str":"Unrecognized node test","attrs":[]},"snippets":[{"source":"xpath","line":1,"content":{"str":"/abc[\n ^ Unrecognized node test","attrs":[{"start":0,"end":5,"type":"role","value":41},{"start":11,"end":13,"type":"role","value":75},{"start":13,"end":35,"type":"role","value":5},{"start":6,"end":35,"type":"role","value":41},{"start":35,"end":35,"type":"role","value":41}]}}],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"Invalid XPath expression","attrs":[]},"reason":{"str":"Unrecognized node test","attrs":[]},"snippets":[{"source":"xpath","line":1,"content":{"str":"/abc[\n ^ Unrecognized node test","attrs":[{"start":0,"end":5,"type":"role","value":41},{"start":11,"end":13,"type":"role","value":75},{"start":13,"end":35,"type":"role","value":5},{"start":6,"end":35,"type":"role","value":41},{"start":35,"end":35,"type":"role","value":41}]}}],"notes":[],"help":{"str":"","attrs":[]}}

@ -1 +1 @@
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"Invalid XML document","attrs":[]},"reason":{"str":"Error parsing start element tag","attrs":[]},"snippets":[{"source":"xmldoc","line":1,"content":{"str":"<abc\n ^ Error parsing start element tag","attrs":[{"start":0,"end":4,"type":"role","value":41},{"start":8,"end":10,"type":"role","value":75},{"start":10,"end":41,"type":"role","value":5},{"start":5,"end":41,"type":"role","value":41},{"start":41,"end":41,"type":"role","value":41}]}}],"help":{"str":"","attrs":[]}}
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"Invalid XML document","attrs":[]},"reason":{"str":"Error parsing start element tag","attrs":[]},"snippets":[{"source":"xmldoc","line":1,"content":{"str":"<abc\n ^ Error parsing start element tag","attrs":[{"start":0,"end":4,"type":"role","value":41},{"start":8,"end":10,"type":"role","value":75},{"start":10,"end":41,"type":"role","value":5},{"start":5,"end":41,"type":"role","value":41},{"start":41,"end":41,"type":"role","value":41}]}}],"notes":[],"help":{"str":"","attrs":[]}}

@ -69,3 +69,17 @@ run_cap_test ./drive_sql "select timediff('today', 'yesterday')"
# timeslice day
run_cap_test ./drive_sql "select timediff('foo', 'yesterday')"
run_cap_test ./drive_sql "SELECT timezone('America/Los_Angeles', '2022-03-02T10:00')"
run_cap_test ./drive_sql "SELECT timezone('America/Los_Angeles', '2022-03-02T10:20:30.400-0700')"
run_cap_test ./drive_sql "SELECT timezone('America/Los_Angeles', '2022-04-02T10:20:30.400-0700')"
run_cap_test ./drive_sql "SELECT timezone('America/New_York', '2022-03-02T10:20:30.400-0700')"
run_cap_test ./drive_sql "SELECT timezone('UTC', '2022-03-02T10:20:30.400-0700')"
run_cap_test ${lnav_test} -nN -c ";SELECT timezone('bad-zone', '2022-03-02T10:20:30.400-0700')"
run_cap_test ${lnav_test} -nN -c ";SELECT timezone('UTC', '2022-03-02T10:20:30.400bad')"

Loading…
Cancel
Save