using System;
using System.Globalization;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Settings;
namespace Unity.Cloud.Collaborate.Utilities
{
///
/// Static class that presents methods to provide timestamps for the UI.
///
static class TimeStamp
{
///
/// Bool to decide whether timestamps should be exact values or relative values.
///
public static bool UseRelativeTimeStamps =>
CollabSettingsManager.Get(CollabSettings.settingRelativeTimestamp, fallback: true);
///
/// Values to translate a number to a string representation.
///
static readonly string[] k_UnitsMap = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
///
/// Get the localized or relative timestamp for the given DateTime based on the current settings.
///
/// DateTime to convert.
/// String representation of the given DateTime.
[NotNull]
public static string GetTimeStamp(DateTimeOffset dateTime)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
return UseRelativeTimeStamps
? GetElapsedTime(dateTime)
: GetLocalisedTimeStamp(dateTime);
}
///
/// Get the localised timestamp for the given DateTime.
///
/// DateTime to convert.
/// Localised string representation of the given DateTime.
[NotNull]
public static string GetLocalisedTimeStamp(DateTimeOffset dateTime)
{
return dateTime.ToString(CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern);
}
// Original credit: https://codereview.stackexchange.com/questions/93239/get-elapsed-time-as-human-friendly-string
///
/// Convert a DateTime into a relative timestamp.
///
/// Datetime to calculate the timestamp from.
/// Relative timestamp for the given DateTime.
[NotNull]
static string GetElapsedTime(DateTimeOffset dateTime)
{
var offset = DateTimeOffset.Now.Subtract(dateTime);
// The trick: make variable contain date and time representing the desired timespan,
// having +1 in each date component.
var date = DateTimeOffset.MinValue + offset;
return ProcessPeriod(date.Year - 1, date.Month - 1, "year")
?? ProcessPeriod(date.Month - 1, date.Day - 1, "month")
?? ProcessPeriod(date.Day - 1, date.Hour, "day", "Yesterday")
?? ProcessPeriod(date.Hour, date.Minute, "hour")
?? ProcessPeriod(date.Minute, date.Second, "minute")
?? ProcessPeriod(date.Second, 0, "second")
?? "Right now";
}
// Original credit: https://codereview.stackexchange.com/questions/93239/get-elapsed-time-as-human-friendly-string
///
/// Output the string representation for the given time frame. If it's not in that time frame, it returns null.
///
/// Bigger time value.
/// Smaller time value eg: minutes if value is hours.
/// Name of the period.
/// Name for period that is singular. Null if it's not singular eg: yesterday.
/// String representation of the period, or null if it's outside of it.
[CanBeNull]
static string ProcessPeriod(int value, int subValue, string name, string singularName = null)
{
// If the value is less than this time frame, skip.
if (value == 0)
{
return null;
}
// If a multiple of this time frame eg: 20 minutes.
if (value != 1)
{
// Convert values specified to string numbers.
var stringValue = value