How Can i retrieve date from a hashset that contains date and name using linq or contains?

1.2k Views Asked by At

I am new to Web API and need help with the code.

I want to return a boolean if the date passed is a holiday listed in GetHolidays or it is Saturday or Sunday

This is my function where I want to check whether a particular date is holiday or not.

public bool IsHoliday(DateTime requesteddate)
{
    HashSet<Holidays> holidays = new HashSet<Holidays>();
    string sat = requesteddate.DayOfWeek.ToString();
    string sun = requesteddate.DayOfWeek.ToString();

    holidays = GetHolidays(requesteddate.Year);
    return true;
}

This is the hashset of holidays that I have calculated for whole year and that works perfectly

public HashSet<Holidays> GetHolidays(int year)
{
    HashSet<Holidays> holidays = new HashSet<Holidays>();

    // NEW YEARS 
    DateTime newYearsDate = AdjustForWeekendHoliday(new DateTime(year, 1, 1).Date);
    holidays.Add(new Holidays(newYearsDate, "New Years Day"));

    // MARTIN LUTHER KING, JR. DAY -- third Monday of January
    DateTime martinLutherDay = new DateTime(year, 1, (from day in Enumerable.Range(1, 31) where new DateTime(year, 1, day).DayOfWeek == DayOfWeek.Monday select day).ElementAt(2));
    holidays.Add(new Holidays(martinLutherDay, "Martin Luther King, Jr. Day"));

    // PRESIDENT'S DAY -- third Monday of February
    DateTime presidentsDay = new DateTime(year, 2, (from day in Enumerable.Range(1, 29) where new DateTime(year, 2, day).DayOfWeek == DayOfWeek.Monday select day).ElementAt(2));
    holidays.Add(new Holidays(presidentsDay, "President's Day"));

    // MEMORIAL DAY  -- last monday in May 
    DateTime memorialDay = new DateTime(year, 5, 31);
    DayOfWeek dayOfWeek = memorialDay.DayOfWeek;

    while (dayOfWeek != DayOfWeek.Monday)
    {
        memorialDay = memorialDay.AddDays(-1);
        dayOfWeek = memorialDay.DayOfWeek;
    }

    holidays.Add(new Holidays(memorialDay.Date, "Memorial Day"));

    // INDEPENCENCE DAY 
    DateTime independenceDay = AdjustForWeekendHoliday(new DateTime(year, 7, 4).Date);
    holidays.Add(new Holidays(independenceDay, "Independence Day"));

    // LABOR DAY -- 1st Monday in September 
    DateTime laborDay = new DateTime(year, 9, 1);
    dayOfWeek = laborDay.DayOfWeek;

    while (dayOfWeek != DayOfWeek.Monday)
    {
        laborDay = laborDay.AddDays(1);
        dayOfWeek = laborDay.DayOfWeek;
    }

    holidays.Add(new Holidays(laborDay.Date, "Labor Day"));

    // VETERANS DAY 
    DateTime veteransDay = AdjustForWeekendHoliday(new DateTime(year, 11, 11).Date);
    holidays.Add(new Holidays(veteransDay, "Veterans Day"));

    // THANKSGIVING DAY - 4th Thursday in November 
    var thanksgiving = (from day in Enumerable.Range(1, 30) where new DateTime(year, 11, day).DayOfWeek == `DayOfWeek.Thursday select day).ElementAt(3);
    DateTime thanksgivingDay = new DateTime(year, 11, thanksgiving);
    holidays.Add(new Holidays(thanksgivingDay.Date, "Thanksgiving"));

    // DAY AFTER THANKSGIVING DAY 
    DateTime dayAfterThankGiving = thanksgivingDay.AddDays(1);
    holidays.Add(new Holidays(dayAfterThankGiving, "Day after Thanksgiving"));

    // CHRISTMAS
    DateTime christmasDay = AdjustForWeekendHoliday(new DateTime(year, 12, 25).Date, true);
    holidays.Add(new Holidays(christmasDay, "Christmas"));

    // CHRISTMAS EVE 
    DateTime christmasEve = christmasDay.AddDays(-1);
    holidays.Add(new Holidays(christmasEve, "Christmas"));

    return holidays;
}

Here is the IHTTP action in the controller

[HttpGet]
public IHttpActionResult IsHoliday(DateTime requesteddate)
{
    try
    {
        var isHoliday = _dateService.IsHoliday(requesteddate);
        return Content(HttpStatusCode.OK, isHoliday);
    }
    catch (Exception exception)
    {
        return BadRequest(exception.Message);
    }
}
2

There are 2 best solutions below

4
On

If Holidays class implement GetHashCode and Equals by just comparing date portion of the class than just checking for Contains will work:

var isHoliday = holidays.Contains(new Holidays(requesteddate, "fake"));

If Holidays class does not implement GetHashCode and Equals pair at all (fix code - Why is it important to override GetHashCode when Equals method is overridden?) or the class actually compares all fields in these two methods than you need to iterate through all items and compare date manually:

var isHoliday = holidays.Contains(h => h.Date == requesteddate);

I personally would use Dictionary<DateTime, Holiday> instead of HashSet as it would be more obvious that that looking up by date with ContainsKey will find if date is in the collection.

Side note: Holidays is very strange name for single item - normally plural nouns imply collections.

1
On

Finally I got it this way.... but thanks for help

public bool IsHoliday(DateTime requesteddate, HolidayType type)
{
  var holidays = GetHolidays(requesteddate.Year, type);
  return holidays.Any(h => DateTime.Equals(h.Date, requesteddate));
}