예제 #1
0
        private DaylightInfo CalculateDaylightInfo(DateTime commuteStart, DateTime commuteEnd, SunCalculator sunCalculator, string timeZoneId)
        {
            var daylightInfo = new DaylightInfo();

            var sunRise = sunCalculator.CalculateSunRise(commuteStart.Date, timeZoneId);
            var sunSet = sunCalculator.CalculateSunSet(commuteStart.Date, timeZoneId);
            var commuteIsAfterSunrise = commuteStart.TimeOfDay >= sunRise.TimeOfDay;
            var commuteIsBeforeSunSet = commuteEnd.TimeOfDay <= sunSet.TimeOfDay;

            if (commuteEnd.Date > commuteStart.Date)
            {
                // Special case; overlapping midnight. Just assume that it's always dark
                return daylightInfo;
            }

            daylightInfo.IsCurrentlyInDaylight = commuteIsAfterSunrise && commuteIsBeforeSunSet;

            for (var d = 0; d < DaysInYear; d++)
            {
                sunRise = sunCalculator.CalculateSunRise(commuteStart.Date.AddDays(d), timeZoneId);
                sunSet = sunCalculator.CalculateSunSet(commuteEnd.Date.AddDays(d), timeZoneId);

                if (commuteStart.TimeOfDay >= sunRise.TimeOfDay && commuteEnd.TimeOfDay <= sunSet.TimeOfDay)
                {
                    daylightInfo.CommutesInDaylightPerYear++;
                }

                if (!daylightInfo.TransitionType.HasValue && DaylightTransitionHappened(sunRise, sunSet, commuteStart, commuteEnd, daylightInfo.IsCurrentlyInDaylight))
                {
                    // We need to work out on which edge the transition happened
                    if (commuteIsAfterSunrise != (commuteStart.TimeOfDay >= sunRise.TimeOfDay))
                    {
                        daylightInfo.NextDaylightTransition = sunRise.AddDays(-1);
                        daylightInfo.TransitionType = DaylightTransition.SunRise;
                    }
                    else if (commuteIsBeforeSunSet != (commuteEnd.TimeOfDay <= sunSet.TimeOfDay))
                    {
                        daylightInfo.NextDaylightTransition = sunSet.AddDays(-1);
                        daylightInfo.TransitionType = DaylightTransition.SunSet;
                    }
                    else
                    {
                        throw new Exception("something went very wrong");
                    }
                }
            }

            return daylightInfo;
        }
예제 #2
0
        public static DaylightInfoModel BuildDaylightInfoModel(DateTime today, DaylightInfo daylightInfo, Commute commuteType, WorkingDays workingDays)
        {
            var daysToTransition = 0;
            DateTime? nextWorkingDayDaylightTransition = null;

            if (daylightInfo.NextDaylightTransition.HasValue)
            {
                var day = today;

                if (day >= daylightInfo.NextDaylightTransition.Value)
                {
                    throw new InvalidOperationException(string.Format("daylightInfo.NextDaylightTransition.Value equals {0}; but it should be in the future.", daylightInfo.NextDaylightTransition.Value));
                }

                var days = new List<DateTime>();

                while (day < daylightInfo.NextDaylightTransition.Value)
                {
                    day = day.AddDays(1);
                    days.Add(day);
                }

                // Nudge to the first working day, if necessary
                // TODO: Get rid of the flags variable here
                var workingDayFlags = new[] { workingDays.HasFlag(WorkingDays.Sunday), workingDays.HasFlag(WorkingDays.Monday), workingDays.HasFlag(WorkingDays.Tuesday), workingDays.HasFlag(WorkingDays.Wednesday), workingDays.HasFlag(WorkingDays.Thursday), workingDays.HasFlag(WorkingDays.Friday), workingDays.HasFlag(WorkingDays.Saturday) };
                while (!workingDayFlags[(int)days.Last().DayOfWeek])
                {
                    days.Add(days.Last().AddDays(1));
                }

                daysToTransition = days.Count(d => workingDayFlags[(int)d.DayOfWeek]);
                nextWorkingDayDaylightTransition = days.Last();
            }

            return new DaylightInfoModel
            {
                IsCurrentlyInDaylight = daylightInfo.IsCurrentlyInDaylight,
                PercentOfTheYearInTheDark = GetPercentOfTheYearInTheDark(daylightInfo.CommutesInDaylightPerYear),
                NextWorkingDayDaylightTransition = nextWorkingDayDaylightTransition,
                CommuteType = commuteType,
                NumberOfDaysToTransition = daysToTransition,
            };
        }
예제 #3
0
        public void SetUp()
        {
            _daylights = new DaylightInfo { TransitionType = DaylightTransition.SunRise };

            _workingDays = WorkingDays.Monday | WorkingDays.Tuesday | WorkingDays.Wednesday | WorkingDays.Thursday | WorkingDays.Friday;
        }