Denkanstoss zur Zeitberechnung

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    Denkanstoss zur Zeitberechnung

    Ich benötige mal einen Denkanstoss um folgendes zu lösen

    Festlegung

    20:00:00 bis 00:00:00 = 10%
    00:00:00 bis 04:00:00 = 20%
    04:00:00 bis 06:00:00 = 15%

    Zeitspanne
    22:00:00 bis 04:30:00

    als ergebins müste rauskomme

    2 Stunden x 10%
    4 Stunden x 20%
    0,5 Stunden x 15%

    mir fehlt im Moment eine Idee das umzusetzen.

    Hat jemand von euch eine Idee.

    Vielen Dank schon mal Norbert
    CCU2 • Raspberry für Wetterstation • ioBroker • HP ProLiant MicroServer Gen8 12GB 2x3TB Server 2012 R2 • PHP • MYSQL • VB.NET (Anfänger)
    Hier mal meine Lösung dazu:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Module Module1
    2. Sub Main()
    3. Dim t As New TimeCollection
    4. t.Add("20:00", "0:00", 0.1)
    5. t.Add("0:00", "4:00", 0.2)
    6. t.Add("4:00", "6:00", 0.15)
    7. For Each x In t.EnumerateTimespan("22:00", "4:30")
    8. Console.WriteLine("{0}h {1}%", x.Item1, x.Item2 * 100)
    9. Next
    10. Console.ReadLine()
    11. End Sub
    12. End Module
    13. Class TimeCollection
    14. Private diffs As New List(Of TimeSpan)
    15. Private values As New List(Of Double)
    16. Private beginTime As Date?
    17. Public Sub Add(t1 As String, t2 As String, p As Double)
    18. Dim d1 = Date.Parse(t1)
    19. Dim d2 = Date.Parse(t2)
    20. Dim diff As TimeSpan
    21. If d1 < d2 Then
    22. diff = d2 - d1
    23. Else
    24. diff = TimeSpan.FromHours(24) - (d1 - d2)
    25. End If
    26. diffs.Add(diff)
    27. values.Add(p)
    28. If Not beginTime.HasValue Then
    29. beginTime = d1
    30. End If
    31. End Sub
    32. Public Iterator Function EnumerateTimespan(t1 As String, t2 As String) As IEnumerable(Of Tuple(Of TimeSpan, Double))
    33. If diffs.Count = 0 Then Return
    34. Dim d1 = Date.Parse(t1)
    35. Dim d2 = Date.Parse(t2)
    36. ' Shift both limits one day into future if the
    37. ' lower limit is "earlier" than the first data point
    38. If d1 < beginTime.Value Then
    39. d1 = d1.AddDays(1)
    40. d2 = d2.AddDays(1)
    41. End If
    42. ' Shift the upper limit an additional day
    43. ' into future if upper limit < lower limit
    44. If d1 > d2 Then
    45. d2 = d2.AddDays(1)
    46. End If
    47. Dim spot As Date = beginTime.Value
    48. Dim i As Int32 = 0
    49. ' Adjust spot to match the lower limit
    50. While d1 > spot And i < diffs.Count
    51. spot = spot.Add(diffs(i))
    52. ' Yield initial difference
    53. If d1 < spot Then
    54. Yield New Tuple(Of TimeSpan, Double)(spot - d1, values(i))
    55. End If
    56. i += 1
    57. End While
    58. ' Stop if data is already exhausted
    59. If i = diffs.Count Then Return
    60. ' Yield all intermediate differences
    61. While i < diffs.Count AndAlso spot.Add(diffs(i)) < d2
    62. spot = spot.Add(diffs(i))
    63. Yield New Tuple(Of TimeSpan, Double)(diffs(i), values(i))
    64. i += 1
    65. End While
    66. ' Stop if data is already exhausted
    67. If i = diffs.Count Then Return
    68. ' Yield final difference
    69. Yield New Tuple(Of TimeSpan, Double)(d2 - spot, values(i))
    70. End Function
    71. End Class


    Den Iterator finde ich ein wenig hässlich, aber es funktioniert. Folgende Annahmen habe ich getroffen:

    - Ist die untere Grenze der gewünschten Zeitspanne kleiner als der erste Zeitpunkt, ist der nächste Tag gemeint
    - Ist die obere Grenze des Zeitintervalls kleiner als die untere, ist ebenfalls der nächste Tag gemeint.
    Gruß
    hal2000
    @nobse Vielleicht ist es besser, gleich eine vollständige Lösung zu implementieren, also:
    Wie sind die Festlegungen von 6 bis 20 Uhr, so dass da 100% rauskommen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    ich würde eine "While" Schleife schreiben die eine Variablen "Startzeit" immer ein Minutee anhebt.
    In der While eine Select Case Variablen "Startzeit" und Case mit den 3 +1 Bereichen (Zeiten) 0% / 10% / 15% / 20% und über 4 Variablen dann jeweils eine Minute dazuzählen.
    Wenn die Endzeit erreicht ist, dann hast Du alle Werte die Du benötigst..
    Hallo

    vielen Dank für Eure Beiträge.

    @hal2000 Danke für deinen Code der hat auf anhieb super funktioniert.

    @RodFromGermany Die andere Zeit gibt es 0%. Hier werden Zuschläge für die angegebene Zeit Berechnet.

    Ich werde den Code von hal2000 implementieren wenn er nichts dagegen hat.

    Gruß Norbert
    CCU2 • Raspberry für Wetterstation • ioBroker • HP ProLiant MicroServer Gen8 12GB 2x3TB Server 2012 R2 • PHP • MYSQL • VB.NET (Anfänger)

    nobse schrieb:

    Die andere Zeit gibt es 0%.
    AHa.
    Zuschläge für Arbeit während der Nachtstunden.
    So was muss einem gesagt werden.
    Nimm den normalen Satz und multipliziere den Anteil, der auf die Nachtzeit fällt, mit
    20:00:00 bis 00:00:00 = 10% ==> 1,1
    00:00:00 bis 04:00:00 = 20% ==> 1,2
    04:00:00 bis 06:00:00 = 15% ==> 1,15

    Zeitspanne
    22:00:00 bis 04:30:00
    ==>
    2 Stunden á 1,1
    4 Stunden á 1,2
    0,5 Stunden á 1,15
    Bei einem Stundenlohn von sagen wir 12 €:
    2 h * 12 € / h * 1,1 = 26,4 €
    4 h * 12 € / h * 1,2 = 57,6 €
    0,5 h * 12 € / h * 1,15 = 6,90 €
    Summe = 90,90 €
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!