2022-03-15 18:00:53 +00:00
|
|
|
// (c) Copyright Ascensio System SIA 2010-2022
|
|
|
|
//
|
|
|
|
// This program is a free software product.
|
|
|
|
// You can redistribute it and/or modify it under the terms
|
|
|
|
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
|
|
|
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
|
|
|
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
|
|
|
// any third-party rights.
|
|
|
|
//
|
|
|
|
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
|
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
|
|
|
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
|
|
//
|
|
|
|
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
|
|
|
//
|
|
|
|
// The interactive user interfaces in modified source and object code versions of the Program must
|
|
|
|
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
|
|
|
//
|
|
|
|
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
|
|
|
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
|
|
|
// trademark law for use of our trademarks.
|
|
|
|
//
|
|
|
|
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
|
|
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
|
|
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
namespace ASC.Api.Core;
|
|
|
|
|
|
|
|
[TypeConverter(typeof(ApiDateTimeTypeConverter))]
|
2022-02-10 10:56:54 +00:00
|
|
|
public sealed class ApiDateTime : IComparable<ApiDateTime>, IComparable
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
public DateTime UtcTime { get; private set; }
|
|
|
|
public TimeSpan TimeZoneOffset { get; private set; }
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-03-25 14:54:34 +00:00
|
|
|
internal static readonly string[] Formats = new[]
|
2022-02-03 13:19:48 +00:00
|
|
|
{
|
2022-03-25 14:54:34 +00:00
|
|
|
"o",
|
|
|
|
"yyyy'-'MM'-'dd'T'HH'-'mm'-'ss'.'fffffffK",
|
|
|
|
"yyyy'-'MM'-'dd'T'HH'-'mm'-'ss'.'fffK",
|
|
|
|
"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK",
|
|
|
|
"yyyy'-'MM'-'dd'T'HH'-'mm'-'ssK",
|
|
|
|
"yyyy'-'MM'-'dd'T'HH':'mm':'ssK",
|
|
|
|
"yyyy'-'MM'-'dd"
|
|
|
|
};
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
private readonly TenantManager _tenantManager;
|
|
|
|
private readonly TimeZoneConverter _timeZoneConverter;
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public ApiDateTime() : this(null, null, null) { }
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public ApiDateTime(
|
|
|
|
TenantManager tenantManager,
|
|
|
|
TimeZoneConverter timeZoneConverter,
|
|
|
|
DateTime? dateTime)
|
|
|
|
: this(tenantManager, dateTime, null, timeZoneConverter) { }
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public ApiDateTime(
|
|
|
|
TenantManager tenantManager,
|
|
|
|
DateTime? dateTime,
|
|
|
|
TimeZoneInfo timeZone,
|
|
|
|
TimeZoneConverter timeZoneConverter)
|
|
|
|
{
|
|
|
|
if (dateTime.HasValue && dateTime.Value > DateTime.MinValue && dateTime.Value < DateTime.MaxValue)
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
_tenantManager = tenantManager;
|
|
|
|
_timeZoneConverter = timeZoneConverter;
|
|
|
|
SetDate(dateTime.Value, timeZone);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
else
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
UtcTime = DateTime.MinValue;
|
|
|
|
TimeZoneOffset = TimeSpan.Zero;
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public ApiDateTime(DateTime utcTime, TimeSpan offset)
|
|
|
|
{
|
|
|
|
UtcTime = new DateTime(utcTime.Ticks, DateTimeKind.Utc);
|
|
|
|
TimeZoneOffset = offset;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public static ApiDateTime Parse(string data, TenantManager tenantManager, TimeZoneConverter timeZoneConverter)
|
|
|
|
{
|
|
|
|
return Parse(data, null, tenantManager, timeZoneConverter);
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static ApiDateTime Parse(string data, TimeZoneInfo tz, TenantManager tenantManager, TimeZoneConverter timeZoneConverter)
|
|
|
|
{
|
2022-03-09 17:15:51 +00:00
|
|
|
ArgumentNullOrEmptyException.ThrowIfNullOrEmpty(data);
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
var offsetPart = data.Substring(data.Length - 6, 6);
|
2022-03-25 14:54:34 +00:00
|
|
|
if (DateTime.TryParseExact(data, Formats, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out var dateTime))
|
2022-02-03 13:19:48 +00:00
|
|
|
{
|
|
|
|
//Parse time
|
|
|
|
var tzOffset = TimeSpan.Zero;
|
2022-03-09 17:15:51 +00:00
|
|
|
if (offsetPart.Contains(':') && TimeSpan.TryParse(offsetPart.TrimStart('+'), out tzOffset))
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2019-06-13 09:25:53 +00:00
|
|
|
return new ApiDateTime(dateTime, tzOffset);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-03-09 17:15:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
if (!data.EndsWith("Z", true, CultureInfo.InvariantCulture))
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (tz == null)
|
|
|
|
{
|
|
|
|
tz = GetTimeZoneInfo(tenantManager, timeZoneConverter);
|
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
|
|
|
|
tzOffset = tz.GetUtcOffset(dateTime);
|
|
|
|
dateTime = dateTime.Subtract(tzOffset);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return new ApiDateTime(dateTime, tzOffset);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
throw new ArgumentException("invalid date time format: " + data);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
private void SetDate(DateTime value, TimeZoneInfo timeZone)
|
|
|
|
{
|
|
|
|
TimeZoneOffset = TimeSpan.Zero;
|
|
|
|
UtcTime = DateTime.MinValue;
|
2019-08-15 12:04:42 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
if (timeZone == null)
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
timeZone = GetTimeZoneInfo(_tenantManager, _timeZoneConverter);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
//Hack
|
|
|
|
if (timeZone.IsInvalidTime(new DateTime(value.Ticks, DateTimeKind.Unspecified)))
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
value = value.AddHours(1);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
if (value.Kind == DateTimeKind.Local)
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
value = TimeZoneInfo.ConvertTimeToUtc(new DateTime(value.Ticks, DateTimeKind.Unspecified), timeZone);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
if (value.Kind == DateTimeKind.Unspecified)
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
value = new DateTime(value.Ticks, DateTimeKind.Utc); //Assume it's utc
|
2022-03-09 17:15:51 +00:00
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
if (value.Kind == DateTimeKind.Utc)
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
UtcTime = value; //Set UTC time
|
|
|
|
TimeZoneOffset = timeZone.GetUtcOffset(value);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
private static TimeZoneInfo GetTimeZoneInfo(TenantManager tenantManager, TimeZoneConverter timeZoneConverter)
|
|
|
|
{
|
|
|
|
var timeZone = TimeZoneInfo.Local;
|
|
|
|
try
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
timeZone = timeZoneConverter.GetTimeZone(tenantManager.GetCurrentTenant().TimeZone);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
catch (Exception)
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
//Tenant failed
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return timeZone;
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
private string ToRoundTripString(DateTime date, TimeSpan offset)
|
|
|
|
{
|
|
|
|
var dateString = date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff", CultureInfo.InvariantCulture);
|
2022-03-09 17:15:51 +00:00
|
|
|
var offsetString = offset.Ticks == 0
|
|
|
|
? "Z" : ((offset < TimeSpan.Zero)
|
2022-02-07 16:03:16 +00:00
|
|
|
? "-" : "+") + offset.ToString("hh\\:mm", CultureInfo.InvariantCulture);
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return dateString + offsetString;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static ApiDateTime FromDate(TenantManager tenantManager, TimeZoneConverter timeZoneConverter, DateTime d)
|
|
|
|
{
|
|
|
|
var date = new ApiDateTime(tenantManager, timeZoneConverter, d);
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return date;
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static ApiDateTime FromDate(TenantManager tenantManager, TimeZoneConverter timeZoneConverter, DateTime? d)
|
|
|
|
{
|
|
|
|
if (d.HasValue)
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
var date = new ApiDateTime(tenantManager, timeZoneConverter, d);
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return date;
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return null;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static bool operator >(ApiDateTime left, ApiDateTime right)
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (ReferenceEquals(left, right))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (left == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return left.CompareTo(right) > 0;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static bool operator >=(ApiDateTime left, ApiDateTime right)
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (ReferenceEquals(left, right))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (left == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return left.CompareTo(right) >= 0;
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public static bool operator <=(ApiDateTime left, ApiDateTime right)
|
|
|
|
{
|
|
|
|
return !(left >= right);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public static bool operator <(ApiDateTime left, ApiDateTime right)
|
|
|
|
{
|
|
|
|
return !(left > right);
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public static bool operator ==(ApiDateTime left, ApiDateTime right)
|
|
|
|
{
|
|
|
|
return Equals(left, right);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public static bool operator !=(ApiDateTime left, ApiDateTime right)
|
|
|
|
{
|
|
|
|
return !(left == right);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static implicit operator DateTime(ApiDateTime d)
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (d == null)
|
|
|
|
{
|
|
|
|
return DateTime.MinValue;
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return d.UtcTime;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public static implicit operator DateTime?(ApiDateTime d)
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (d == null)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return d.UtcTime;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public int CompareTo(DateTime other)
|
|
|
|
{
|
|
|
|
return CompareTo(new ApiDateTime(_tenantManager, _timeZoneConverter, other));
|
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public int CompareTo(ApiDateTime other)
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (other == null)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return UtcTime.CompareTo(other.UtcTime);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public override bool Equals(object obj)
|
|
|
|
{
|
2022-03-17 15:01:39 +00:00
|
|
|
if (obj is null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ReferenceEquals(this, obj))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-04-14 19:23:57 +00:00
|
|
|
if (obj is not ApiDateTime)
|
2022-03-17 15:01:39 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return Equals((ApiDateTime)obj);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public bool Equals(ApiDateTime other)
|
|
|
|
{
|
2022-02-07 16:03:16 +00:00
|
|
|
if (other is null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (ReferenceEquals(this, other))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return UtcTime.Equals(other.UtcTime) && TimeZoneOffset.Equals(other.TimeZoneOffset);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public override int GetHashCode()
|
|
|
|
{
|
|
|
|
unchecked
|
|
|
|
{
|
|
|
|
return UtcTime.GetHashCode() * 397 + TimeZoneOffset.GetHashCode();
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public int CompareTo(object obj)
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
if (obj is DateTime dateTime)
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return CompareTo(dateTime);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return obj is ApiDateTime apiDateTime ? CompareTo(apiDateTime) : 0;
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public override string ToString()
|
|
|
|
{
|
|
|
|
var localUtcTime = UtcTime;
|
|
|
|
if (!UtcTime.Equals(DateTime.MinValue))
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
localUtcTime = UtcTime.Add(TimeZoneOffset);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-01-31 16:36:51 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return ToRoundTripString(localUtcTime, TimeZoneOffset);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public static ApiDateTime GetSample()
|
|
|
|
{
|
|
|
|
return new ApiDateTime(DateTime.UtcNow, TimeSpan.Zero);
|
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public class ApiDateTimeTypeConverter : DateTimeConverter
|
|
|
|
{
|
|
|
|
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
2019-06-13 09:25:53 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
if (destinationType == typeof(string))
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return value.ToString();
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
return base.ConvertTo(context, culture, value, destinationType);
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|
2020-02-25 12:21:48 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
2020-02-25 12:21:48 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
if (value is string @string)
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return ApiDateTime.Parse(@string, null, null);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
if (value is DateTime time)
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return new ApiDateTime(null, null, time);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
|
|
|
|
return base.ConvertFrom(context, culture, value);
|
|
|
|
}
|
|
|
|
}
|
2020-02-25 12:21:48 +00:00
|
|
|
|
2022-02-03 13:19:48 +00:00
|
|
|
public class ApiDateTimeConverter : System.Text.Json.Serialization.JsonConverter<ApiDateTime>
|
|
|
|
{
|
|
|
|
public override ApiDateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
|
|
{
|
|
|
|
if (reader.TryGetDateTime(out var result))
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return new ApiDateTime(result, TimeSpan.Zero);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
else
|
2020-02-25 12:21:48 +00:00
|
|
|
{
|
2022-03-25 14:54:34 +00:00
|
|
|
if (DateTime.TryParseExact(reader.GetString(), ApiDateTime.Formats,
|
2022-02-07 16:03:16 +00:00
|
|
|
CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime))
|
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return new ApiDateTime(dateTime, TimeSpan.Zero);
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
else
|
2022-02-07 16:03:16 +00:00
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
return new ApiDateTime();
|
2022-03-09 17:15:51 +00:00
|
|
|
}
|
2020-02-25 12:21:48 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
}
|
2020-02-25 12:21:48 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public override void Write(Utf8JsonWriter writer, ApiDateTime value, JsonSerializerOptions options)
|
|
|
|
{
|
2022-02-03 13:19:48 +00:00
|
|
|
writer.WriteStringValue(value.ToString());
|
2022-02-07 16:03:16 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
[Scope]
|
|
|
|
public class ApiDateTimeHelper
|
|
|
|
{
|
|
|
|
private readonly TenantManager _tenantManager;
|
|
|
|
private readonly TimeZoneConverter _timeZoneConverter;
|
|
|
|
|
|
|
|
public ApiDateTimeHelper(TenantManager tenantManager, TimeZoneConverter timeZoneConverter)
|
|
|
|
{
|
|
|
|
_tenantManager = tenantManager;
|
|
|
|
_timeZoneConverter = timeZoneConverter;
|
2020-02-25 12:21:48 +00:00
|
|
|
}
|
2022-02-03 13:19:48 +00:00
|
|
|
|
2022-02-07 16:03:16 +00:00
|
|
|
public ApiDateTime Get(DateTime? from)
|
|
|
|
{
|
|
|
|
return ApiDateTime.FromDate(_tenantManager, _timeZoneConverter, from);
|
|
|
|
}
|
2019-06-13 09:25:53 +00:00
|
|
|
}
|