Skip to content

Commit

Permalink
#7 Fix Date formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
yvolk committed Feb 14, 2020
1 parent 45110fc commit 28874da
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.andstatus.todoagenda.prefs;

import org.andstatus.todoagenda.BaseWidgetTest;
import org.andstatus.todoagenda.prefs.dateformat.DateFormatType;
import org.andstatus.todoagenda.prefs.dateformat.DateFormatValue;
import org.andstatus.todoagenda.prefs.dateformat.DateFormatter;
import org.joda.time.DateTime;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
* @author [email protected]
*/
public class DateFormatterTest extends BaseWidgetTest {

@Test
public void timeTimeZones() {
InstanceSettings settings = getSettings();
settings.clock().setSnapshotMode(SnapshotMode.SNAPSHOT_TIME);
assertNow("2020-02-15T01:00:00.000+08:00");
assertNow("2020-02-15T23:00:00.000+08:00");
assertNow("2020-02-29T01:00:00.000+08:00");
assertNow("2020-02-29T23:00:00.000+08:00");
assertNow("2020-02-15T01:00:00.000-05:00");
assertNow("2020-02-15T23:00:00.000-05:00");
assertNow("2020-02-29T01:00:00.000-05:00");
assertNow("2020-02-29T23:00:00.000-05:00");
assertNow("2025-03-01T23:00:00.000-01:00");
}

private void assertNow(String pattern) {
DateTime now = DateTime.parse(pattern);
getSettings().clock().setSnapshotDate(now);

assertPattern(now, "MM-dd b", String.format("%02d-%02d", now.monthOfYear().get(),
now.dayOfMonth().get()) + " 0");

DateTime yesterday = now.minusDays(1);
assertPattern(yesterday, "MM-dd b", String.format("%02d-%02d", yesterday.monthOfYear().get(),
yesterday.dayOfMonth().get()) + " -1");
assertPattern(yesterday, "b MM.dd", "-1 " + String.format("%02d.%02d", yesterday.monthOfYear().get(),
yesterday.dayOfMonth().get()));
assertPattern(yesterday, "MM.b.dd", String.format("%02d.-1.%02d", yesterday.monthOfYear().get(),
yesterday.dayOfMonth().get()));

DateTime tomorrow = now.plusDays(1);
assertPattern(tomorrow, "MM-dd b", String.format("%02d-%02d", tomorrow.monthOfYear().get(),
tomorrow.dayOfMonth().get()) + " 1");
}

@Test
public void customPatterns() {
InstanceSettings settings = getSettings();
settings.clock().setSnapshotMode(SnapshotMode.SNAPSHOT_TIME);
DateTime now = settings.clock().now().withTimeAtStartOfDay().plusHours(1);
settings.clock().setSnapshotDate(now);

assertPattern(now, "yyyy-MM-dd b", String.format("%04d-%02d-%02d", now.yearOfEra().get(),
now.monthOfYear().get(), now.dayOfMonth().get()) + " 0");
assertPattern(now, "b", "0");
assertPattern(now, "MM-dd bb", String.format("%02d-%02d", now.monthOfYear().get(), now.dayOfMonth().get()) + " 00");
assertPattern(now.plusDays(1), "", "");
assertPattern(now.plusDays(1), "b", "1");
assertPattern(now.plusDays(1), "'begin' b", "begin 1");
}

private void assertPattern(DateTime date, String pattern, String expected) {
DateFormatValue format = DateFormatValue.of(DateFormatType.CUSTOM, pattern);
DateTime now = getSettings().clock().now();
DateFormatter formatter = new DateFormatter(getSettings().getContext(), format, now);
assertEquals("Date: " + date + ", Now:" + now + ", Pattern: [" + pattern + "]", expected, formatter.formatDate(date));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.andstatus.todoagenda.prefs.AllSettings;
import org.andstatus.todoagenda.prefs.ApplicationPreferences;
import org.andstatus.todoagenda.prefs.InstanceSettings;
import org.joda.time.DateTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -85,7 +86,7 @@ protected View onCreateDialogView(Context context) {

private CharSequence getSampleDateText() {
return new DateFormatter(getContext(), sampleDateFormatValue, getSettings().clock().now())
.formatMillis(getSettings().clock().now().getMillis());
.formatDate(getSettings().clock().now());
}

@Override
Expand Down Expand Up @@ -150,7 +151,7 @@ private void calcResult() {
result = sampleDate == null
? "null"
: new DateFormatter(this.getContext(), dateFormatValue, getSettings().clock().now())
.formatMillis(sampleDate.getTime());
.formatDate(new DateTime(sampleDate.getTime(), getSettings().clock().getZone()));
} catch (ParseException e) {
result = e.getLocalizedMessage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public String save() {
}

public boolean hasPattern() {
return StringUtil.nonEmpty(getPattern());
return type == CUSTOM || StringUtil.nonEmpty(getPattern());
}

public String getPattern() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import android.text.format.DateUtils;

import org.andstatus.todoagenda.R;
import org.andstatus.todoagenda.util.StringUtil;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Instant;

import java.text.SimpleDateFormat;
import java.util.Date;
Expand All @@ -42,27 +42,27 @@ public DateFormatter(Context context, DateFormatValue dateFormatValue, DateTime
this.now = now;
}

public CharSequence formatMillis(long millis) {
public CharSequence formatDate(DateTime date) {
try {
if(dateFormatValue.hasPattern()) {
return formatDateCustom(millis, dateFormatValue.getPattern());
return formatDateCustom(date, dateFormatValue.getPattern());
}

switch (dateFormatValue.type) {
case HIDDEN:
return "";
case DEVICE_DEFAULT:
return formatDateTime(millis, DateUtils.FORMAT_SHOW_DATE);
return formatDateTime(date, DateUtils.FORMAT_SHOW_DATE);
case DEFAULT_WEEKDAY:
return formatDateTime(millis, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY);
return formatDateTime(date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY);
case ABBREVIATED:
return formatDateTime(millis, DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
return formatDateTime(date, DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_SHOW_WEEKDAY);
case DEFAULT_DAYS:
return getNumberOfDaysToEventString(context, 5, getNumberOfDaysToEvent(millis)) + ", " +
formatDateTime(millis, DateUtils.FORMAT_SHOW_DATE);
return getNumberOfDaysToEventString(context, 5, getNumberOfDaysToEvent(date)) + ", " +
formatDateTime(date, DateUtils.FORMAT_SHOW_DATE);
case NUMBER_OF_DAYS:
return getNumberOfDaysToEventString(context, 5, getNumberOfDaysToEvent(millis));
return getNumberOfDaysToEventString(context, 5, getNumberOfDaysToEvent(date));
default:
return "(not implemented)";
}
Expand All @@ -71,7 +71,8 @@ public CharSequence formatMillis(long millis) {
}
}

private String formatDateTime(long millis, int flags) {
private String formatDateTime(DateTime date, int flags) {
long millis = toJavaDate(date).getTime();
return DateUtils.formatDateRange(context,
new Formatter(new StringBuilder(50), locale),
millis,
Expand All @@ -81,8 +82,12 @@ private String formatDateTime(long millis, int flags) {
.toString();
}

public static Date toJavaDate(DateTime date) {
return new Date(date.getYearOfEra() - 1900, date.getMonthOfYear() - 1, date.getDayOfMonth());
}

public static CharSequence getNumberOfDaysToEventString(Context context, int formatLength, int daysToEvent) {
if (formatLength > 4) {
if (formatLength >= 4) {
switch (daysToEvent) {
case -1:
return context.getText(R.string.yesterday);
Expand All @@ -94,36 +99,53 @@ public static CharSequence getNumberOfDaysToEventString(Context context, int for
break;
}
}
return Math.abs(daysToEvent) > 9999 ? "..." : Integer.toString(daysToEvent);
if (Math.abs(daysToEvent) > 9999) return "...";

CharSequence days1 = Integer.toString(daysToEvent);
if (days1.length() > formatLength) return days1;

return String.format("%0" + formatLength + "d", daysToEvent);
}

public int getNumberOfDaysToEvent(long millis) {
return Days.daysBetween(now.withTimeAtStartOfDay(),
Instant.ofEpochMilli(millis)).getDays();
public int getNumberOfDaysToEvent(DateTime date) {
return Days.daysBetween(now.withTimeAtStartOfDay(), date.withTimeAtStartOfDay())
.getDays();
}

private String formatDateCustom(long millis, String pattern) {
private String formatDateCustom(DateTime date, String pattern) {
if (StringUtil.isEmpty(pattern)) return "";

try {
String pattern2 = preProcessNumberOfDaysToEvent(millis, pattern);
SimpleDateFormat format = new SimpleDateFormat(pattern2, locale);
Date date = new Date(millis);
return format.format(date);
String pattern2 = preProcessNumberOfDaysToEvent(date, pattern);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern2, locale);
return simpleDateFormat.format(toJavaDate(date));
} catch (Exception e) {
return e.getLocalizedMessage();
}
}

private String preProcessNumberOfDaysToEvent(long millis, String pattern) {
int ind1 = pattern.indexOf(NUMBER_OF_DAYS_LETTER);
private String preProcessNumberOfDaysToEvent(DateTime date, String pattern) {
int ind1 = getIndexOfNumberOfDaysLetter(pattern);
if (ind1 < 0) return pattern;

int ind2 = ind1;
while (ind2 < pattern.length() && pattern.charAt(ind2) == NUMBER_OF_DAYS_LETTER) {
ind2++;
}
CharSequence result = getNumberOfDaysToEventString(context, ind2 - ind1, getNumberOfDaysToEvent(millis));
CharSequence result = getNumberOfDaysToEventString(context, ind2 - ind1, getNumberOfDaysToEvent(date));
return (ind1 > 0 ? pattern.substring(0, ind1) : "") +
"'" + result + "'" +
(ind2 < pattern.length() ? pattern.substring(ind2) : "");
}

private int getIndexOfNumberOfDaysLetter(String pattern) {
boolean inQuotes = false;
for (int ind = 0; ind < pattern.length(); ind++) {
if ((pattern.charAt(ind) == NUMBER_OF_DAYS_LETTER) && !inQuotes) return ind;

if (pattern.charAt(ind) == '\'') inQuotes = !inQuotes;
}
return -1;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public boolean duplicates(WidgetEntry other) {
public CharSequence formatEntryDate() {
return settings.getEntryDateFormat().type == DateFormatType.HIDDEN
? ""
: settings.newDateformatter().formatMillis(entryDate.getMillis());
: settings.newDateformatter().formatDate(entryDate);
}

@Override
Expand Down

0 comments on commit 28874da

Please sign in to comment.