private static void addConfiguredInfoItems(final Geocache cache, final List<Integer> configuredItems, final @Nullable List<AbstractList> storedLists, final @Nullable String excludeList, final List<SpannableString> infos) {
        for (int item : configuredItems) {
            if (item == CacheListInfoItem.VALUES.GCCODE.id) {
                if (StringUtils.isNotBlank(cache.getGeocode())) {
                    infos.add(new SpannableString(cache.getShortGeocode()));
                }
            } else if (item == CacheListInfoItem.VALUES.DIFFICULTY.id) {
                if (cache.hasDifficulty()) {
                    infos.add(new SpannableString("D " + formatDT(cache.getDifficulty())));
                }
            } else if (item == CacheListInfoItem.VALUES.TERRAIN.id) {
                if (cache.hasTerrain()) {
                    infos.add(new SpannableString("T " + formatDT(cache.getTerrain())));
                }
            } else if (item == CacheListInfoItem.VALUES.MEMBERSTATE.id) {
                if (cache.isPremiumMembersOnly()) {
                    infos.add(new SpannableString(CgeoApplication.getInstance().getString(R.string.cache_premium)));
                }
            } else if (item == CacheListInfoItem.VALUES.SIZE.id) {
                if (cache.getSize() != CacheSize.UNKNOWN && cache.showSize()) {
                    infos.add(new SpannableString(cache.getSize().getL10n()));
                }
            } else if (item == CacheListInfoItem.VALUES.LISTS.id) {
                formatCacheLists(cache, storedLists, excludeList, infos);
            } else if (item == CacheListInfoItem.VALUES.EVENTDATE.id) {
                if (cache.isEventCache()) {
                    final Date hiddenDate = cache.getHiddenDate();
                    if (hiddenDate != null) {
                        infos.add(new SpannableString(formatShortDateIncludingWeekday(hiddenDate.getTime())));
                    }
                }
            } else if (item == CacheListInfoItem.VALUES.HIDDEN_MONTH.id) {
                final Date hiddenDate = cache.getHiddenDate();
                if (hiddenDate != null) {
                    infos.add(new SpannableString(formatDateYYYYMM(hiddenDate.getTime())));
                }
            } else if (item == CacheListInfoItem.VALUES.RECENT_LOGS.id) {
                final List<LogEntry> logs = cache.getLogs();
                if (!logs.isEmpty()) {
                    int count = 0;
                    // mitigation to make displaying ImageSpans work even in wrapping lines, see #14163
                    // ImageSpans are separated by a zero-width space character (\u200b)
                    final SpannableString s = new SpannableString(" \u200b \u200b \u200b \u200b \u200b \u200b \u200b \u200b");
                    for (int i = 0; i < Math.min(logs.size(), 8); i++) {
                        final ImageSpan is;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                            is = new ImageSpan(getContext(), logs.get(i).logType.getLogOverlay(), ImageSpan.ALIGN_CENTER);
                        } else {
                            is = new ImageSpan(getContext(), logs.get(i).logType.getLogOverlay());
                        }
                        s.setSpan(is, i * 2, i * 2 + 1, 0);
                        count++;
                    }
                    infos.add(new SpannableString(s.subSequence(0, 2 * count)));
                }

            // newline items should be last in list
            } else if (item == CacheListInfoItem.VALUES.NEWLINE1.id || item == CacheListInfoItem.VALUES.NEWLINE2.id || item == CacheListInfoItem.VALUES.NEWLINE3.id || item == CacheListInfoItem.VALUES.NEWLINE4.id) {
                infos.add(new SpannableString("\n"));
            }
        }
    }
Generate a numeric date and time string according to system-wide settings (locale,
date format) such as "7 september at 12:35".

@param date milliseconds since the epoch
@return the formatted string
main/src/main/java/cgeo/geocaching/utils/Formatter.java