Format dates with 310 backport

pull/996/head
Alex Baker 6 years ago
parent d045c75ff2
commit 447b6be7d2

@ -6,93 +6,31 @@
package com.todoroo.andlib.utility;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.todoroo.andlib.utility.DateUtilities.getDateString;
import static com.todoroo.andlib.utility.DateUtilities.getStartOfDay;
import static com.todoroo.andlib.utility.DateUtilities.getTimeString;
import static com.todoroo.andlib.utility.DateUtilities.getWeekday;
import static com.todoroo.andlib.utility.DateUtilities.getWeekdayShort;
import static junit.framework.Assert.assertEquals;
import static org.tasks.Freeze.freezeAt;
import static org.tasks.date.DateTimeUtils.newDate;
import static org.tasks.date.DateTimeUtils.newDateTime;
import android.content.res.Configuration;
import android.util.DisplayMetrics;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.After;
import org.junit.Before;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.Snippet;
import org.tasks.time.DateTime;
import org.threeten.bp.format.FormatStyle;
@RunWith(AndroidJUnit4.class)
public class DateUtilitiesTest {
private static Locale defaultLocale;
@Before
public void setUp() {
defaultLocale = Locale.getDefault();
setLocale(Locale.US);
}
@After
public void tearDown() {
public void after() {
DateUtilities.is24HourOverride = null;
setLocale(defaultLocale);
}
private void setLocale(Locale locale) {
org.tasks.locale.Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
DisplayMetrics metrics = getTargetContext().getResources().getDisplayMetrics();
getTargetContext().getResources().updateConfiguration(config, metrics);
}
public void forEachLocale(Runnable r) {
Locale[] locales = Locale.getAvailableLocales();
for (Locale locale : locales) {
setLocale(locale);
r.run();
}
}
@Test
public void testTimeString() {
forEachLocale(
() -> {
DateTime d = newDateTime();
DateUtilities.is24HourOverride = false;
for (int i = 0; i < 24; i++) {
d = d.withHourOfDay(i);
getTimeString(getTargetContext(), d);
}
DateUtilities.is24HourOverride = true;
for (int i = 0; i < 24; i++) {
d = d.withHourOfDay(i);
getTimeString(getTargetContext(), d);
}
});
}
@Test
public void testDateString() {
forEachLocale(
() -> {
DateTime d = newDateTime();
for (int i = 0; i < 12; i++) {
d = d.withMonthOfYear(i);
getDateString(d);
}
});
}
@Test
@ -117,176 +55,246 @@ public class DateUtilitiesTest {
@Test
public void testGetDateStringWithYear() {
assertEquals("Jan 4 '14", getDateString(new DateTime(2014, 1, 4, 0, 0, 0)));
assertEquals("Jan 4, 2014", getDateString(getApplicationContext(), new DateTime(2014, 1, 4, 0, 0, 0)));
}
@Test
public void testGetDateStringHidingYear() {
freezeAt(newDate(2014, 1, 1))
freezeAt(newDate(2014, 2, 1))
.thawAfter(
new Snippet() {
{
assertEquals("Jan 1", getDateString(newDateTime()));
assertEquals("Jan 1", getDateString(getApplicationContext(), new DateTime(2014, 1, 1)));
}
});
}
@Test
public void testGetDateStringWithDifferentYear() {
freezeAt(newDate(2013, 12, 31))
freezeAt(newDate(2013, 12, 1))
.thawAfter(
new Snippet() {
{
assertEquals("Jan 1 '14", getDateString(new DateTime(2014, 1, 1, 0, 0, 0)));
assertEquals("Jan 1, 2014", getDateString(getApplicationContext(),new DateTime(2014, 1, 1, 0, 0, 0)));
}
});
}
@Test
public void testShouldGetStartOfDay() {
DateTime now = new DateTime(2014, 1, 3, 10, 41, 41, 520);
assertEquals(now.startOfDay().getMillis(), getStartOfDay(now.getMillis()));
public void testGetWeekdayLongString() {
assertEquals("Sunday", getWeekday(newDate(2013, 12, 29), Locale.US));
assertEquals("Monday", getWeekday(newDate(2013, 12, 30), Locale.US));
assertEquals("Tuesday", getWeekday(newDate(2013, 12, 31), Locale.US));
assertEquals("Wednesday", getWeekday(newDate(2014, 1, 1), Locale.US));
assertEquals("Thursday", getWeekday(newDate(2014, 1, 2), Locale.US));
assertEquals("Friday", getWeekday(newDate(2014, 1, 3), Locale.US));
assertEquals("Saturday", getWeekday(newDate(2014, 1, 4), Locale.US));
}
@Test
public void testGetWeekdayLongString() {
assertEquals("Sunday", getWeekday(newDate(2013, 12, 29)));
assertEquals("Monday", getWeekday(newDate(2013, 12, 30)));
assertEquals("Tuesday", getWeekday(newDate(2013, 12, 31)));
assertEquals("Wednesday", getWeekday(newDate(2014, 1, 1)));
assertEquals("Thursday", getWeekday(newDate(2014, 1, 2)));
assertEquals("Friday", getWeekday(newDate(2014, 1, 3)));
assertEquals("Saturday", getWeekday(newDate(2014, 1, 4)));
public void testGetWeekdayShortString() {
assertEquals("Sun", getWeekdayShort(newDate(2013, 12, 29), Locale.US));
assertEquals("Mon", getWeekdayShort(newDate(2013, 12, 30), Locale.US));
assertEquals("Tue", getWeekdayShort(newDate(2013, 12, 31), Locale.US));
assertEquals("Wed", getWeekdayShort(newDate(2014, 1, 1), Locale.US));
assertEquals("Thu", getWeekdayShort(newDate(2014, 1, 2), Locale.US));
assertEquals("Fri", getWeekdayShort(newDate(2014, 1, 3), Locale.US));
assertEquals("Sat", getWeekdayShort(newDate(2014, 1, 4), Locale.US));
}
@Test
public void testGetWeekdayShortString() {
assertEquals("Sun", getWeekdayShort(newDate(2013, 12, 29)));
assertEquals("Mon", getWeekdayShort(newDate(2013, 12, 30)));
assertEquals("Tue", getWeekdayShort(newDate(2013, 12, 31)));
assertEquals("Wed", getWeekdayShort(newDate(2014, 1, 1)));
assertEquals("Thu", getWeekdayShort(newDate(2014, 1, 2)));
assertEquals("Fri", getWeekdayShort(newDate(2014, 1, 3)));
assertEquals("Sat", getWeekdayShort(newDate(2014, 1, 4)));
public void getRelativeFullDate() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"Sunday, January 14",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void usDateNoYear() {
setLocale(Locale.US);
public void getRelativeFullDateWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"Sunday, January 14, 2018",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void getRelativeFullDateTime() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"Jan 14",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
"Sunday, January 14 1:43 PM",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 43, 1).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void usDateWithYear() {
setLocale(Locale.US);
public void getRelativeFullDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"Jan 14 '18",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
"Sunday, January 14, 2018 11:50 AM",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 11, 50, 1).getMillis(),
Locale.US,
FormatStyle.FULL)));
}
@Test
public void germanDateNoYear() {
setLocale(Locale.GERMAN);
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"14 Jan.",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"Sonntag, 14. Januar",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.GERMAN,
FormatStyle.FULL)));
}
@Test
public void germanDateWithYear() {
setLocale(Locale.GERMAN);
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"14 Jan. '18",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"Sonntag, 14. Januar 2018",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.GERMAN,
FormatStyle.FULL)));
}
@Test
public void koreanDateNoYear() {
setLocale(Locale.KOREAN);
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"1월 14일",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"1월 14일 일요일",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.KOREAN,
FormatStyle.FULL)));
}
@Test
public void koreanDateWithYear() {
setLocale(Locale.KOREAN);
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"18년 1월 14일",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"2018년 1월 14일 일요일",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.KOREAN,
FormatStyle.FULL)));
}
@Test
public void japaneseDateNoYear() {
setLocale(Locale.JAPANESE);
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"1月14日日曜日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.JAPANESE,
FormatStyle.FULL)));
}
@Test
public void japaneseDateWithYear() {
setLocale(Locale.JAPANESE);
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"18年 1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"2018年1月14日日曜日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.JAPANESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateNoYear() {
setLocale(Locale.CHINESE);
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
assertEquals(
"1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"1月14日星期日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateWithYear() {
setLocale(Locale.CHINESE);
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
assertEquals(
"18年 1月 14日",
DateUtilities.getRelativeDateStringWithTime(
getTargetContext(), new DateTime(2018, 1, 14).getMillis())));
Assert.assertEquals(
"2018年1月14日星期日",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateTimeNoYear() {
freezeAt(new DateTime(2018, 1, 1))
.thawAfter(
() ->
Assert.assertEquals(
"1月14日星期日 上午11:53",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 11, 53, 1).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
@Test
public void chineseDateTimeWithYear() {
freezeAt(new DateTime(2017, 12, 12))
.thawAfter(
() ->
Assert.assertEquals(
"2018年1月14日星期日 下午1:45",
DateUtilities.getRelativeDateTime(
getApplicationContext(),
new DateTime(2018, 1, 14, 13, 45, 1).getMillis(),
Locale.CHINESE,
FormatStyle.FULL)));
}
}

@ -1,6 +1,6 @@
package com.todoroo.andlib.utility;
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.todoroo.andlib.utility.DateUtilities.getRelativeDay;
import static junit.framework.Assert.assertEquals;
import static org.tasks.Freeze.freezeAt;
@ -13,6 +13,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
import org.threeten.bp.format.FormatStyle;
@RunWith(AndroidJUnit4.class)
public class RelativeDayTest {
@ -62,16 +63,20 @@ public class RelativeDayTest {
@Test
public void testRelativeDayOneWeek() {
checkRelativeDay(new DateTime().minusDays(7), "Dec 24", "Dec 24");
checkRelativeDay(new DateTime().minusDays(7), "December 24", "Dec 24");
}
@Test
public void testRelativeDayOneWeekNextYear() {
checkRelativeDay(new DateTime().plusDays(7), "Jan 7 '14", "Jan 7 '14");
checkRelativeDay(new DateTime().plusDays(7), "January 7, 2014", "Jan 7, 2014");
}
private void checkRelativeDay(DateTime now, String full, String abbreviated) {
assertEquals(full, getRelativeDay(getTargetContext(), now.getMillis(), false));
assertEquals(abbreviated, getRelativeDay(getTargetContext(), now.getMillis(), true));
assertEquals(
full,
getRelativeDay(getApplicationContext(), now.getMillis(), Locale.US, FormatStyle.LONG));
assertEquals(
abbreviated,
getRelativeDay(getApplicationContext(), now.getMillis(), Locale.US, FormatStyle.MEDIUM));
}
}

@ -11,10 +11,15 @@ import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import android.content.Context;
import android.text.format.DateFormat;
import androidx.annotation.Nullable;
import com.google.common.base.Strings;
import com.todoroo.astrid.data.Task;
import org.tasks.BuildConfig;
import org.tasks.R;
import org.tasks.locale.Locale;
import org.tasks.time.DateTime;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.FormatStyle;
import org.threeten.bp.format.TextStyle;
public class DateUtilities {
@ -27,13 +32,6 @@ public class DateUtilities {
/** Represents a single minute */
public static final long ONE_MINUTE = 60000L;
private static final long abbreviationLimit = DateUtilities.ONE_DAY * 6;
private static final String JA = "MMM d\u65E5";
private static final String JA_YEAR = "yy\u5E74 " + JA;
private static final String KO = "MMM d\uC77C";
private static final String KO_YEAR = "yy\uB144 " + KO;
private static final String ZH = "MMM d\u65E5";
private static final String ZH_YEAR = "yy\u5E74 " + ZH;
static Boolean is24HourOverride = null;
/** Returns unixtime for current time */
@ -45,16 +43,10 @@ public class DateUtilities {
* =========================================================== formatters
* ====================================================================== */
public static boolean is24HourFormat(Context context) {
if (is24HourOverride != null) {
return is24HourOverride;
}
return DateFormat.is24HourFormat(context);
}
public static String getTimeString(Context context, long timestamp) {
return getTimeString(context, newDateTime(timestamp));
private static boolean is24HourFormat(Context context) {
return BuildConfig.DEBUG && is24HourOverride != null
? is24HourOverride
: DateFormat.is24HourFormat(context);
}
public static String getTimeString(Context context, DateTime date) {
@ -69,120 +61,106 @@ public class DateUtilities {
return date.toString(value);
}
public static String getLongDateString(DateTime date) {
return getDateString("MMMM", date);
public static String getLongDateString(DateTime date, java.util.Locale locale) {
return getFullDate(date, locale, FormatStyle.LONG);
}
/**
* @param date date to format
* @return date, with month, day, and year
*/
public static String getDateString(DateTime date) {
return getDateString("MMM", date);
public static String getDateString(Context context, DateTime date) {
return getRelativeDay(
context, date.getMillis(), java.util.Locale.getDefault(), FormatStyle.MEDIUM);
}
private static String getDateString(String simpleDateFormat, DateTime date) {
boolean includeYear = date.getYear() != newDateTime().getYear();
String format = getFormat(Locale.getInstance(), simpleDateFormat, includeYear);
return date.toString(format);
}
private static String getFormat(Locale locale, String monthFormat, boolean includeYear) {
switch (locale.getLanguage()) {
case "ja":
return includeYear ? JA_YEAR : JA;
case "ko":
return includeYear ? KO_YEAR : KO;
case "zh":
return includeYear ? ZH_YEAR : ZH;
}
switch (locale.getCountry()) {
case "BZ":
case "CA":
case "KE":
case "MN":
case "US":
return includeYear ? monthFormat + " d ''yy" : monthFormat + " d";
default:
return includeYear ? "d " + monthFormat + " ''yy" : "d " + monthFormat;
}
static String getWeekday(DateTime date, java.util.Locale locale) {
return date.toLocalDate().getDayOfWeek().getDisplayName(TextStyle.FULL, locale);
}
/** @return weekday */
public static String getWeekday(DateTime date) {
return date.toString("EEEE");
static String getWeekdayShort(DateTime date, java.util.Locale locale) {
return date.toLocalDate().getDayOfWeek().getDisplayName(TextStyle.SHORT, locale);
}
/** @return weekday */
public static String getWeekdayShort(DateTime date) {
return date.toString("EEE");
public static String getLongDateStringWithTime(long timestamp, java.util.Locale locale) {
return getFullDateTime(newDateTime(timestamp), locale, FormatStyle.LONG);
}
public static String getLongDateStringWithTime(Context context, long timestamp) {
DateTime date = newDateTime(timestamp);
return getLongDateString(date) + ", " + getTimeString(context, date);
public static String getRelativeDateTime(
Context context, long date, java.util.Locale locale, FormatStyle style) {
String day = getRelativeDay(context, date, locale, isAbbreviated(style));
if (!Strings.isNullOrEmpty(day)) {
if (Task.hasDueTime(date)) {
String time = getTimeString(context, newDateTime(date));
return newDateTime().startOfDay().equals(newDateTime(date).startOfDay()) ? time : String.format("%s %s", day, time);
} else {
return day;
}
public static String getDateStringWithTime(Context context, long timestamp) {
DateTime date = newDateTime(timestamp);
return getDateString(date) + ", " + getTimeString(context, date);
}
public static String getRelativeDateStringWithTime(Context context, long timestamp) {
String string = DateUtilities.getRelativeDay(context, timestamp, false);
if (Task.hasDueTime(timestamp)) {
string =
String.format(
"%s %s",
string, // $NON-NLS-1$
DateUtilities.getTimeString(context, timestamp));
return Task.hasDueTime(date)
? getFullDateTime(newDateTime(date), locale, style)
: getFullDate(newDateTime(date), locale, style);
}
return string;
private static boolean isAbbreviated(FormatStyle style) {
return style == FormatStyle.SHORT || style == FormatStyle.MEDIUM;
}
public static String getAbbreviatedRelativeDateWithTime(Context context, long date) {
long startOfToday = getStartOfDay(currentTimeMillis());
long startOfDate = getStartOfDay(date);
String day = getRelativeDay(context, date, startOfDate, startOfToday, true);
if (Task.hasDueTime(date)) {
String time = getTimeString(context, date);
return startOfToday == startOfDate ? time : String.format("%s %s", day, time);
static String getRelativeDay(
Context context,
long date,
java.util.Locale locale,
FormatStyle style) {
String relativeDay = getRelativeDay(context, date, locale, isAbbreviated(style));
return Strings.isNullOrEmpty(relativeDay)
? getFullDate(newDateTime(date), locale, style)
: relativeDay;
}
return day;
private static String getFullDate(DateTime date, java.util.Locale locale, FormatStyle style) {
return stripYear(
DateTimeFormatter.ofLocalizedDate(style)
.withLocale(locale)
.format(date.toLocalDate()),
newDateTime().getYear());
}
/** @return yesterday, today, tomorrow, or null */
public static String getRelativeDay(Context context, long date, boolean abbreviated) {
long today = getStartOfDay(currentTimeMillis());
long input = getStartOfDay(date);
private static String getFullDateTime(DateTime date, java.util.Locale locale, FormatStyle style) {
return stripYear(
DateTimeFormatter.ofLocalizedDateTime(style, FormatStyle.SHORT)
.withLocale(locale)
.format(date.toLocalDateTime()),
newDateTime().getYear());
}
return getRelativeDay(context, date, input, today, abbreviated);
private static String stripYear(String date, int year) {
return date.replaceFirst("(,? )?" + year + "(年|년 )?", "");
}
private static String getRelativeDay(
Context context, long date, long input, long today, boolean abbreviated) {
if (today == input) {
private static @Nullable String getRelativeDay(Context context, long date, java.util.Locale locale, boolean abbreviated) {
DateTime startOfToday = newDateTime().startOfDay();
DateTime startOfDate = newDateTime(date).startOfDay();
if (startOfToday.equals(startOfDate)) {
return context.getString(R.string.today);
}
if (today + ONE_DAY == input) {
if (startOfToday.plusDays(1).equals(startOfDate)) {
return context.getString(abbreviated ? R.string.tmrw : R.string.tomorrow);
}
if (today == input + ONE_DAY) {
if (startOfDate.plusDays(1).equals(startOfToday)) {
return context.getString(abbreviated ? R.string.yest : R.string.yesterday);
}
if (today + abbreviationLimit >= input && today - abbreviationLimit <= input) {
if (Math.abs(startOfToday.getMillis() - startOfDate.getMillis()) <= DateUtilities.ONE_DAY * 6) {
DateTime dateTime = newDateTime(date);
return abbreviated
? DateUtilities.getWeekdayShort(newDateTime(date))
: DateUtilities.getWeekday(newDateTime(date));
}
? DateUtilities.getWeekdayShort(dateTime, locale)
: DateUtilities.getWeekday(dateTime, locale);
return getDateString(newDateTime(date));
}
public static long getStartOfDay(long time) {
return newDateTime(time).startOfDay().getMillis();
return null;
}
}

@ -276,7 +276,7 @@ public final class TaskEditFragment extends InjectingFragment
String.format(
"%s %s\n%s %s", // $NON-NLS-1$
getString(R.string.TEA_timer_comment_stopped),
DateUtilities.getTimeString(getActivity(), newDateTime()),
DateUtilities.getTimeString(context, newDateTime()),
getString(R.string.TEA_timer_comment_spent),
elapsedTime),
null);
@ -289,7 +289,7 @@ public final class TaskEditFragment extends InjectingFragment
String.format(
"%s %s",
getString(R.string.TEA_timer_comment_started),
DateUtilities.getTimeString(getActivity(), newDateTime())),
DateUtilities.getTimeString(context, newDateTime())),
null);
return model;
}

@ -417,8 +417,7 @@ public class Task implements Parcelable {
public boolean isOverdue() {
long dueDate = getDueDate();
long compareTo =
hasDueTime() ? DateUtilities.now() : DateUtilities.getStartOfDay(DateUtilities.now());
long compareTo = hasDueTime() ? DateUtilities.now() : newDateTime().startOfDay().getMillis();
return dueDate < compareTo && !isCompleted();
}

@ -26,6 +26,7 @@ import org.tasks.R;
import org.tasks.data.UserActivity;
import org.tasks.data.UserActivityDao;
import org.tasks.files.FileHelper;
import org.tasks.locale.Locale;
import org.tasks.preferences.Preferences;
public class CommentsController {
@ -34,6 +35,7 @@ public class CommentsController {
private final ArrayList<UserActivity> items = new ArrayList<>();
private final Activity activity;
private final Preferences preferences;
private final Locale locale;
private int commentItems = 10;
private Task task;
@ -41,10 +43,11 @@ public class CommentsController {
@Inject
public CommentsController(
UserActivityDao userActivityDao, Activity activity, Preferences preferences) {
UserActivityDao userActivityDao, Activity activity, Preferences preferences, Locale locale) {
this.userActivityDao = userActivityDao;
this.activity = activity;
this.preferences = preferences;
this.locale = locale;
}
private static void setupImagePopupForCommentView(
@ -114,7 +117,7 @@ public class CommentsController {
// date
final TextView date = view.findViewById(R.id.date);
date.setText(DateUtilities.getLongDateStringWithTime(activity, item.getCreated()));
date.setText(DateUtilities.getLongDateStringWithTime(item.getCreated(), locale.getLocale()));
// picture
final ImageView commentPictureView = view.findViewById(R.id.comment_picture);

@ -41,6 +41,7 @@ import org.tasks.activities.DateAndTimePickerActivity;
import org.tasks.dialogs.MyTimePickerDialog;
import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.locale.Locale;
import org.tasks.preferences.Preferences;
import org.tasks.themes.ThemeBase;
import org.tasks.time.DateTime;
@ -66,6 +67,7 @@ public class HideUntilControlSet extends TaskEditControlFragment implements OnIt
@Inject @ForActivity Context context;
@Inject ThemeBase themeBase;
@Inject Preferences preferences;
@Inject Locale locale;
// private final CheckBox enabled;
@BindView(R.id.hideUntil)
Spinner spinner;
@ -266,12 +268,12 @@ public class HideUntilControlSet extends TaskEditControlFragment implements OnIt
&& hideUntilAsDate.getMinuteOfHour() == 0
&& hideUntilAsDate.getSecondOfMinute() == 0) {
return new HideUntilValue(
DateUtilities.getDateString(newDateTime(timestamp)),
DateUtilities.getDateString(context, newDateTime(timestamp)),
Task.HIDE_UNTIL_SPECIFIC_DAY,
timestamp);
} else {
return new HideUntilValue(
DateUtilities.getDateStringWithTime(context, timestamp),
DateUtilities.getLongDateStringWithTime(timestamp, locale.getLocale()),
Task.HIDE_UNTIL_SPECIFIC_DAY_TIME,
timestamp);
}

@ -45,6 +45,7 @@ import org.tasks.data.Alarm;
import org.tasks.dialogs.MyTimePickerDialog;
import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.locale.Locale;
import org.tasks.ui.HiddenTopArrayAdapter;
import org.tasks.ui.TaskEditControlFragment;
@ -66,6 +67,7 @@ public class ReminderControlSet extends TaskEditControlFragment {
private final Set<Long> alarms = new LinkedHashSet<>();
@Inject AlarmService alarmService;
@Inject @ForActivity Context context;
@Inject Locale locale;
@BindView(R.id.alert_container)
LinearLayout alertContainer;
@ -231,7 +233,7 @@ public class ReminderControlSet extends TaskEditControlFragment {
private void addAlarmRow(final Long timestamp) {
if (alarms.add(timestamp)) {
addAlarmRow(getLongDateStringWithTime(context, timestamp), v -> alarms.remove(timestamp));
addAlarmRow(getLongDateStringWithTime(timestamp, locale.getLocale()), v -> alarms.remove(timestamp));
}
}

@ -15,6 +15,8 @@ import java.text.ParseException;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.locale.Locale;
import org.threeten.bp.format.FormatStyle;
import timber.log.Timber;
public class RepeatConfirmationReceiver extends BroadcastReceiver {
@ -22,12 +24,15 @@ public class RepeatConfirmationReceiver extends BroadcastReceiver {
private final Activity activity;
private final Tracker tracker;
private final TaskDao taskDao;
private final Locale locale;
@Inject
public RepeatConfirmationReceiver(Activity activity, Tracker tracker, TaskDao taskDao) {
public RepeatConfirmationReceiver(
Activity activity, Tracker tracker, TaskDao taskDao, Locale locale) {
this.activity = activity;
this.tracker = tracker;
this.taskDao = taskDao;
this.locale = locale;
}
@Override
@ -60,7 +65,9 @@ public class RepeatConfirmationReceiver extends BroadcastReceiver {
final Task task,
final long oldDueDate,
final long newDueDate) {
String dueDateString = getRelativeDateAndTimeString(activity, newDueDate);
String dueDateString =
DateUtilities.getRelativeDateTime(
activity, newDueDate, locale.getLocale(), FormatStyle.LONG);
String snackbarText =
activity.getString(R.string.repeat_snackbar, task.getTitle(), dueDateString);
taskListFragment
@ -84,14 +91,4 @@ public class RepeatConfirmationReceiver extends BroadcastReceiver {
})
.show();
}
private String getRelativeDateAndTimeString(Context context, long date) {
String dueString = date > 0 ? DateUtilities.getRelativeDay(context, date, false) : "";
if (Task.hasDueTime(date)) {
dueString =
context.getString(
R.string.repeat_snackbar_time, dueString, DateUtilities.getTimeString(context, date));
}
return dueString;
}
}

@ -9,7 +9,6 @@ import static com.google.ical.values.Frequency.MONTHLY;
import static com.google.ical.values.Frequency.WEEKLY;
import static com.google.ical.values.Frequency.YEARLY;
import static java.util.Arrays.asList;
import static org.tasks.date.DateTimeUtils.newDateTime;
import static org.tasks.dialogs.MyDatePickerDialog.newDatePicker;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
@ -51,7 +50,6 @@ import com.google.ical.values.RRule;
import com.google.ical.values.Weekday;
import com.google.ical.values.WeekdayNum;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.repeats.RepeatControlSet;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
@ -68,6 +66,7 @@ import org.tasks.injection.InjectingDialogFragment;
import org.tasks.locale.Locale;
import org.tasks.preferences.ResourceResolver;
import org.tasks.time.DateTime;
import org.threeten.bp.format.FormatStyle;
import timber.log.Timber;
public class CustomRecurrenceDialog extends InjectingDialogFragment {
@ -158,19 +157,6 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment {
return dialog;
}
private static String getDisplayString(Context context, long repeatUntilValue) {
StringBuilder displayString = new StringBuilder();
DateTime d = newDateTime(repeatUntilValue);
if (d.getMillis() > 0) {
displayString.append(DateUtilities.getDateString(d));
if (Task.hasDueTime(repeatUntilValue)) {
displayString.append(", "); // $NON-NLS-1$ //$NON-NLS-2$
displayString.append(DateUtilities.getTimeString(context, repeatUntilValue));
}
}
return displayString.toString();
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@ -532,7 +518,10 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment {
int count = rrule.getCount();
if (repeatUntil > 0) {
repeatUntilOptions.add(
getString(R.string.repeat_until, getDisplayString(context, repeatUntil)));
getString(
R.string.repeat_until,
DateUtilities.getRelativeDateTime(
context, repeatUntil, locale.getLocale(), FormatStyle.MEDIUM)));
repeatTimes.setVisibility(View.GONE);
repeatTimesText.setVisibility(View.GONE);
} else if (count > 0) {

@ -58,7 +58,7 @@ public class RepeatRuleToString {
R.string.repeats_single_on_until,
frequencyString,
dayString,
DateUtilities.getLongDateString(repeatUntil));
DateUtilities.getLongDateString(repeatUntil, locale.getLocale()));
}
} else if (count > 0) {
return context.getString(
@ -69,7 +69,7 @@ public class RepeatRuleToString {
return context.getString(
R.string.repeats_single_until,
frequencyString,
DateUtilities.getLongDateString(repeatUntil));
DateUtilities.getLongDateString(repeatUntil, locale.getLocale()));
}
} else {
int plural = getFrequencyPlural(frequency);
@ -90,7 +90,7 @@ public class RepeatRuleToString {
R.string.repeats_plural_on_until,
frequencyPlural,
dayString,
DateUtilities.getLongDateString(repeatUntil));
DateUtilities.getLongDateString(repeatUntil, locale.getLocale()));
}
} else if (count > 0) {
return context.getString(
@ -101,7 +101,7 @@ public class RepeatRuleToString {
return context.getString(
R.string.repeats_plural_until,
frequencyPlural,
DateUtilities.getLongDateString(repeatUntil));
DateUtilities.getLongDateString(repeatUntil, locale.getLocale()));
}
}
}

@ -2,7 +2,7 @@ package org.tasks.tasklist;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastKitKat;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
import static com.todoroo.andlib.utility.DateUtilities.getAbbreviatedRelativeDateWithTime;
import static com.todoroo.andlib.utility.DateUtilities.getRelativeDateTime;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -30,6 +30,7 @@ import org.tasks.dialogs.Linkify;
import org.tasks.preferences.Preferences;
import org.tasks.ui.CheckBoxProvider;
import org.tasks.ui.ChipProvider;
import org.threeten.bp.format.FormatStyle;
public class ViewHolder extends RecyclerView.ViewHolder {
@ -253,7 +254,9 @@ public class ViewHolder extends RecyclerView.ViewHolder {
} else {
dueDate.setTextColor(textColorSecondary);
}
String dateValue = getAbbreviatedRelativeDateWithTime(context, task.getDueDate());
String dateValue =
getRelativeDateTime(
context, task.getDueDate(), java.util.Locale.getDefault(), FormatStyle.MEDIUM);
dueDate.setText(dateValue);
dueDate.setVisibility(View.VISIBLE);
} else {

@ -18,6 +18,8 @@ import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import org.tasks.locale.Locale;
import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalDateTime;
public class DateTime {
@ -320,6 +322,14 @@ public class DateTime {
return timestamp == 0 ? null : new DateValueImpl(getYear(), getMonthOfYear(), getDayOfMonth());
}
public LocalDate toLocalDate() {
return timestamp == 0 ? null : LocalDate.of(getYear(), getMonthOfYear(), getDayOfMonth());
}
public LocalDateTime toLocalDateTime() {
return timestamp == 0 ? null : LocalDateTime.of(getYear(), getMonthOfYear(), getDayOfMonth(), getHourOfDay(), getMinuteOfHour());
}
public int getDayOfWeekInMonth() {
return getCalendar().get(Calendar.DAY_OF_WEEK_IN_MONTH);
}

@ -38,6 +38,7 @@ import org.tasks.dialogs.MyDatePickerDialog;
import org.tasks.dialogs.MyTimePickerDialog;
import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent;
import org.tasks.locale.Locale;
import org.tasks.preferences.Preferences;
import org.tasks.time.DateTime;
@ -54,6 +55,7 @@ public class DeadlineControlSet extends TaskEditControlFragment {
@Inject Preferences preferences;
@Inject @ForActivity Context context;
@Inject Locale locale;
@BindView(R.id.due_date)
Spinner dueDateSpinner;
@ -364,7 +366,7 @@ public class DeadlineControlSet extends TaskEditControlFragment {
} else if (date == today.plusWeeks(1).getMillis()) {
dueDateOptions.set(0, nextWeekString);
} else {
dueDateOptions.set(0, DateUtilities.getLongDateString(newDateTime(date)));
dueDateOptions.set(0, DateUtilities.getLongDateString(newDateTime(date), locale.getLocale()));
}
}
dueDateOptions.set(3, nextWeekString);

@ -28,6 +28,7 @@ import org.tasks.locale.Locale;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
import org.tasks.ui.CheckBoxProvider;
import org.threeten.bp.format.FormatStyle;
import timber.log.Timber;
class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
@ -36,6 +37,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private final TaskDao taskDao;
private final DefaultFilterProvider defaultFilterProvider;
private final CheckBoxProvider checkBoxProvider;
private final Locale locale;
private final SubtasksHelper subtasksHelper;
private final Preferences preferences;
private final WidgetPreferences widgetPreferences;
@ -60,7 +62,8 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
int widgetId,
TaskDao taskDao,
DefaultFilterProvider defaultFilterProvider,
CheckBoxProvider checkBoxProvider) {
CheckBoxProvider checkBoxProvider,
Locale locale) {
this.subtasksHelper = subtasksHelper;
this.preferences = preferences;
this.context = context;
@ -68,6 +71,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
this.taskDao = taskDao;
this.defaultFilterProvider = defaultFilterProvider;
this.checkBoxProvider = checkBoxProvider;
this.locale = locale;
widgetPreferences = new WidgetPreferences(context, preferences, widgetId);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
widgetPadding = (int)(10 * metrics.density);
@ -220,7 +224,8 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
row.setViewVisibility(R.id.widget_due_date, View.VISIBLE);
row.setTextViewText(
R.id.widget_due_date,
DateUtilities.getRelativeDateStringWithTime(context, task.getDueDate()));
DateUtilities.getRelativeDateTime(
context, task.getDueDate(), locale.getLocale(), FormatStyle.MEDIUM));
//noinspection ResourceAsColor
row.setTextColor(
R.id.widget_due_date,

@ -57,6 +57,7 @@ public class ScrollableWidgetUpdateService extends RemoteViewsService {
widgetId,
taskDao,
defaultFilterProvider,
new CheckBoxProvider(context, new ColorProvider(context, preferences)));
new CheckBoxProvider(context, new ColorProvider(context, preferences)),
locale);
}
}

@ -261,7 +261,6 @@
<string name="repeat_number_of_times">Повтаряй брой пъти</string>
<string name="repeat_occurs">Възниква</string>
<string name="repeat_snackbar">%1$s е насрочено за %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s в %2$s</string>
<string name="new_tag">Нов таг</string>
<string name="new_list">Създаване на нов списък</string>
<string name="tag_FEx_untagged">Без категория</string>

@ -368,7 +368,6 @@
<string name="repeat_type_completion">okamžiku dokočení</string>
<string name="repeat_occurs">Vyskytne se</string>
<string name="repeat_snackbar">Úkol %1$s byl znovu naplánován na %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. 'Tomorrow at 8 AM' or '21 May at 8 AM'">%1$s na %2$s</string>
<string name="new_list">Vytvořit nový seznam</string>
<string name="EPr_voiceRemindersEnabled_desc_enabled">Aplikace bude nahlas číst název úkolu při upozornění</string>
<string name="attachment_directory">Adresář příloh</string>

@ -257,7 +257,6 @@
<string name="repeat_number_of_times">Wiederhole n-mal</string>
<string name="repeat_occurs">Tritt ein</string>
<string name="repeat_snackbar">%1$s neu geplant für %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s um %2$s</string>
<string name="new_tag">Neues Schlagwort erstellen</string>
<string name="new_list">Neue Liste erstellen</string>
<string name="tag_FEx_untagged">Nicht kategorisiert</string>

@ -262,7 +262,6 @@
<string name="repeat_number_of_times">Repetir un número de veces</string>
<string name="repeat_occurs">Número de repeticiones</string>
<string name="repeat_snackbar">%1$s He reprogramado esta tarea recurrente para %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s a %2$s</string>
<string name="new_tag">Crear nueva etiqueta</string>
<string name="new_list">Crea una nueva lista</string>
<string name="tag_FEx_untagged">Sin Categoría</string>

@ -266,7 +266,6 @@
<string name="repeat_number_of_times">Errepikatu aldi kopuru bat</string>
<string name="repeat_occurs">Errepikapenak</string>
<string name="repeat_snackbar">"%1$s %2$s-rako programatuta"</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. 'Tomorrow at 8 AM' or '21 May at 8 AM'">%1$s %2$s(e)tan</string>
<string name="new_tag">Sortu etiketa berria</string>
<string name="new_list">Sortu zerrenda berria</string>
<string name="tag_FEx_untagged">Kategoria gabe</string>

@ -247,7 +247,6 @@
<string name="repeat_number_of_times">Nombre de répétitions</string>
<string name="repeat_occurs">Se répète</string>
<string name="repeat_snackbar">%1$s replanifiée à %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s à %2$s</string>
<string name="new_tag">Créer un nouveau tag</string>
<string name="new_list">Créer une nouvelle liste</string>
<string name="tag_FEx_untagged">Non classé</string>

@ -261,7 +261,6 @@
<string name="repeat_number_of_times">Ismétlés meghatározott alkalommal</string>
<string name="repeat_occurs">Előfordul</string>
<string name="repeat_snackbar">%1$s újraütemezve ekkorra: %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s ekkor: %2$s</string>
<string name="new_tag">Új címke létrehozása</string>
<string name="new_list">Új lista létrehozása</string>
<string name="tag_FEx_untagged">Kategória nélküli</string>

@ -259,7 +259,6 @@
<string name="repeat_number_of_times">Ripeti un dato numero di volte</string>
<string name="repeat_occurs">Si verifica</string>
<string name="repeat_snackbar">%1$s ripianificata per %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s alle %2$s</string>
<string name="new_tag">Crea nuova etichetta</string>
<string name="new_list">Crea nuova lista</string>
<string name="tag_FEx_untagged">Non classificate</string>

@ -294,7 +294,6 @@
<string name="repeat_number_of_times">חוזר מספר פעמים</string>
<string name="repeat_occurs">קורה</string>
<string name="repeat_snackbar">%1$s תזמן מחדש משימה חוזרת זו ל־%2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s בשעה %2$s</string>
<string name="new_tag">יצירת תגית חדשה</string>
<string name="new_list">יצירת רשימה חדשה</string>
<string name="tag_FEx_untagged">ללא קיטלוג</string>

@ -259,7 +259,6 @@
<string name="repeat_number_of_times">繰り返し回数</string>
<string name="repeat_occurs">発生</string>
<string name="repeat_snackbar">%1$s を %2$s にスケジュール変更しました</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s %2$s</string>
<string name="new_tag">新しいタグを作成</string>
<string name="new_list">新しいリストを作成</string>
<string name="tag_FEx_untagged">未分類</string>

@ -263,7 +263,6 @@
<string name="repeat_number_of_times">여러회 반복</string>
<string name="repeat_occurs">반복횟수</string>
<string name="repeat_snackbar">%1$s 이 %2$s 로 변경되었습니다</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s %2$s</string>
<string name="new_tag">새 태그 만들기</string>
<string name="new_list">새 목록 만들기</string>
<string name="tag_FEx_untagged">미분류 할일</string>

@ -258,7 +258,6 @@
<string name="repeat_number_of_times">Kartoti nustatytą kiekį kartų</string>
<string name="repeat_occurs">Įvyksta</string>
<string name="repeat_snackbar">%1$s perplanuotas šiai datai: %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s %2$s metu</string>
<string name="new_tag">Sukurti naują etiketę</string>
<string name="new_list">Sukurti naują sąrašą</string>
<string name="tag_FEx_untagged">Nekategorizuotos</string>

@ -325,7 +325,6 @@
<string name="repeat_number_of_times">Gjenta et antall ganger</string>
<string name="repeat_occurs">Inntreffer</string>
<string name="repeat_snackbar">%1$s flyttet til %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. 'Tomorrow at 8 AM' or '21 May at 8 AM'">%1$s %2$s</string>
<string name="new_tag">Opprett en ny etikett</string>
<string name="new_list">Opprett en ny liste</string>
<string name="delete_tag_confirmation">Slett %s\?</string>

@ -258,7 +258,6 @@
<string name="repeat_number_of_times">Herhaal een aantal keer</string>
<string name="repeat_occurs">Keren</string>
<string name="repeat_snackbar">%1$s opnieuw ingepland op %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s om %2$s</string>
<string name="new_tag">Nieuw label aanmaken</string>
<string name="new_list">Nieuwe lijst aanmaken</string>
<string name="tag_FEx_untagged">Niet gecategoriseerd</string>

@ -272,7 +272,6 @@
<string name="repeat_number_of_times">Powtarzaj podaną ilość razy</string>
<string name="repeat_occurs">Występuje</string>
<string name="repeat_snackbar">%1$s przełożone na %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s o %2$s</string>
<string name="new_tag">Stwórz nowy tag</string>
<string name="new_list">Utwórz nową listę</string>
<string name="tag_FEx_untagged">Na żadnej liście</string>

@ -259,7 +259,6 @@
<string name="repeat_number_of_times">Repetir um número de vezes</string>
<string name="repeat_occurs">Ocorre</string>
<string name="repeat_snackbar">%1$s remarcada para %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s as %2$s</string>
<string name="new_tag">Criar nova etiqueta</string>
<string name="new_list">Criar nova lista</string>
<string name="tag_FEx_untagged">Sem categoria</string>

@ -278,7 +278,6 @@
<string name="repeat_number_of_times">Повторять несколько раз</string>
<string name="repeat_occurs">Повторять</string>
<string name="repeat_snackbar">«%1$s» перенесено на %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s в %2$s</string>
<string name="new_tag">Создать новый тег</string>
<string name="new_list">Создать новый список</string>
<string name="tag_FEx_untagged">Без тега</string>

@ -259,7 +259,6 @@
<string name="repeat_number_of_times">Opakovať určitý počet krát</string>
<string name="repeat_occurs">Vyskytuje sa</string>
<string name="repeat_snackbar">%1$s preložené na %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s, %2$s</string>
<string name="new_tag">Vytvoriť nový štítok</string>
<string name="new_list">Vytvoriť nový zoznam</string>
<string name="tag_FEx_untagged">Nezaradené</string>

@ -367,7 +367,6 @@
<string name="repeat_type_completion">datum färdigställt</string>
<string name="repeat_number_of_times">Repetera ett visst antal gånger</string>
<string name="repeat_occurs">Inträffar</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. 'Tomorrow at 8 AM' or '21 May at 8 AM'">%1$s vid %2$s</string>
<string name="TEA_timer_controls">Timer</string>
<string name="google_drive_backup">Kopiera till Google Drive</string>
<string name="row_spacing">Radavstånd</string>

@ -264,7 +264,6 @@
<string name="repeat_number_of_times">Birkaç kez yinele</string>
<string name="repeat_occurs">Şu kadar gerçekleşir</string>
<string name="repeat_snackbar">%1$s, %2$s için yeniden zamanlandı</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s saat %2$s</string>
<string name="new_tag">Yeni etiket oluştur</string>
<string name="new_list">Yeni liste oluştur</string>
<string name="tag_FEx_untagged">Kategorilendirilmemiş</string>

@ -261,7 +261,6 @@
<string name="repeat_number_of_times">Повторити кількість разів</string>
<string name="repeat_occurs">Станеться</string>
<string name="repeat_snackbar">%1$s перенесено на %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s о %2$s</string>
<string name="new_tag">Створити новий ярлик</string>
<string name="new_list">Новий список</string>
<string name="tag_FEx_untagged">Без категорії</string>

@ -248,7 +248,6 @@
<string name="repeat_number_of_times">重复多次</string>
<string name="repeat_occurs">发生</string>
<string name="repeat_snackbar">%1$s 重新安排在 %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. \'Tomorrow at 8 AM\' or \'21 May at 8 AM\'">%1$s 的 %2$s</string>
<string name="new_tag">新建标签</string>
<string name="new_list">新建列表</string>
<string name="tag_FEx_untagged">未分类</string>

@ -275,7 +275,6 @@ File %1$s contained %2$s.\n\n
<string name="repeat_number_of_times">Repeat a number of times</string>
<string name="repeat_occurs">Occurs</string>
<string name="repeat_snackbar">%1$s rescheduled for %2$s</string>
<string name="repeat_snackbar_time" comment="display new due date and time in snackbar after completing repeating task, e.g. 'Tomorrow at 8 AM' or '21 May at 8 AM'">%1$s at %2$s</string>
<string name="new_tag">Create new tag</string>
<string name="new_list">Create new list</string>
<string name="tag_FEx_untagged">Uncategorized</string>

Loading…
Cancel
Save