using System.Collections.Generic;
public static void Main()
OpeningHours morning = new OpeningHours(8, 11);
OpeningHours evening = new OpeningHours(13, 18);
OpeningDay sunday = OpeningDay.Open(DayOfWeek.Sunday, new List<OpeningHours> { morning, evening });
OpeningDay monday = OpeningDay.Open(DayOfWeek.Monday, new List<OpeningHours> { morning, evening });
OpeningDay tuesday = OpeningDay.Open(DayOfWeek.Tuesday, new List<OpeningHours> { morning, evening });
OpeningDay wednesday = OpeningDay.Open(DayOfWeek.Wednesday, new List<OpeningHours> { morning, evening });
OpeningDay thrusday = OpeningDay.Open(DayOfWeek.Thursday, new List<OpeningHours> { morning, evening });
OpeningDay friday = OpeningDay.Open(DayOfWeek.Friday, new List<OpeningHours> { morning, evening });
OpeningDay saturday = OpeningDay.Open(DayOfWeek.Saturday, new List<OpeningHours> { morning, evening });
BusinessDays businessDays = BusinessDays.FromDays(new List<OpeningDay>() { sunday, monday, tuesday, wednesday, thrusday, friday, saturday });
foreach(OpeningDay openingDay in businessDays.OpeningDays) {
Console.WriteLine("Dia: {0}", openingDay.DayOfWeek);
foreach(OpeningHours openingHours in openingDay.OpeningHours) {
Console.WriteLine("Horário de Abertura: {0}", openingHours.OpeningTime);
Console.WriteLine("Horário de Fechamento: {0}", openingHours.ClosingTime);
Console.WriteLine("Estabelecimento fechado.");
Console.WriteLine("-------------------------------------------------");
public class BusinessDays
private List<OpeningDay> _openingDays;
public IReadOnlyList<OpeningDay> OpeningDays
private BusinessDays(List<OpeningDay> openingDays) {
EnsureAllDaysOfWeekAreFilled(openingDays);
_openingDays = openingDays;
public static BusinessDays FromDays(List<OpeningDay> openingDays) {
return new BusinessDays(openingDays);
public static BusinessDays Default() {
List<OpeningDay> openingDays = new List<OpeningDay>();
foreach(DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek))) {
OpeningDay openingDay = OpeningDay.Closed(dayOfWeek);
openingDays.Add(openingDay);
return new BusinessDays(openingDays);
private void EnsureAllDaysOfWeekAreFilled(List<OpeningDay> openingDays) {
foreach(DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek))) {
bool dayExists = openingDays.Any(od => od.DayOfWeek == dayOfWeek);
throw new InvalidOperationException(string.Format("Todos os dias da semana devem ser cadastrados. Dia faltante {0}", dayOfWeek));
public class OpeningDay {
public DayOfWeek DayOfWeek { get; private set; }
public bool IsOpen { get; private set; }
private List<OpeningHours> _openingHours;
public IReadOnlyList<OpeningHours> OpeningHours
private OpeningDay(DayOfWeek dayOfWeek) {
private OpeningDay(DayOfWeek dayOfWeek, List<OpeningHours> openingHours) {
_openingHours = openingHours;
public static OpeningDay Closed(DayOfWeek dayOfWeek) {
return new OpeningDay(dayOfWeek);
public static OpeningDay Open(DayOfWeek dayOfWeek, List<OpeningHours> openingHours){
return new OpeningDay(dayOfWeek, openingHours);
public class OpeningHours
public int OpeningTime { get; private set; }
public int ClosingTime { get; private set; }
public OpeningHours(int openingTime, int closingTime) {
OpeningTime = openingTime;
ClosingTime = closingTime;
if(CheckIfItsTheSameTime())
throw new InvalidOperationException(string.Format("As horas de abertura e fechamento não podem ser iguais."));
public bool CheckIfItsTheSameTime() {
return OpeningTime == ClosingTime;
public bool CheckForIntersections(OpeningHours otherOpeningHours) {
bool hasIntesection = false;
if(!BeginsAndEndsFirst(otherOpeningHours) && !BeginsAndEndsAfter(otherOpeningHours))
private bool BeginsAndEndsFirst(OpeningHours otherOpeningHours) {
bool beginsAndEndsFirst = OpeningTime <= otherOpeningHours.OpeningTime && ClosingTime <= otherOpeningHours.OpeningTime;
Console.WriteLine("BeginsAndEndsFirst: {0}", beginsAndEndsFirst);
return beginsAndEndsFirst;
private bool BeginsAndEndsAfter(OpeningHours otherOpeningHours) {
bool beginsAndEndsAfter = OpeningTime >= otherOpeningHours.ClosingTime && ClosingTime >= otherOpeningHours.ClosingTime;
Console.WriteLine("BeginsAndEndsAfter: {0}", beginsAndEndsAfter);
return beginsAndEndsAfter;