910e62b5创建于 1月15日历史提交
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_SYSTEM_TIME_CALENDAR_UTILS_H_
#define ASH_SYSTEM_TIME_CALENDAR_UTILS_H_

#include <optional>
#include <set>
#include <tuple>

#include "ash/ash_export.h"
#include "base/time/time.h"
#include "google_apis/calendar/calendar_api_response_types.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/insets.h"

namespace views {

class TableLayout;

}  // namespace views

namespace ash {

namespace calendar_utils {

// Number of days in one week.
constexpr int kDateInOneWeek = 7;

// Milliseconds per minute.
constexpr int kMillisecondsPerMinute = 60000;

// The padding in each date cell view.
constexpr int kDateVerticalPadding = 13;
constexpr int kDateHorizontalPadding = 16;
constexpr int kColumnSetPadding = 5;

// The insets for the event list item view.
constexpr int kEventListItemViewStartEndMargin = 12;

// The insets within a Date cell.
const auto kDateCellInsets =
    gfx::Insets::VH(kDateVerticalPadding, kDateHorizontalPadding);

// Duration of opacity animation for visibility changes.
constexpr base::TimeDelta kAnimationDurationForVisibility =
    base::Milliseconds(200);

// Fade-out and fade-in duration for resetting to today animation.
constexpr base::TimeDelta kResetToTodayFadeAnimationDuration =
    base::Milliseconds(100);

// Duration of moving animation.
constexpr base::TimeDelta kAnimationDurationForMoving = base::Milliseconds(300);

// Duration of month moving animation.
constexpr base::TimeDelta kAnimationDurationForMonthMoving =
    base::Milliseconds(600);

// This duration is added to a midnight `base::Time` to adjust the DST when
// adding days by `base::Day`.
//
// For example, in PST time zone, when we add 1 week (7 days) to Nov 3rd 00:00,
// the expected result is Nov 10th 00:00, but the actual result is Nov 9th
// 23:00. Because in Nov 6th is the DST end day and there are 25 hours in that
// day. By adding this time delta, the result is Nov 10th 4:00, which is the
// expected date.
constexpr base::TimeDelta kDurationForAdjustingDST = base::Hours(5);

// Duration subtracted from an existing midnight in UTC to get the
// previous day. It is less than 24 hours to consider daylight savings.
constexpr base::TimeDelta kDurationForGettingPreviousDay = base::Hours(20);

// The fetch of a user's calendar list or event list will terminate if a
// response is not received sooner than this.
constexpr base::TimeDelta kCalendarDataFetchTimeout = base::Seconds(10);

// Maximum number of selected calendars for which events should be fetched when
// Multi-Calendar Support is enabled.
constexpr int kMultipleCalendarsLimit = 10;

// Number of months, before and after the month currently on-display, that we
// cache-ahead.
constexpr int kNumSurroundingMonthsCached = 2;

// Maximum number of non-prunable months allowed, which is a function of
// kNumSurroundingMonthsCached.
constexpr int kMaxNumNonPrunableMonths = 2 * kNumSurroundingMonthsCached + 1;

// Maximum number of prunable months to cache. Note that this plus
// kMaxNumNonPrunableMonths is the total maximum number of cached months.
constexpr int kMaxNumPrunableMonths = 20;

// Between child spacing for `CalendarUpNextView`.
constexpr int kUpNextBetweenChildSpacing = 8;

// The `CalendarUpNextView` UI has a rounded 'nub' that sticks up in the middle
// of the view. To ensure that the scroll view animates nicely behind the up
// next view, we need to forcibly overlap the views slightly for the distance
// between the bottom and top of the 'nub'.
constexpr int kUpNextOverlapInPx = 12;

// Returns true if the Multi-Calendar Support feature is enabled.
bool IsMultiCalendarEnabled();

// Checks if the `selected_date` is local time today.
bool IsToday(const base::Time selected_date);

// Checks if the two exploded are in the same day.
bool IsTheSameDay(std::optional<base::Time> date_a,
                  std::optional<base::Time> date_b);

// Returns the set of months that includes |selected_date| and
// |num_months_out| before and after.
std::set<base::Time> GetSurroundingMonthsUTC(const base::Time& selected_date,
                                             int num_months_out);

// Gets the given `date`'s `Exploded` instance, in UTC time.
base::Time::Exploded GetExplodedUTC(const base::Time& date);

// Gets the `date`'s month name, numeric day of month, and year.
// (e.g. March 10, 2022)
ASH_EXPORT std::u16string GetMonthDayYear(const base::Time date);

// Gets the `date`'s month name, numeric day of month, year and day of week.
// (e.g. Wednesday, May 25, 2022)
ASH_EXPORT std::u16string GetMonthDayYearWeek(const base::Time date);

// Gets the `date`'s month name in string in the current language.
// (e.g. March)
ASH_EXPORT std::u16string GetMonthName(const base::Time date);

// Gets the `date`'s day of month in local format. For some languages, the
// formatter adds some words/characters which means `day` in that language to
// the digital day of month (e.g. 10日).
ASH_EXPORT std::u16string GetDayOfMonth(const base::Time date);

// Gets the `date`'s numeric day of month.
// (e.g. 10)
ASH_EXPORT std::u16string GetDayIntOfMonth(const base::Time local_date);

// Gets the `date`'s month name and the numeric day of month.
// (e.g. March 10)
ASH_EXPORT std::u16string GetMonthNameAndDayOfMonth(const base::Time date);

// Gets the `date`'s time in twelve hour clock format.
// (e.g. 10:31 PM)
ASH_EXPORT std::u16string GetTwelveHourClockTime(const base::Time date);

// Gets the `date`'s time in twenty four hour clock format.
// (e.g. 22:31)
ASH_EXPORT std::u16string GetTwentyFourHourClockTime(const base::Time date);

// Gets the `date`'s time zone.
// (e.g. Greenwich Mean Time)
ASH_EXPORT std::u16string GetTimeZone(const base::Time date);

// Gets the index of this day in the week, starts from 1. This number is
// different for different languages.
ASH_EXPORT std::u16string GetDayOfWeek(const base::Time date);

// Gets the `date`'s year.
// (e.g. 2022)
ASH_EXPORT std::u16string GetYear(const base::Time date);

// Gets the `date`'s month name and year.
// (e.g. March 2022)
ASH_EXPORT std::u16string GetMonthNameAndYear(const base::Time date);

// Gets the `date`'s hour in twelve hour clock format.
// (e.g. 9, when given 21:05)
// Some locales may add zero-padding.
ASH_EXPORT std::u16string GetTwelveHourClockHours(const base::Time date);

// Gets the `date`'s hour in twenty four hour clock format.
// (e.g. 21, when given 21:05)
// Some locales may add zero-padding.
ASH_EXPORT std::u16string GetTwentyFourHourClockHours(const base::Time date);

// Gets the `date`'s minutes with zero-padding.
// (e.g. 05, when given 22:05)
ASH_EXPORT std::u16string GetMinutes(const base::Time date);

// Gets the formatted interval between `start_time` and `end_time` in twelve
// hour clock format.
// (e.g. 8:30 – 9:30 PM or 11:30 AM – 2:30 PM)
ASH_EXPORT std::u16string FormatTwelveHourClockTimeInterval(
    const base::Time& start_time,
    const base::Time& end_time);

// Gets the formatted interval between `start_time` and `end_time` in twenty
// four hour clock format.
// (e.g. 20:30 – 21:30)
ASH_EXPORT std::u16string FormatTwentyFourHourClockTimeInterval(
    const base::Time& start_time,
    const base::Time& end_time);

// Sets up the `TableLayout` to have 7 columns, which is one week row (7 days).
void SetUpWeekColumns(views::TableLayout* layout);

// Computes the distance, in months, between `start_date` and `end_date`.
ASH_EXPORT int GetMonthsBetween(const base::Time& start_date,
                                const base::Time& end_date);

// Gets date with greater value between `d1` and `d2`.
ASH_EXPORT base::Time GetMaxTime(const base::Time d1, const base::Time d2);

// Gets date with lesser value between `d1` and `d2`.
ASH_EXPORT base::Time GetMinTime(const base::Time d1, const base::Time d2);

// Colors.
SkColor GetPrimaryTextColor();
SkColor GetSecondaryTextColor();
SkColor GetDisabledTextColor();

// Get the first day of the month that includes |date|.
ASH_EXPORT base::Time GetFirstDayOfMonth(const base::Time& date);

// Get the first day of the month before the one that includes |date|.
base::Time GetStartOfPreviousMonthLocal(base::Time date);

// Get the first day of the month after the one that includes |date|.
base::Time GetStartOfNextMonthLocal(base::Time date);

// Get UTC midnight on the first day of the month that includes |date|.
base::Time GetStartOfMonthUTC(const base::Time& date);

// Get UTC midnight on the first day of the month before the one that includes
// |date|.
base::Time GetStartOfPreviousMonthUTC(base::Time date);

// Get UTC midnight on the first day of the month after the one that includes
// |date|.
base::Time GetStartOfNextMonthUTC(base::Time date);

// Returns UTC midnight of `date`'s next day without adjusting time difference.
ASH_EXPORT base::Time GetNextDayMidnight(base::Time date);

// Returns true if (1) it's a regular user; and (2) the user session is not
// blocked; and (3) the admin has not disabled Google Calendar integration.
bool ShouldFetchCalendarData();

// Returns true if it's a regular user or the user session is not blocked.
bool IsActiveUser();

// Returns true if the admin has disabled Google Calendar integration.
bool IsDisabledByAdmin();

// Get the time difference to UTC time based on the time passed in and the
// system timezone. Daylight saving is considered.
ASH_EXPORT base::TimeDelta GetTimeDifference(base::Time date);

// Gets the first day's local midnight of the week based on the `date`.
base::Time GetFirstDayOfWeekLocalMidnight(base::Time date);

// Calculate the start/end times for a fetch of a single month's events.
// `start_of_month_local_midnight` should be local midnight on the first day of
// a month, and the two `base::Time` objects returned are the UTC times that
// represent the start of the month and start of the next month. See the unit
// test of this method in calendar_utils_unittest.cc for examples.
ASH_EXPORT const std::pair<base::Time, base::Time> GetFetchStartEndTimes(
    base::Time start_of_month_local_midnight);

// Gets the int index of this day in the week, starts from 1. This number is
// different for different languages. If cannot find this local's day in a week,
// returns its time exploded's `day_of_week`;
ASH_EXPORT int GetDayOfWeekInt(const base::Time date);

// Checks if the event spans more than one day.
ASH_EXPORT bool IsMultiDayEvent(
    const google_apis::calendar::CalendarEvent* event);

// Returns the `start_time` of `event` adjusted by time difference, to ensure
// that each event is stored by its local time, e.g. an event that starts at
// 2022-05-31 22:00:00.000 PST (2022-06-01 05:00:00.000 UTC) is stored in the
// map for 05-2022.
base::Time GetStartTimeAdjusted(
    const google_apis::calendar::CalendarEvent* event);

// Returns the `end_time` of `event` adjusted by time difference.
base::Time GetEndTimeAdjusted(
    const google_apis::calendar::CalendarEvent* event);

// Returns midnight on the day of the start time of `event`.
ASH_EXPORT base::Time GetStartTimeMidnightAdjusted(
    const google_apis::calendar::CalendarEvent* event);

// Returns midnight on the day of the end time of `event`.
ASH_EXPORT base::Time GetEndTimeMidnightAdjusted(
    const google_apis::calendar::CalendarEvent* event);

// Gets the event start and end times accounting for timezone.
const std::tuple<base::Time, base::Time> GetStartAndEndTime(
    const google_apis::calendar::CalendarEvent* event,
    const base::Time& selected_date,
    const base::Time& selected_date_midnight,
    const base::Time& selected_date_midnight_utc);

// Calculates the UTC and local midnight times for the given `base::Time`,
// rounding to the correct midnight for the given timezone. This avoids an
// issue with `base::Time::UTCMidnight()`, which will (in certain ahead
// timezones) return the previous days midnight.
// For example, if the current time is 19 Jan 2023 00:10 in GMT+13, then
// `GetUTCMidnight` will return 19 Jan 2023 00:00 UTC.
// `base::Time::UTCMidnight()` will round down to 18 Jan 2023 00:00 UTC.
ASH_EXPORT const std::tuple<base::Time, base::Time> GetMidnight(
    const base::Time);

}  // namespace calendar_utils

}  // namespace ash

#endif  // ASH_SYSTEM_TIME_CALENDAR_UTILS_H_