예제 #1
0
        private static void StopTimeTest(IGTFSDataSource source)
        {
            IGTFSFeed feed      = new LenientGTFSFeed(source);
            var       stopTimes = feed.StopTimes;

            var tripsByRouteService = feed.Trips.GroupBy(tp => (tp.RouteID, tp.ServiceID));
            var timesByTrip         = stopTimes.GroupBy(stm => stm.TripID).ToDictionary(stm => stm.Key, stm => new { start = stm.Min(x => x.DepartureTime), end = stm.Max(x => x.ArrivalTime) });

            DurationPattern ptn = DurationPattern.CreateWithInvariantCulture("H:mm:ss");

            foreach (var group in tripsByRouteService)
            {
                var rt  = feed.Routes[group.Key.RouteID];
                var cal = feed.Calendars[group.Key.ServiceID].Item1;

                string header = $"{rt.Type} {rt.ShortName} {rt.LongName} - {DayMasks.Get(cal.Mask)}";

                Duration min = Duration.MaxValue;
                Duration max = Duration.MinValue;

                foreach (var trip in group)
                {
                    var times = timesByTrip[trip.ID];
                    min = Duration.Min(times.start.Value, min);
                    max = Duration.Max(times.end.Value, max);
                }

                string timeStr = $"{ptn.Format(min)} - {ptn.Format(max)}";

                Console.WriteLine($"{header}: {timeStr}");
            }
        }
예제 #2
0
        private static void ProcessEntry(List <LogEntry> entries, int index)
        {
            LogEntry entry = entries[index];

            // Ignore any "end" actions. Assume they've already been handled (or are useless if they're orphans)
            if (entry.Action.StartsWith(EndPrefix))
            {
                return;
            }

            // If we have a "start" action, find the next matching "start" or "end", and handle appropriately
            if (entry.Action.StartsWith(StartPrefix))
            {
                string unprefixedAction  = entry.Action.Substring(StartPrefix.Length);
                string expectedEndAction = EndPrefix + unprefixedAction;

                // Note: in theory we should probably do this by index rather than timing, but it's very unlikely
                // to cause issues.
                var nextStart = entries.Skip(index + 1).FirstOrDefault(e => e.Action.StartsWith(entry.Action));
                var nextEnd   = entries.Skip(index + 1).FirstOrDefault(e => e.Action.StartsWith(expectedEndAction));
                if (nextEnd == null)
                {
                    PrintEntry(entry.Timestamp, null, $"No matching end: {unprefixedAction}");
                    return;
                }
                if (nextStart != null && nextStart.Timestamp < nextEnd.Timestamp)
                {
                    PrintEntry(entry.Timestamp, null, $"Matching start before end: {unprefixedAction}");
                    return;
                }
                // We report the action in parentheses as a simple indication that it's a compound action.
                PrintEntry(entry.Timestamp, nextEnd.Timestamp, $"({unprefixedAction})");
                return;
            }
            // Simple case: just one line for this action, and we're not at the end. Use the next entry.
            if (index < entries.Count - 1)
            {
                PrintEntry(entry.Timestamp, entries[index + 1].Timestamp, entry.Action);
            }
            // We only have one line for the action, but it's also the last line of the file. We have a start
            // but no end, so we can't work out the duration.
            else
            {
                PrintEntry(entry.Timestamp, null, $"Final line of file: {entry.Action}");
            }

            void PrintEntry(Instant start, Instant?end, string action)
            {
                string formattedDuration = end != null
                    ? s_durationPattern.Format(end.Value - start)
                    : NoDurationText;

                Console.WriteLine($"{InstantPattern.General.Format(start)}   {formattedDuration}   {action}");
            }
        }
 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
     if (value is Duration)
     {
         return(hm.Format((Duration)value));
     }
     else
     {
         return(value.ToString());
     }
 }
예제 #4
0
        /// <inheritdoc />
        public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
        {
            if (value == null)
            {
                return(string.Empty);
            }

            var duration = (Duration)value;

            return(DurationPattern.Format(duration));
        }
예제 #5
0
 public static string FormatHMS(this Duration duration)
 {
     return(hms.Format(duration));
 }