From 62e89933d667e5d9c86a1cecaa6f934698803c6b Mon Sep 17 00:00:00 2001 From: conradchen Date: Wed, 1 Dec 2021 17:02:29 -0500 Subject: [PATCH] [DatePicker] Fix wrong month title with certain months The issue is caused by failing to correctly take the daylight saving time into account - internally we use UTC time to represent dates, however when generating month titles we try to calculate the time difference of the UTC time and the local time, which can result in off-by-one errors when the first day of the month is also the first day of the daylight saving time, e.g., April 1, 1979 in Poland. Fixes this by always using UTC time to generate month titles. Also clears the relevant implementation for a little bit since context is actually not required when we only need to format years and months. Resolves https://github.com/material-components/material-components-android/issues/1935 PiperOrigin-RevId: 413505587 --- .../google/android/material/datepicker/DateStrings.java | 9 +++------ .../android/material/datepicker/MaterialCalendar.java | 2 +- .../com/google/android/material/datepicker/Month.java | 5 ++--- .../android/material/datepicker/MonthsPagerAdapter.java | 6 ++---- .../material/datepicker/MonthsPagerAdapterTest.java | 6 +++--- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/lib/java/com/google/android/material/datepicker/DateStrings.java b/lib/java/com/google/android/material/datepicker/DateStrings.java index 19f1be000be..5d9cccbe716 100644 --- a/lib/java/com/google/android/material/datepicker/DateStrings.java +++ b/lib/java/com/google/android/material/datepicker/DateStrings.java @@ -15,7 +15,6 @@ */ package com.google.android.material.datepicker; -import android.content.Context; import android.icu.text.DateFormat; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; @@ -26,17 +25,15 @@ import java.util.Calendar; import java.util.Date; import java.util.Locale; -import java.util.TimeZone; /** Util methods for formatting date strings for use in {@link MaterialDatePicker}. */ class DateStrings { private DateStrings() {} - static String getYearMonth(Context context, long timeInMillis) { - int flags = DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_NO_MONTH_DAY; - long offsetMillis = TimeZone.getDefault().getOffset(timeInMillis); - return DateUtils.formatDateTime(context, timeInMillis - offsetMillis, flags); + static String getYearMonth(long timeInMillis) { + int flags = DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_NO_MONTH_DAY | DateUtils.FORMAT_UTC; + return DateUtils.formatDateTime(null, timeInMillis, flags); } static String getYearMonthDay(long timeInMillis) { diff --git a/lib/java/com/google/android/material/datepicker/MaterialCalendar.java b/lib/java/com/google/android/material/datepicker/MaterialCalendar.java index d409acf1011..810080a2f4c 100644 --- a/lib/java/com/google/android/material/datepicker/MaterialCalendar.java +++ b/lib/java/com/google/android/material/datepicker/MaterialCalendar.java @@ -390,7 +390,7 @@ public void onInitializeAccessibilityNodeInfo( yearFrame = root.findViewById(R.id.mtrl_calendar_year_selector_frame); dayFrame = root.findViewById(R.id.mtrl_calendar_day_selector_frame); setSelector(CalendarSelector.DAY); - monthDropSelect.setText(current.getLongName(root.getContext())); + monthDropSelect.setText(current.getLongName()); recyclerView.addOnScrollListener( new OnScrollListener() { @Override diff --git a/lib/java/com/google/android/material/datepicker/Month.java b/lib/java/com/google/android/material/datepicker/Month.java index 42864a10778..508faa1d850 100644 --- a/lib/java/com/google/android/material/datepicker/Month.java +++ b/lib/java/com/google/android/material/datepicker/Month.java @@ -15,7 +15,6 @@ */ package com.google.android.material.datepicker; -import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import androidx.annotation.IntDef; @@ -189,9 +188,9 @@ Month monthsLater(int months) { /** Returns a localized String representation of the month name and year. */ @NonNull - String getLongName(Context context) { + String getLongName() { if (longName == null) { - longName = DateStrings.getYearMonth(context, firstOfMonth.getTimeInMillis()); + longName = DateStrings.getYearMonth(firstOfMonth.getTimeInMillis()); } return longName; } diff --git a/lib/java/com/google/android/material/datepicker/MonthsPagerAdapter.java b/lib/java/com/google/android/material/datepicker/MonthsPagerAdapter.java index 9fd4896cfb7..82f526d206f 100644 --- a/lib/java/com/google/android/material/datepicker/MonthsPagerAdapter.java +++ b/lib/java/com/google/android/material/datepicker/MonthsPagerAdapter.java @@ -37,7 +37,6 @@ */ class MonthsPagerAdapter extends RecyclerView.Adapter { - private final Context context; @NonNull private final CalendarConstraints calendarConstraints; private final DateSelector dateSelector; private final OnDayClickListener onDayClickListener; @@ -63,7 +62,6 @@ class MonthsPagerAdapter extends RecyclerView.Adapter