// Ignore Spelling: Linq
using System;
namespace AsbCloudInfrastructure;
public static class DateTimeExtensions
{
///
/// Приветсти к UTC из времени куста
///
///
///
///
public static DateTimeOffset ToUtcDateTimeOffset(this DateTime date, double remoteTimezoneOffsetHours)
{
if (date == default)
return new DateTimeOffset();
var dateUtc = date.Kind switch
{
DateTimeKind.Local => date.ToUniversalTime(),
DateTimeKind.Unspecified => DateTime.SpecifyKind(date.AddHours(-remoteTimezoneOffsetHours), DateTimeKind.Utc),
_ => date,
};
return new DateTimeOffset(dateUtc);
}
///
/// Привести ко времени куста из utc
///
///
///
///
public static DateTime ToRemoteDateTime(this DateTimeOffset date, double remoteTimezoneOffsetHours)
{
if (date == default)
return new DateTime(0, DateTimeKind.Unspecified);
var dateTz = date.ToOffset(TimeSpan.FromHours(remoteTimezoneOffsetHours));
return dateTz.DateTime;
}
///
/// Поиск индекса близкого к value значения в span.
/// Элементы в span должны быть отсортированы по возрастанию по полю propertyGetter.
///
///
///
///
/// метод получения свойства из объекта класса T
/// искомое значение
/// максимальное кол-во итераций. Прим.:
/// в span из 4000 записей достаточно 9-ти итераций
/// 8_000 => 10 итераций;
/// 16_000 => 11;
/// ...
/// 256_000 => 15;
/// При недостаточном кол-ве итераций индекс может оказаться близко, но это будет не ближайшее значение
///
///
public static int BinarySearch(this Span span, Func propertyGetter, TProp value, int maxIterations = 16)
where TProp : IComparable
{
if (span.Length < 2 || --maxIterations < 0)
return 0;
var indexOfMiddle = span.Length >> 1;
var comparison = value.CompareTo(propertyGetter(span[indexOfMiddle]));
if (comparison > 0)
{
var index = indexOfMiddle + 1 + BinarySearch(span[(indexOfMiddle + 1)..], propertyGetter, value, maxIterations);
return index < span.Length ? index : span.Length - 1;
}
else if (comparison < 0)
return BinarySearch(span[..(indexOfMiddle)], propertyGetter, value, maxIterations);
else //if (comparison == 0)
return indexOfMiddle;
}
}