Find time occurence and duration in certain time range

I made a little parking application in C#. There are some different pricings depending on vehicle type and time zone. Day can be divided into time zones (for example morning, day, evening and night). Now if customer stops parking I want to calculate in which time zones customer has parked and how long.

For example morning time zone starts at 6:00 and ends 12:00, day time zone starts at 12:00 and ends 16:00, evening time zone starts at 16:00 and ends at 23:00 and night time zone starts at 23:00 and ends at 6:00. Customer started parking his car at 00:30 and ends parking at 6:32. Currently I have 4 variables for that: parking start time, parking end time and timezone starting time and timezone ending time.

Second example would be like customer parks 24H, then the parking time has all time zones covered.

How is the simplest way to calculate how many hours and minutes customer parked his car in different time zones?

Regards, evilone

EDIT:

Got this answer from MSDN and post it here so others can learn from it too.

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            DateTime start = new DateTime(2011, 7, 25, 0, 30, 0);
            DateTime end = new DateTime(2011, 7, 26, 6, 32, 0);
            List<DateTime> listTimeZones = CalculateTotalTime(start, end);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < listTimeZones.Count; i++)
            {
                sb.AppendLine(String.Format("{0}. {1}: from {2} to {3}",
                                            i + 1,
                                            GetZoneInWords(listTimeZones[i].Hour),
                                            String.Format("{0:dd.MM.yyyy hh:mm}", listTimeZones[i]),
                                            (i + 1) < listTimeZones.Count
                                                ? String.Format("{0:dd.MM.yyyy hh:mm}", listTimeZones[i + 1])
                                                : "Parking ended"));
            }
            MessageBox.Show(sb.ToString());
        }

        private List<DateTime> CalculateTotalTime(DateTime start, DateTime end)
        {
            DateTime temp = start;

            int hour = start.Hour;
            int minute = start.Minute;

            int morning = 6;
            int day = 12;
            int evening = 17;
            int night = 23;

            List<DateTime> timeZones = new List<DateTime>();

            do
            {
                temp = temp.AddHours(1);
                if (temp.Hour == morning || temp.Hour == day ||
                    temp.Hour == evening || temp.Hour == night)
                {
                    timeZones.Add(temp);
                }
            } while (temp < end);

            return timeZones;
        }

        private string GetZoneInWords(int time)
        {
            string timeOfDay = "";
            if (time.Equals(6))
                timeOfDay = "Morning";
            else if (time.Equals(12))
                timeOfDay = "Day";
            else if (time.Equals(17))
                timeOfDay = "Evening";
            else if (time.Equals(23))
                timeOfDay = "Night";

            return timeOfDay + " parking";
        }
    }

Iterate through all the "time zones" and for each, work out the overlap between that and the customer's parking. For example, as pseudo-code:

private static TimeSpan FindOverlap(ParkingTime parkingTime, TimeZone timeZone)
{
    // Handle wraparound zones like 23-6. Note that this doesn't attempt
    // to handle *parking* which starts at 11.30pm etc.
    if (timeZone.Start > timeZone.End)
    {
        return FindOverlap(parkingTime,
                     new TimeZone(timeZone.Start.Date, timeZone.End)
             + FindOverlap(parkingTime,
                     new TimeZone(timeZone.End, timeZone.Start.Date.AddDays(1));
    }

    DateTime overlapStart = Max(parkingTime.Start, timeZone.Start);
    DateTime overlapEnd = Min(parkingTime.End, timeZone.End);
    TimeSpan overlap = overlapEnd - overlapStart;

    // If the customer arrived after the end or left before the start,
    // the overlap will be negative at this point.
    return overlap < TimeSpan.Zero ? TimeSpan.Zero : overlap;
}

private static DateTime Min(DateTime x, DateTime y)
{
    return x < y ? x : y;
}

private static DateTime Max(DateTime x, DateTime y)
{
    return x > y ? x : y;
}

By the way, I would strongly encourage you to rename your "time zone" concept, given that it already has a well-known (if not well-understood :) meaning.

Perhaps you should call it ParkingInterval ? Or ParkingPriceInterval if the difference is really in terms of cost?

链接地址: http://www.djcxy.com/p/95414.html

上一篇: 计算整个月的百分比时间

下一篇: 在特定时间范围内查找时间的发生和持续时间