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