Frage

Der Versuch, den Umsatz der 24-Stunden-Uhr mit der Hand zu emulieren (mit Mathe gegen die Zeitspanne Klassen). Das Erhöhen Teil war leicht, herauszufinden, wie von 23.00 Uhr bis 00.00 Uhr rollen und von, aber es geht in der anderen Richtung dreht geführt wird wirklich immer verwirrend. Hier ist, was ich bisher:

static void IncrementMinute(int min, int incr)
{
    int newMin = min + incr,
                hourIncrement = newMin / 60;

    //increment or decrement the hour
    if((double)newMin % 60 < 0 && (double)newMin % 60 > -1)
        hourIncrement = -1;

    Console.WriteLine("Hour increment is {0}: ", hourIncrement);
}

Das Problem, dass im Befunde, wenn rückwärts, wenn das das E-Modul zwischen den Zahlen ist, wird es nicht richtig verringern. Beispiel: Es ist 12:00 Uhr und Sie 61 Minuten subtrahieren, wissen wir, die Zeit 10.59 Uhr sein würde, wie die Stunde sollte gehen von 12.00 bis 11.59 Uhr, dann wieder für den Gang ab 11:00 Uhr um 1 Stunde zurück rollen bis 10.59. Leider ist die Art und Weise der Berechnung im it: 60% newMin in diesem Fall greift nur die erste Stunde Transfer abbrechen, aber da der zweite Rollback ist technisch -1,0166 als Rest, und da eine ganze Zahl mod nur zurückkehrt, seine Abrundung. Ich bin sicher, im hier einige grundlegende mathematische fehlt, konnte aber jemand helfen mir?

EDIT: Ich habe diese eine Reihe von Möglichkeiten lange geschrieben und kurz. Einige sind näher als andere, aber ich weiß, das ist einfacher, als es scheint. Ich weiß, das scheint irgendwie „wtf wurde er tut“, aber man sollte im Grunde sehen kann, was Im versuchen zu tun. eine Uhr Inkrementieren und Roll 23.59 bis 00.00 Uhr mit leicht. Kümmert hat nach hinten beweist nicht so einfach sein.

OK, hier ist die incrementMinute mit dem Rollover. Einfach. Aber versuchen, rückwärts zu gehen. Funktioniert nicht.

static void IncrementMinute(int min, int incr)

        {
            int newMin = min + incr,
                hourIncrement = newMin / 60;

            min = newMin % 60;

            Console.WriteLine("The new minute is {0} and the hour has incremented by {1}", min, hourIncrement);
        }
War es hilfreich?

Lösung

ich für etwas ein gehen würde etwas einfacher

public class Clock
{
    public const int HourPerDay = 24;
    public const int MinutesPerHour = 60;
    public const int MinutesPerDay = MinutesPerHour * HourPerDay;

    private int totalMinutes;

    public int Minute
    {
        get { return this.totalMinutes % MinutesPerHour; }
    }

    public int Hour
    {
        get { return this.totalMinutes / MinutesPerHour; }
    }

    public void AddMinutes(int minutes)
    {
        this.totalMinutes += minutes;
        this.totalMinutes %= MinutesPerDay;
        if (this.totalMinutes < 0)
            this.totalMinutes += MinutesPerDay;
    }

    public void AddHours(int hours)
    {
        this.AddMinutes(hours * MinutesPerHour);
    }

    public override string ToString()
    {
        return string.Format("{0:00}:{1:00}", this.Hour, this.Minute);
    }
}

Verwendungsbeispiel:

new Clock().AddMinutes(-1);    // 23:59
new Clock().AddMinutes(-61);   // 22:59
new Clock().AddMinutes(-1441); // 23:59
new Clock().AddMinutes(1);     // 00:01
new Clock().AddMinutes(61);    // 01:01
new Clock().AddMinutes(1441);  // 00:01

Andere Tipps

Sie könnten versuchen, beid Minuten- und Stunden Schritte Berechnung zuerst, dann die Bearbeitung von Fällen, wo die neuen Minuten überqueren eine Stunde Grenze, etwa wie folgt:

int hourIncrement = incr / 60;
int minIncrement = incr % 60;

int newMin = min + minIncrement;

if (newMin < 0)
{
    newMin += 60;
    hourIncrement--;
}
else if (newMin > 60)
{
    newMin -= 60;
    hourIncrement++;
}

Bearbeiten

Ich mag @ Ben Voigts Antwort, aber frage mich, ob es einen Unterschied in der Leistung sein würde. Ich lief unter die Konsolenanwendung zu Zeit sie beide, und war ein wenig von den Ergebnissen überrascht.

  • 40 ms für den Code oben
  • 2876 ms für Bens Antwort

Dies wurde in einem Release-Build getan. Kann jemand anderes diese und bestätigen laufen? Bin ich irgendwelche Fehler in der Art, wie ich Zeit, um sie?

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            int max = 100000000;

            sw.Start();
            for (int i = 0; i < max; i++)
                IncrementMinute1(0, -61);
            sw.Stop();

            Console.WriteLine("IncrementMinute1: {0} ms", sw.ElapsedMilliseconds);

            sw.Reset();

            sw.Start();
            for (int i = 0; i < max; i++)
                IncrementMinute2(0, -61);
            sw.Stop();

            Console.WriteLine("IncrementMinute2: {0} ms", sw.ElapsedMilliseconds);

            Console.ReadLine();
        }

        static void IncrementMinute1(int min, int incr)
        {
            int hourIncrement = incr / 60;
            int minIncrement = incr % 60;

            int newMin = min + minIncrement;

            if (newMin < 0)
            {
                newMin += 60;
                hourIncrement--;
            }
            else if (newMin > 60)
            {
                newMin -= 60;
                hourIncrement++;
            }
        }

        static void IncrementMinute2(int min, int incr)
        {
            min += incr;
            int hourIncrement = (int)Math.Floor(min / 60.0);
            min -= hourIncrement * 60;
        }
    }
}

Modular Mathematik ist nur für die ganzen Zahlen definiert. Wenn Sie modulare Arithmetik mischen mit reellen Zahlen versuchen, werden Sie keinen Erfolg. Sie müssen aus einem anderen mathematischen Ansatz zur Figur.

Versuchen

        int newMin = min + incr,
            hourIncrement = (int)Math.Floor(newMin / 60.0);

        min -= hourIncrement * 60;

Das wesentliche Problem war, dass man hourIncrement abrunden will, aber Integer-Division Runden gegen Null. Sie sind die gleichen mit positiven Zahlen, aber nicht für negative ...

EDIT (loszuwerden nutzlos zusätzliche Variable):

    min += incr;
    int hourIncrement = (int)Math.Floor(min / 60.0);
    min -= hourIncrement * 60;

EDIT2 (avoid Gleitkomma-Arithmetik):

    min += incr;
    int hourIncrement = min / 60;
    min -= hourIncrement * 60;
    if (min < 0) { min += 60; --hourIncrement; }

Warum die Dinge komplizieren

public System.Timers.Timer timer = new System.Timers.Timer(1000);
public DateTime d;

public void init()
{
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);

d = new DateTime(2011, 11, 11, 23, 59, 50);
d=d.AddHours(1);
Console.Writeline(d);
d=d.AddHours(-2);
Console.Writeline(d);
timer.Enabled = true;
}
   void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
        {
            MoveClockHands();
            d=d.AddSeconds(1);
            Console.WriteLine(d);

        }));
    }

    void MoveClockHands()  //12 hours clock
    (
       s=d.Second * 6;
       m=d.Minute * 6;
       h=0.5 * ((d.Hour % 12) * 60 + d.Minute)
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top