1

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);
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

2 Answers2

1

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.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • why mixing _not good_ answer with good answer? :P its really weird to not consider part of the object`s property when computing hash of that object. specially when that property is required for object(i.e not optional)... using Dictionary is definitely the answer. – M.kazem Akhgary Dec 29 '16 at 22:12
  • Thanks for the reply. I tried buy comparing manually but, whatever date I put the return is false. – user1746021 Dec 30 '16 at 18:04
  • @user1746021 most likely because you've lied to yourself when named variables - chances are that `requesteddate` is not a date, but current time or something similar. That's why providing [MCVE] is important part of good SO question. – Alexei Levenkov Dec 30 '16 at 18:25
  • Hi I have posted the code that worked for me. Thanks for the help – user1746021 Jan 05 '17 at 20:03
0

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));
}
Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
  • So you're using a hash set but then looping through each item to find one with a matching property? Why not just override `Equals` and `GetHashCode` like has been suggested? – D Stanley Jan 05 '17 at 20:07