Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf3e6d7a authored by Gabor Keszthelyi's avatar Gabor Keszthelyi Committed by Marten Gajda
Browse files

Fix 12/24h format on event list due date-time by using an 5.1.1 Android...

Fix 12/24h format on event list due date-time by using an 5.1.1 Android version of the DateUtils method. #396 (#510)
parent 893ded99
Loading
Loading
Loading
Loading
+133 −8
Original line number Diff line number Diff line
@@ -19,11 +19,14 @@ package org.dmfs.tasks.utils;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
import android.text.format.Time;

import org.dmfs.jems.pair.Pair;
import org.dmfs.jems.pair.elementary.ValuePair;
import org.dmfs.rfc5545.DateTime;
import org.dmfs.tasks.R;

@@ -34,6 +37,10 @@ import java.util.Formatter;
import java.util.Locale;
import java.util.TimeZone;

import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.FORMAT_SHOW_TIME;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;


/**
 * Helper class to format a date to present it to the user.
@@ -74,7 +81,7 @@ public class DateFormatter
                        else
                        {
                            return DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_WEEKDAY
                                    | DateUtils.FORMAT_SHOW_TIME;
                                    | FORMAT_SHOW_TIME;
                        }
                    }
                },
@@ -112,7 +119,7 @@ public class DateFormatter
                        int result = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH;
                        if (!date.allDay)
                        {
                            result |= DateUtils.FORMAT_SHOW_TIME;
                            result |= FORMAT_SHOW_TIME;
                        }
                        if (now.year != date.year)
                        {
@@ -130,7 +137,7 @@ public class DateFormatter
                    @Override
                    public int getDateUtilsFlags(Time now, Time date)
                    {
                        return DateUtils.FORMAT_SHOW_TIME;
                        return FORMAT_SHOW_TIME;
                    }
                },

@@ -161,7 +168,7 @@ public class DateFormatter
                    @Override
                    public int getDateUtilsFlags(Time now, Time date)
                    {
                        return DateUtils.FORMAT_SHOW_TIME;
                        return FORMAT_SHOW_TIME;
                    }


@@ -178,7 +185,7 @@ public class DateFormatter
            if (now.year == date.year && now.yearDay == date.yearDay)
            {
                // today, show time only
                return DateUtils.FORMAT_SHOW_TIME;
                return FORMAT_SHOW_TIME;
            }
            else if (now.year == date.year)
            {
@@ -215,6 +222,8 @@ public class DateFormatter
     */
    private Time mNow;

    private static Pair<Locale, Boolean> sIs12hourFormatCache;


    public DateFormatter(Context context)
    {
@@ -278,7 +287,7 @@ public class DateFormatter
            {
                Time allDayNow = new Time("UTC");
                allDayNow.set(now.monthDay, now.month, now.year);
                return DateUtils.getRelativeTimeSpanString(date.toMillis(false), allDayNow.toMillis(false), DateUtils.DAY_IN_MILLIS).toString();
                return DateUtils.getRelativeTimeSpanString(date.toMillis(false), allDayNow.toMillis(false), DAY_IN_MILLIS).toString();
            }
            else if (delta < 60 * 1000)
            {
@@ -294,12 +303,12 @@ public class DateFormatter
            {
                // time is within 24 hours, show relative string with time
                // FIXME: instead of using a fixed 24 hour interval this should be aligned to midnight tomorrow and yesterday
                return DateUtils.getRelativeDateTimeString(mContext, date.toMillis(false), DateUtils.DAY_IN_MILLIS, DateUtils.WEEK_IN_MILLIS,
                return routingGetRelativeDateTimeString(mContext, date.toMillis(false), DAY_IN_MILLIS, WEEK_IN_MILLIS,
                        dateContext.getDateUtilsFlags(now, date)).toString();
            }
            else
            {
                return DateUtils.getRelativeTimeSpanString(date.toMillis(false), now.toMillis(false), DateUtils.DAY_IN_MILLIS).toString();
                return DateUtils.getRelativeTimeSpanString(date.toMillis(false), now.toMillis(false), DAY_IN_MILLIS).toString();
            }
        }

@@ -370,4 +379,120 @@ public class DateFormatter
        }
        return time;
    }


    /**
     * Routes between old and current version of {@link DateUtils#getRelativeDateTimeString(Context, long, long, long, int)}
     * in order to work around the framework bug introduced in Android 6 for this method:
     * not using the user's 12/24 hours settings for the time format.
     * <p>
     * The reported bugs:
     * <p>
     * <a href="https://github.com/dmfs/opentasks/issues/396">opentasks/396</a>
     * <p>
     * <a href="https://issuetracker.google.com/issues/37127319">google/37127319</a>
     */
    private CharSequence routingGetRelativeDateTimeString(Context c, long time, long minResolution,
                                                          long transitionResolution, int flags)
    {
        return isDefaultLocale12HourFormat() ?
                oldGetRelativeDateTimeString(c, time, minResolution, transitionResolution, flags)
                : DateUtils.getRelativeDateTimeString(c, time, minResolution, transitionResolution, flags);
    }


    /**
     * This method is copied from Android 5.1.1 source for {@link DateUtils#getRelativeDateTimeString(Context, long, long, long, int)}
     * <p>
     * <a href="https://android.googlesource.com/platform/frameworks/base/+/android-5.1.1_r29/core/java/android/text/format/DateUtils.java">DateUtils 5.1.1
     * source</a>
     * <p>
     * because newer versions don't respect the 12/24h settings of the user, they use the locale's default instead.
     * <p>
     * Be aware of the original note inside the method, too.
     * <p>
     * ------ Original javadoc:
     * <p>
     * Return string describing the elapsed time since startTime formatted like
     * "[relative time/date], [time]".
     * <p>
     * Example output strings for the US date format.
     * <ul>
     * <li>3 mins ago, 10:15 AM</li>
     * <li>yesterday, 12:20 PM</li>
     * <li>Dec 12, 4:12 AM</li>
     * <li>11/14/2007, 8:20 AM</li>
     * </ul>
     *
     * @param time
     *         some time in the past.
     * @param minResolution
     *         the minimum elapsed time (in milliseconds) to report when showing relative times. For example, a time 3 seconds in the past will be reported as
     *         "0 minutes ago" if this is set to {@link DateUtils#MINUTE_IN_MILLIS}.
     * @param transitionResolution
     *         the elapsed time (in milliseconds) at which to stop reporting relative measurements. Elapsed times greater than this resolution will default to
     *         normal date formatting. For example, will transition from "6 days ago" to "Dec 12" when using {@link DateUtils#WEEK_IN_MILLIS}.
     */
    private CharSequence oldGetRelativeDateTimeString(Context c, long time, long minResolution,
                                                      long transitionResolution, int flags)
    {
        Resources r = c.getResources();
        long now = System.currentTimeMillis();
        long duration = Math.abs(now - time);
        // getRelativeTimeSpanString() doesn't correctly format relative dates
        // above a week or exact dates below a day, so clamp
        // transitionResolution as needed.
        if (transitionResolution > WEEK_IN_MILLIS)
        {
            transitionResolution = WEEK_IN_MILLIS;
        }
        else if (transitionResolution < DAY_IN_MILLIS)
        {
            transitionResolution = DAY_IN_MILLIS;
        }
        CharSequence timeClause = DateUtils.formatDateRange(c, time, time, FORMAT_SHOW_TIME);
        String result;
        if (duration < transitionResolution)
        {
            CharSequence relativeClause = DateUtils.getRelativeTimeSpanString(time, now, minResolution, flags);
            result = r.getString(R.string.opentasks_relative_time, relativeClause, timeClause);
        }
        else
        {
            CharSequence dateClause = DateUtils.getRelativeTimeSpanString(c, time, false);
            result = r.getString(R.string.opentasks_date_time, dateClause, timeClause);
        }
        return result;
    }


    /**
     * Returns whether the default locale uses 12 hour format (am/pm).
     * <p>
     * Based on the implementation in {@link android.text.format.DateFormat#is24HourFormat(Context)}.
     */
    private boolean isDefaultLocale12HourFormat()
    {
        if (sIs12hourFormatCache != null && sIs12hourFormatCache.left().equals(Locale.getDefault()))
        {
            return sIs12hourFormatCache.right();
        }

        Locale locale = Locale.getDefault();
        java.text.DateFormat natural = java.text.DateFormat.getTimeInstance(java.text.DateFormat.LONG, locale);

        boolean result;
        if (natural instanceof SimpleDateFormat)
        {
            result = ((SimpleDateFormat) natural).toPattern().indexOf('H') < 0;
        }
        else
        {
            // We don't know, so we fall back to true. (Same as in {@link DateFormat#is24HourFormat})
            result = true;
        }

        sIs12hourFormatCache = new ValuePair<>(locale, result);
        return result;
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -250,4 +250,6 @@
    <!-- Sharing intent -->
    <string name="share_as_task">Vytvořit úkol</string>

    <string name="opentasks_date_time">%1$s %2$s</string>

</resources>
+2 −0
Original line number Diff line number Diff line
@@ -249,4 +249,6 @@
    <!-- Incoming share -->
    <string name="share_as_task">Ajouter une tâche</string>

    <string name="opentasks_date_time">%1$s à %2$s</string>

</resources>
+2 −0
Original line number Diff line number Diff line
@@ -254,4 +254,6 @@
    <!-- Outgoing share -->
    <string name="opentasks_share_footer">OpenTasks-al küldve</string>

    <string name="opentasks_date_time">%1$s %2$s</string>

</resources>
+2 −0
Original line number Diff line number Diff line
@@ -118,4 +118,6 @@
    <!-- Incoming share -->
    <string name="share_as_task">Aggiungi attività</string>

    <string name="opentasks_date_time">%1$s %2$s</string>

</resources>
Loading