1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.calendar.common;
18 
19 import static android.text.format.DateUtils.FORMAT_ABBREV_ALL;
20 import static android.text.format.DateUtils.FORMAT_NO_YEAR;
21 import static android.text.format.DateUtils.FORMAT_SHOW_TIME;
22 
23 import android.content.Context;
24 import android.icu.text.DisplayContext;
25 import android.icu.text.RelativeDateTimeFormatter;
26 import android.icu.util.ULocale;
27 import android.text.format.DateUtils;
28 
29 import java.text.DateFormat;
30 import java.text.SimpleDateFormat;
31 import java.time.Clock;
32 import java.time.Instant;
33 import java.time.LocalDate;
34 import java.time.ZonedDateTime;
35 import java.util.Date;
36 import java.util.Formatter;
37 import java.util.Locale;
38 import java.util.TimeZone;
39 
40 /** App specific text formatting utility. */
41 public class CalendarFormatter {
42     private static final String TAG = "CarCalendarFormatter";
43     private static final String SPACED_BULLET = " \u2022 ";
44     private final Context mContext;
45     private final Locale mLocale;
46     private final Clock mClock;
47     private final DateFormat mDateFormat;
48 
CalendarFormatter(Context context, Locale locale, Clock clock)49     public CalendarFormatter(Context context, Locale locale, Clock clock) {
50         mContext = context;
51         mLocale = locale;
52         mClock = clock;
53 
54         String pattern =
55                 android.text.format.DateFormat.getBestDateTimePattern(mLocale, "EEE, d MMM");
56         mDateFormat = new SimpleDateFormat(pattern, mLocale);
57         mDateFormat.setTimeZone(TimeZone.getTimeZone(mClock.getZone()));
58     }
59 
60     /** Formats the given date to text. */
getDateText(LocalDate localDate)61     public String getDateText(LocalDate localDate) {
62         RelativeDateTimeFormatter formatter =
63                 RelativeDateTimeFormatter.getInstance(
64                         ULocale.forLocale(mLocale),
65                         null,
66                         RelativeDateTimeFormatter.Style.LONG,
67                         DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE);
68 
69         LocalDate today = LocalDate.now(mClock);
70         LocalDate tomorrow = today.plusDays(1);
71         LocalDate dayAfter = tomorrow.plusDays(1);
72 
73         String relativeDay = null;
74         if (localDate.equals(today)) {
75             relativeDay =
76                     formatter.format(
77                             RelativeDateTimeFormatter.Direction.THIS,
78                             RelativeDateTimeFormatter.AbsoluteUnit.DAY);
79         } else if (localDate.equals(tomorrow)) {
80             relativeDay =
81                     formatter.format(
82                             RelativeDateTimeFormatter.Direction.NEXT,
83                             RelativeDateTimeFormatter.AbsoluteUnit.DAY);
84         } else if (localDate.equals(dayAfter)) {
85             relativeDay =
86                     formatter.format(
87                             RelativeDateTimeFormatter.Direction.NEXT_2,
88                             RelativeDateTimeFormatter.AbsoluteUnit.DAY);
89         }
90 
91         StringBuilder result = new StringBuilder();
92         if (relativeDay != null) {
93             result.append(relativeDay);
94             result.append(SPACED_BULLET);
95         }
96 
97         ZonedDateTime zonedDateTime = localDate.atStartOfDay(mClock.getZone());
98         Date date = new Date(zonedDateTime.toInstant().toEpochMilli());
99         result.append(mDateFormat.format(date));
100         return result.toString();
101     }
102 
103     /** Formats the given time to text. */
getTimeRangeText(Instant start, Instant end)104     public String getTimeRangeText(Instant start, Instant end) {
105         Formatter formatter = new Formatter(new StringBuilder(50), mLocale);
106         return DateUtils.formatDateRange(
107                         mContext,
108                         formatter,
109                         start.toEpochMilli(),
110                         end.toEpochMilli(),
111                         FORMAT_SHOW_TIME | FORMAT_NO_YEAR | FORMAT_ABBREV_ALL,
112                         mClock.getZone().getId())
113                 .toString();
114     }
115 }
116