From a27d0b93db5c894d3d16a0f87e46441112cb07d4 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Sat, 16 Sep 2023 12:41:27 +0100 Subject: [PATCH] New template function: format_date_field(). This function is much faster than format_date() because it avoids a round-trip conversion of date -> string -> date. --- manual/template_lang.rst | 5 ++++ src/calibre/utils/formatter_functions.py | 36 +++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/manual/template_lang.rst b/manual/template_lang.rst index 07e786bf47..3c02a11aef 100644 --- a/manual/template_lang.rst +++ b/manual/template_lang.rst @@ -552,6 +552,11 @@ In `GPM` the functions described in `Single Function Mode` all require an additi format_date(raw_field('pubdate'), 'yyyy') +* ``format_date_field(field_name, format_string)`` -- format the value in the field ``field_name``, which must be the lookup name of date field, either standard or custom. See ``format_date()`` for the formatting codes. This function is much faster than format_date and should be used when you are formatting the value in a field (column). It can't be used for computed dates or dates in string variables. Examples:: + + format_date_field('pubdate', 'yyyy.MM.dd') + format_date_field('#date_read', 'MMM dd, yyyy') + * ``formats_modtimes(date_format_string)`` -- return a comma-separated list of colon-separated items ``FMT:DATE`` representing modification times for the formats of a book. The ``date_format_string`` parameter specifies how the date is to be formatted. See the ``format_date()`` function for details. You can use the ``select`` function to get the modification time for a specific format. Note that format names are always uppercase, as in EPUB. * ``formats_paths()`` -- return a comma-separated list of colon-separated items ``FMT:PATH`` giving the full path to the formats of a book. You can use the select function to get the path for a specific format. Note that format names are always uppercase, as in EPUB. * ``formats_sizes()`` -- return a comma-separated list of colon-separated ``FMT:SIZE`` items giving the sizes in bytes of the formats of a book. You can use the select function to get the size for a specific format. Note that format names are always uppercase, as in EPUB. diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index 607dfdb8dc..5281b3d6b3 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -1285,6 +1285,40 @@ class BuiltinFormatDate(BuiltinFormatterFunction): return s +class BuiltinFormatDateField(BuiltinFormatterFunction): + name = 'format_date_field' + arg_count = 2 + category = 'Formatting values' + __doc__ = doc = _("format_date_field(field_name, format_string) -- format " + "the value in the field 'field_name', which must be the lookup name " + "of date field, either standard or custom. See 'format_date' for " + "the formatting codes. This function is much faster than format_date " + "and should be used when you are formatting the value in a field " + "(column). It can't be used for computed dates or dates in string " + "variables. Example: format_date_field('pubdate', 'yyyy.MM.dd')") + + def evaluate(self, formatter, kwargs, mi, locals, field, format_string): + try: + if field not in mi.all_field_keys(): + return _('Unknown field %s passed to function %s')%(field, 'format_date_field') + val = mi.get(field, None) + if val is None: + s = '' + elif format_string == 'to_number': + s = val.timestamp() + elif format_string.startswith('from_number'): + val = datetime.fromtimestamp(float(val)) + f = format_string[12:] + s = format_date(val, f if f else 'iso') + else: + s = format_date(val, format_string) + return s + except: + traceback.print_exc() + s = 'BAD DATE' + return s + + class BuiltinUppercase(BuiltinFormatterFunction): name = 'uppercase' arg_count = 1 @@ -2522,7 +2556,7 @@ _formatter_builtins = [ BuiltinExtraFileNames(), BuiltinExtraFileSize(), BuiltinExtraFileModtime(), BuiltinFirstNonEmpty(), BuiltinField(), BuiltinFieldExists(), BuiltinFinishFormatting(), BuiltinFirstMatchingCmp(), BuiltinFloor(), - BuiltinFormatDate(), BuiltinFormatNumber(), BuiltinFormatsModtimes(), + BuiltinFormatDate(), BuiltinFormatDateField(), BuiltinFormatNumber(), BuiltinFormatsModtimes(), BuiltinFormatsPaths(), BuiltinFormatsSizes(), BuiltinFractionalPart(), BuiltinGlobals(), BuiltinHasExtraFiles(), BuiltinHasCover(), BuiltinHumanReadable(), BuiltinIdentifierInList(),