diff --git a/app/src/main/java/org/isoron/uhabits/helpers/DateHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/DateHelper.java index b2c300453..5d6685984 100644 --- a/app/src/main/java/org/isoron/uhabits/helpers/DateHelper.java +++ b/app/src/main/java/org/isoron/uhabits/helpers/DateHelper.java @@ -25,9 +25,12 @@ import android.text.format.DateFormat; import org.isoron.uhabits.R; import java.text.SimpleDateFormat; +import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; import java.util.TimeZone; public class DateHelper @@ -155,23 +158,122 @@ public class DateHelper } + /** + * Throughout the code, it is assumed that the weekdays are numbered + * from 0 (Saturday) to 6 (Friday). + * + * see https://github.com/iSoron/uhabits/issues/74 + * + * In the Java Calendar they are numbered from 1 (Sunday) to 7 (Saturday) + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
daydayNumberwdaysIndex
Su11
Mo22
Tu33
We44
Th55
Fr66
Sa70
+ * + * So we have {@code wdaysIndex = dayNumber % 7} + * + * @return weekday number in the internal interpretation + * + * @see #getWeekday(long) + * @see java.util.Calendar#SUNDAY + * + */ + public static int weekDayNumber2wdays(int number) + { + return number % 7; + } + public static String[] getDayNames(int format) { String[] wdays = new String[7]; - GregorianCalendar day = new GregorianCalendar(); - day.set(GregorianCalendar.DAY_OF_WEEK, 0); + Calendar day = new GregorianCalendar(); + // we start with Saturday + day.set(GregorianCalendar.DAY_OF_WEEK, Calendar.SATURDAY); - for (int i = 0; i < 7; i++) + for (int i = 0; i < wdays.length; i++) { wdays[i] = day.getDisplayName(GregorianCalendar.DAY_OF_WEEK, format, Locale.getDefault()); + // advance in time by one day day.add(GregorianCalendar.DAY_OF_MONTH, 1); } return wdays; } + + /** + * + * @return array with weekday names starting according to locale settings, + * e.g. [Mo,Di,Mi,Do,Fr,Sa,So] in Europe + * + */ + public static String[] getLocaleDayNames(int format) + { + String[] days = new String[7]; + + Calendar calendar = new GregorianCalendar(); + calendar.set(GregorianCalendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); + for (int i = 0; i < days.length; i++) + { + days[i] = calendar.getDisplayName(GregorianCalendar.DAY_OF_WEEK, format, + Locale.getDefault()); + // advance in time by one day + calendar.add(GregorianCalendar.DAY_OF_MONTH, 1); + } + + return days; + } + + /** + * + * @return array with week days numbers starting according to locale settings, + * e.g. [2,3,4,5,6,7,1] in Europe + * + * @see java.util.Calendar#SUNDAY + * + */ + public static Integer[] getLocaleWeekdayList() + { + Integer[] dayNumbers = new Integer[7]; + // a dummy calendar + Calendar calendar = new GregorianCalendar(); + // set staring day according to locale + calendar.set(GregorianCalendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); + for (int i = 0; i < dayNumbers.length; i++) { + dayNumbers[i] = calendar.get(GregorianCalendar.DAY_OF_WEEK); + // advance in time by one day + calendar.add(GregorianCalendar.DAY_OF_MONTH, 1); + } + return dayNumbers; + } + + /** + * here we create the mapping of week days numbers into the "wdays"-indices + * + * @see DateHelper#getDayNames(int) + */ + public static Map getWeekdayMap() + { + Map number2wdays = new HashMap<>(); + for (Integer number : getLocaleWeekdayList()) { + number2wdays.put(number, number % 7); + } + return number2wdays; + } + public static String formatWeekdayList(Context context, boolean weekday[]) { String shortDayNames[] = getShortDayNames(); diff --git a/app/src/main/java/org/isoron/uhabits/views/HabitFrequencyView.java b/app/src/main/java/org/isoron/uhabits/views/HabitFrequencyView.java index c3d47d9f0..2da6d6e51 100644 --- a/app/src/main/java/org/isoron/uhabits/views/HabitFrequencyView.java +++ b/app/src/main/java/org/isoron/uhabits/views/HabitFrequencyView.java @@ -35,6 +35,7 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; +import java.util.Map; import java.util.Random; public class HabitFrequencyView extends ScrollableDataView implements HabitDataView @@ -62,7 +63,6 @@ public class HabitFrequencyView extends ScrollableDataView implements HabitDataV private boolean isBackgroundTransparent; private HashMap frequency; - private String wdays[]; public HabitFrequencyView(Context context) { @@ -89,8 +89,6 @@ public class HabitFrequencyView extends ScrollableDataView implements HabitDataV createPaints(); createColors(); - wdays = DateHelper.getShortDayNames(); - dfMonth = DateHelper.getDateFormat("MMM"); dfYear = DateHelper.getDateFormat("yyyy"); @@ -230,11 +228,13 @@ public class HabitFrequencyView extends ScrollableDataView implements HabitDataV float rowHeight = rect.height() / 8.0f; prevRect.set(rect); - for (int i = 0; i < 7; i++) + Integer[] localeWeekdayList = DateHelper.getLocaleWeekdayList(); + for (int j = 0; j < localeWeekdayList.length; j++) { rect.set(0, 0, baseSize, baseSize); - rect.offset(prevRect.left, prevRect.top + columnWidth * i); + rect.offset(prevRect.left, prevRect.top + columnWidth * j); + int i = DateHelper.weekDayNumber2wdays(localeWeekdayList[j]); if(values != null) drawMarker(canvas, rect, values[i]); @@ -272,9 +272,8 @@ public class HabitFrequencyView extends ScrollableDataView implements HabitDataV pText.setColor(textColor); pGrid.setColor(dimmedTextColor); - for (int i = 0; i < nRows; i++) - { - canvas.drawText(wdays[i], rGrid.right - columnWidth, + for (String day : DateHelper.getLocaleDayNames(Calendar.SHORT)) { + canvas.drawText(day, rGrid.right - columnWidth, rGrid.top + rowHeight / 2 + 0.25f * em, pText); pGrid.setStrokeWidth(1f); diff --git a/app/src/main/java/org/isoron/uhabits/views/HabitHistoryView.java b/app/src/main/java/org/isoron/uhabits/views/HabitHistoryView.java index 0958bf275..05315ef16 100644 --- a/app/src/main/java/org/isoron/uhabits/views/HabitHistoryView.java +++ b/app/src/main/java/org/isoron/uhabits/views/HabitHistoryView.java @@ -40,6 +40,7 @@ import org.isoron.uhabits.tasks.ToggleRepetitionTask; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.Map; import java.util.Random; public class HabitHistoryView extends ScrollableDataView implements HabitDataView, @@ -57,13 +58,13 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie private float columnHeight; private int nColumns; - private String wdays[]; private SimpleDateFormat dfMonth; private SimpleDateFormat dfYear; private Calendar baseDate; private int nDays; - private int todayWeekday; + /** 0-based-position of today in the column */ + private int todayPositionInColumn; private int colors[]; private RectF baseLocation; private int primaryColor; @@ -98,7 +99,6 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie isEditable = false; checkmarks = new int[0]; primaryColor = ColorHelper.palette[7]; - wdays = DateHelper.getShortDayNames(); dfMonth = DateHelper.getDateFormat("MMM"); dfYear = DateHelper.getDateFormat("yyyy"); @@ -111,10 +111,11 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie baseDate.add(Calendar.DAY_OF_YEAR, -(getDataOffset() - 1) * 7); nDays = (nColumns - 1) * 7; - todayWeekday = DateHelper.getStartOfTodayCalendar().get(Calendar.DAY_OF_WEEK) % 7; + int realWeekday = DateHelper.getStartOfTodayCalendar().get(Calendar.DAY_OF_WEEK); + todayPositionInColumn = (7 + realWeekday - baseDate.getFirstDayOfWeek()) % 7; baseDate.add(Calendar.DAY_OF_YEAR, -nDays); - baseDate.add(Calendar.DAY_OF_YEAR, -todayWeekday); + baseDate.add(Calendar.DAY_OF_YEAR, -todayPositionInColumn); } @Override @@ -155,7 +156,7 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie { float width = 0; - for(String w : wdays) + for(String w : DateHelper.getLocaleDayNames(Calendar.SHORT)) width = Math.max(width, pSquareFg.measureText(w)); return width; @@ -274,9 +275,9 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie for (int j = 0; j < 7; j++) { - if (!(column == nColumns - 2 && getDataOffset() == 0 && j > todayWeekday)) + if (!(column == nColumns - 2 && getDataOffset() == 0 && j > todayPositionInColumn)) { - int checkmarkOffset = getDataOffset() * 7 + nDays - 7 * (column + 1) + todayWeekday - j; + int checkmarkOffset = getDataOffset() * 7 + nDays - 7 * (column + 1) + todayPositionInColumn - j; drawSquare(canvas, location, date, checkmarkOffset); } @@ -298,10 +299,10 @@ public class HabitHistoryView extends ScrollableDataView implements HabitDataVie private void drawAxis(Canvas canvas, RectF location) { - for (int i = 0; i < 7; i++) + for (String day : DateHelper.getLocaleDayNames(Calendar.SHORT)) { location.offset(0, columnWidth); - canvas.drawText(wdays[i], location.left + headerTextOffset, + canvas.drawText(day, location.left + headerTextOffset, location.bottom - headerTextOffset, pTextHeader); } }