So My coworker and I have been in the works on creating a Blazor app for an expiration date calculator for the labs at our company. We are basically almost done until we realized that leap years exist and are messing up the calculation.
We know how to check for a leap year but the thing is, once we account for a leap year (e.g 2024) every calculation for every year after that turns up wrong (e.g 2025,2026, etc.).
We don't know how to remedy this beyond just creating a check if it's a leap year or not since the calculation is just messed up every year after that... thoughts or has anyone else run into this issue? The logic part of the code is listed below:
@code {
private RecordEditContext recordEditContext = new RecordEditContext(new());
private ExpirationDate ExpiryDate = new ExpirationDate();
private string errorMessage = string.Empty;
private bool IsError => this.errorMessage != string.Empty;
private void CalculateExpiryDate()
{
this.errorMessage = string.Empty;
this.ExpiryDate.Value = DateTime.MinValue;
this.recordEditContext.SetToClean();
if ((recordEditContext.IsBeforeDate == false) && (recordEditContext.IsPlate == false) && (recordEditContext.ShelfLife >= 90))
{
this.ExpiryDate.Value = (recordEditContext.MixDate + TimeSpan.FromDays(recordEditContext.ShelfLife)) - TimeSpan.FromDays(30);
this.ExpiryDate.Format = ExpirationDate.ExpiryDateFormat.MonthYear;
DateTime expDay = this.ExpiryDate.Value;
DateTime endOfMonth = new DateTime(expDay.Year, expDay.Month, DateTime.DaysInMonth(expDay.Year, expDay.Month));
return;
}
if ((recordEditContext.IsBeforeDate == true) || (recordEditContext.IsPlate == true) || (recordEditContext.ShelfLife < 90))
{
this.ExpiryDate.Value = (recordEditContext.MixDate + TimeSpan.FromDays(recordEditContext.ShelfLife)).AddDays(-1);
this.ExpiryDate.Format = ExpirationDate.ExpiryDateFormat.YearMonthDay;
return;
}
this.errorMessage = "Please Try Again. Information Not Satisfactory.";
}
let me know if you guys need more information!
It sounds to me like the business wants a product that expires to show the expiration date as 3 years as shown on a calendar minus 30 days. At least from what I can tell. So specifically you want November 1, 2022 with a 3 year expiration date to be November 1, 2025 minus 30 days. To do this, you cannot count by days alone as you are.
A reproduction of what you're doing now:
//this is what you're currently doing
//(recordEditContext.MixDate + TimeSpan.FromDays(recordEditContext.ShelfLife)) - TimeSpan.FromDays(30)
DateTime MixDate = new DateTime(2022, 12, 01);
TimeSpan ShelfLife = TimeSpan.FromDays(1095);
TimeSpan ThirtyDays = TimeSpan.FromDays(30);
var TimeAsIs = (MixDate + ShelfLife) - ThirtyDays;
Console.WriteLine($"### original ###\nMixed: {MixDate} Expires: {TimeAsIs}");
How you might fix most of the issue:
//This sets the day of expiration based on the mix date and then calculates the date you need.
//If you need it to be November 1, 2025 minus 30 days
//because it was mixed on November 1 2022, this is how.
DateTime ExpirationDateIsThreeYears = new DateTime(MixDate.Year + 3, MixDate.Month, MixDate.Day);
var NewTime = ExpirationDateIsThreeYears - ThirtyDays;
Console.WriteLine($"### new ###\nMixed: {MixDate} Expires: {NewTime}");
Console.ReadLine();
This outputs:
### original ###
Mixed: 12/1/2022 12:00:00 AM Expires: 10/31/2025 12:00:00 AM
### new ###
Mixed: 12/1/2022 12:00:00 AM Expires: 11/1/2025 12:00:00 AM
Basically if I understand your problem correctly, you can solve it by simply adding 1 or 3 years to the MixDate year and then subtracting 30 days. This would still cause an issue counting backwards through February 29 if the product expires between March 1 and March 29 on a leap year, but it eliminates the overwhelming majority of the issue since 11/12 cases will only count forward through February 29. Hope this helps!