Skip to content

Instantly share code, notes, and snippets.

@scarletquasar
Created October 20, 2024 01:51
Show Gist options
  • Save scarletquasar/b468cddd2b681e1e4361937fde827c3e to your computer and use it in GitHub Desktop.
Save scarletquasar/b468cddd2b681e1e4361937fde827c3e to your computer and use it in GitHub Desktop.
RecurrentDateTimeOffset Draft
namespace FitLivre.DataStructures
{
public class RecurrentDateTimeOffset
{
private readonly RecurrentDateTimeKind _recurrencyKind;
private readonly DateTimeOffset[]? _fixedFiniteOccurrences;
private readonly RecurrentWeekDayAndTime[]? _perWeekOccurrences;
private readonly RecurrentMonthDayAndTime[]? _perMonthOccurrences;
private readonly RecurrentYearMonthDayAndTime[]? _perYearOccurrences;
private readonly TimeSpan _tolerance;
private readonly TimeSpan _defaultTolerance = TimeSpan.FromHours(1);
public RecurrentDateTimeOffset(DateTimeOffset[] dateTimeOffsets, TimeSpan? tolerance)
{
_tolerance = tolerance ?? _defaultTolerance;
_recurrencyKind = RecurrentDateTimeKind.FixedFiniteOccurrences;
_fixedFiniteOccurrences = dateTimeOffsets;
}
public RecurrentDateTimeOffset(RecurrentWeekDayAndTime[] perWeekOccurrences, TimeSpan? tolerance)
{
_tolerance = tolerance ?? _defaultTolerance;
_recurrencyKind = RecurrentDateTimeKind.OccurrencesPerWeek;
_perWeekOccurrences = perWeekOccurrences;
}
public RecurrentDateTimeOffset(RecurrentMonthDayAndTime[] perMonthOccurrences, TimeSpan? tolerance)
{
_tolerance = tolerance ?? _defaultTolerance;
_recurrencyKind = RecurrentDateTimeKind.OccurrencesPerMonth;
_perMonthOccurrences = perMonthOccurrences;
}
public RecurrentDateTimeOffset(RecurrentYearMonthDayAndTime[] perYearOccurrences, TimeSpan? tolerance)
{
_tolerance = tolerance ?? _defaultTolerance;
_recurrencyKind = RecurrentDateTimeKind.FixedFiniteOccurrences;
_perYearOccurrences = perYearOccurrences;
}
public bool IsHappening()
{
return _recurrencyKind switch
{
RecurrentDateTimeKind.FixedFiniteOccurrences => IsHappeningFixedTime(),
RecurrentDateTimeKind.OccurrencesPerWeek => IsHappeningPerWeek(),
RecurrentDateTimeKind.OccurrencesPerMonth => IsHappeningPerMonth(),
RecurrentDateTimeKind.OccurrencesPerYear => IsHappeningPerYear(),
_ => throw new InvalidOperationException(),
};
}
private bool IsHappeningFixedTime()
{
return _fixedFiniteOccurrences!.Any(IsDateTimeOffsetTolerated);
}
private bool IsHappeningPerWeek()
{
var isHappening = false;
var currentDateTime = DateTimeOffset.Now;
foreach (var occurrence in _perWeekOccurrences!)
{
var isDayOfWeek = occurrence.DayOfWeek == currentDateTime.DayOfWeek;
var isCurrentTime = occurrence.TimeOnly < TimeOnly.FromDateTime(currentDateTime.UtcDateTime).Add(_tolerance);
if (isDayOfWeek && isCurrentTime)
{
isHappening = true;
}
}
return isHappening;
}
private bool IsHappeningPerMonth()
{
var isHappening = false;
var currentDateTime = DateTimeOffset.Now;
foreach (var occurrence in _perMonthOccurrences!)
{
var isDayOfMonth = occurrence.DayOfMonth == currentDateTime.Day;
var isCurrentTime = occurrence.TimeOnly < TimeOnly.FromDateTime(currentDateTime.UtcDateTime).Add(_tolerance);
if (isDayOfMonth && isCurrentTime)
{
isHappening = true;
}
}
return isHappening;
}
private bool IsHappeningPerYear()
{
var isHappening = false;
var currentDateTime = DateTimeOffset.Now;
foreach (var occurrence in _perYearOccurrences!)
{
var isMonth = occurrence.Month == currentDateTime.Month;
var isDayOfMonth = occurrence.DayOfMonth == currentDateTime.Day;
var isCurrentTime = occurrence.TimeOnly < TimeOnly.FromDateTime(currentDateTime.UtcDateTime).Add(_tolerance);
if (isMonth && isDayOfMonth && isCurrentTime)
{
isHappening = true;
}
}
return isHappening;
}
private bool IsDateTimeOffsetTolerated(DateTimeOffset current)
{
return DateTimeOffset.Now < current + _tolerance;
}
}
public enum RecurrentDateTimeKind
{
OccurrencesPerWeek,
OccurrencesPerMonth,
OccurrencesPerYear,
FixedFiniteOccurrences
}
public record struct RecurrentWeekDayAndTime(DayOfWeek DayOfWeek, TimeOnly TimeOnly);
public record struct RecurrentMonthDayAndTime(uint DayOfMonth, TimeOnly TimeOnly);
public record struct RecurrentYearMonthDayAndTime(uint Month, uint DayOfMonth, TimeOnly TimeOnly);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment