using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using TSLab.Script.Handlers;
using TSLab.Script.Handlers.Options;
using static GAA.ServiceLib.DatesTime.Constants;
namespace GAA.Cubes.AddSubtractDateNS
{
#region CubeDescription
[HandlerCategory("Ganov Cubes. DateTime")]
[HandlerName("AddSubtractDate", Language = "ru-ru")]
[Description("Кубик принимает на вход дату формата ТСЛаб и число дней, которые надо вычесть или прибавить от/к указанной дате. Если на вход в качестве даты поступает число" +
" больше 6-ти или меньше 5-ти цифр, либо имеющее дробную часть, либо число меньше 10101 то кубик вернет значение \"10101\". Также в случае если при вычитание числа итоговая дата" +
" становится меньше \"@ExtDate.MinHystoryDate\", то кубик вернет значение \"10101\". Кубик производит как операцию сложения, так и операцию вычитания в зависимости от выбранного типа операции. Выбранная" +
" операция производится для каждого бара, то есть если на входе будут на каждом баре меняться значения, то выходная коллекция значений также будет изменяться на каждом баре, при этом" +
" если какие-либо значения не соответствуют выше описанным правилам, то на этом баре кубик вернет значение \"10101\"" +
"\nКубик имеет следующие входы: " +
"\n======================" +
"\nДата - дата, над которой будет производиться операция сложения или вычитания" +
"\nДни - количество дней, которые надо прибавить или вычесть из даты")]
[HelperLink("http://forum.tslab.ru/ubb/ubbthreads.php?ubb=showflat&Number=87152&page=1", "Описание на форуме ТСлаб", "ru-ru")]
[InputsCount(2)]
[Input(0, TemplateTypes.DOUBLE, Name = "Дата")]
[Input(1, TemplateTypes.DOUBLE, Name = "Дни")]
[OutputsCount(1)]
[OutputType(TemplateTypes.DOUBLE)]
#endregion
public class AddSubtractDate : IContextUses, IStreamHandler, IDoubleInput0, IDoubleInput1, IDoubleReturns
{
public IContext Context { get; set; }
///
/// Тип операции
///
[HandlerParameter(true, "Subtract", NotOptimized = false, Name = "Тип операции", IsVisibleInBlock = true)]
[Description("Тип операции: Прибавить, Вычесть")]
public DateOperationType OperType { get; set; } = DateOperationType.Subtract;
///
/// Метод возвращает дату в формате ТСЛаб после вычитания/прибавления указанного количества дней
///
/// Дата в формате ТСлаб
/// Количество дней для вычитания прибавления
/// Рассчитанное значение даты
public double Execute(double dateTSLabFormat, int daysToAddSubtract)
{
return GetBarDate(dateTSLabFormat, daysToAddSubtract);
}
///
/// Метод возвращает дату в формате ТСЛаб после вычитания/прибавления указанного количества дней
///
/// Дата в формате ТСлаб
/// Количество дней для вычитания прибавления
/// Коллекцию значений с рассчитанной датой
public IList Execute(IList dateTSLabFormat, IList daysToAddSubtract)
{
var barsCount = Context.BarsCount;
var retValue = Context.GetArray(barsCount);
if (dateTSLabFormat.Any() && daysToAddSubtract.Any())
for (var i = 0; i < barsCount; i++)
retValue[i] = GetBarDate(dateTSLabFormat[i], daysToAddSubtract[i]);
return retValue;
}
///
/// Метод возвращает дату в формате ТСЛаб с вычетом или добавлением
/// указанного количества дней
///
///
///
///
private double GetBarDate(double date, double days)
{
var strDate = date.ToString();
if (date % 1 != 0 || strDate.Length > 6 || strDate.Length < 5 || date < MinHistoryDate) return MinHistoryDate;
var dtDate = DateTime.Parse($"{strDate.Substring(strDate.Length - 2, 2)}.{strDate.Substring(strDate.Length - 4, 2)}." +
$"20{(strDate.Length == 5 ? "0" : "")}{strDate[..(strDate.Length == 5 ? 1 : 2)]}").AddDays(OperType == DateOperationType.Add ? days : -days);
return int.Parse(dtDate.ToString("yyMMdd"));
}
}
}