vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevAniGif - als kostenlose Vollversion auf unserer vb@rchiv CD Vol.5  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2015
 
zurück
Rubrik: Verschiedenes / Sonstiges   |   VB-Versionen: VB.NET04.04.07
Verbalisierte Datumsangaben in Benutzer-Dialogen

Ersetzung von Datumsangaben durch relative Begriffe wie "gestern", "in drei Tagen" usw.

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  6.729 
ohne HomepageSystem:  WinNT, Win2k, WinXP, Vista, Win7, Win8 Beispielprojekt auf CD 

Summer-Special bei Tools & Components!
Gute Laune Sommer bei Tools & Components
Top Summer-Special - Sparen Sie teilweise über 100,- EUR
Alle sev-Entwicklerkomponenten und Komplettpakete jetzt bis zu 25% reduziert!
zum Beispiel:
  • Developer CD nur 455,- EUR statt 569,- EUR
  • sevDTA 2.0 nur 224,30 EUR statt 299,- EUR
  •  
  • vb@rchiv   Vol.6 nur 18,70 EUR statt 24,95 EUR
  • sevCoolbar 3.0 nur 58,70 EUR statt 69,- EUR
  • - Werbung -Und viele weitere Angebote           Aktionspreise nur für kurze Zeit gültig

    Problemstellung:
    Wenn man in einem Dialog dem Benutzer eine Liste von Datumsangaben zur Bearbeitung vorlegt - z.B. für die Terminplanung oder zur Ereignisüberwachung - ist es oftmals günstiger, die reinen Datumswerte im Format Tag/Monat/Jahr - soweit sie in der Nähe des aktuellen Datums liegen - zu ersetzen oder zu ergänzen durch aussagekräftigere Bezeichnungen wie "heute", "vorgestern" oder "kommenden Dienstag".
    Auch bei der Anzeige von Datums-Spalten in Datenbanktabellen kann eine Option zur Darstellung der Einträge in Form von solchen Begriffen nützlich sein.

    In Dialogen, bei deren Bearbeitung es vor allem auf die Zeitspanne ankommt, kann man statt dessen Benennungen wie "vor drei Tagen" oder "in 14 Tagen" ausgeben.

    Da Visual Basic einen Kalender, den speziellen Datentyp "DateTime" und dafür zahlreiche Datumsfunktionen bereit hält, ist die Programmierung relativ einfach. Die benötigten Methoden sind im Namespace "Microsoft.Visualbasic" enthalten. (Im Code werden die Methoden "voll qualifiziert" aufgerufen).

    Zu beachten ist dabei insbesondere, dass Instanzen der Datenstruktur "System.DateTime" IMMER einen "tick"-genauen Zeitpunkt enthalten, also ein Datum UND eine Uhrzeit umfassen. Das gilt auch für die aktuelle Version des "klassischen" VB-Datentyps "Date", der in VB 2005 als ein Ableger von "DateTime" enthalten ist und dessen Instanzen ebenfalls die entsprechenden Methoden bereit stellen (vgl. unten).

    Details zu den VB-Methoden:
    Den aktuellen Zeitpunkt, dessen Datum den Bezugspunkt bei Bildung der strukturierten Angaben darstellt, liefert die Eigenschaft "System.DateTime.Now".
    Sie ruft ein DateTime-Objekt ab, das auf das aktuelle Datum und die aktuelle Zeit auf dem lokalen Rechner als lokale Zeit festgelegt ist (VB-Doku). Allerdings wird die Kind-Eigenschaft dabei nicht auf "DateTimeKind:Local“ gesetzt, sondern bleibt unspezifiziert.

    Die Now-Eigenschaft ist nicht zu verwechseln mit der auf Modulebene verfügbaren Now-Funktion (Microsoft.Visualbasic), die das Systemdatum und die Systemzeit abfragt.

    Für jedes im Dialog angezeigte Datum ist die Zahl der Tageswechsel zu bestimmen, durch die sie vom Now-Datum abweichen. Liegt kein Tageswechsel vor, ist das Datum durch "Heute" verbal zu etikettieren.

    Die Funktion "DateDiff" berechnet das Intervall zwischen zwei Zeitpunkten in einem vorzugebenden Maßstab - in unserem Fall sind das Tage.
    "DateDiff" berücksichtigt dabei den genauen Zeitpunkt der übergebenen Parameter. Das bedeutet, zwischen dem 1.1.2007 23:00:00 und dem 2.1.2007 01:00:00 liegen zwei Stunden, also weniger als ein Tag - d.h. die Methode errechnet 0 Tage, obwohl ein Tageswechsel stattgefunden hat.
    Als Übergabeparameter muss deshalb die Rückgabe der "DateTime“-Eigenschaft "Date" verwendet werden. Diese Eigenschaft liefert den Zeitwert stets als 00:00:00. Der obige Vergleich gestaltet sich als Differenz der Zeitpunkte 1.1.2007 00:00:00 und 2.1.2007 00:00:00 - und liefert somit korrekt den benötigten einen Tageswechsel.
    Bei Bestimmung der Tageswechsel ist zu beachten, ob der übergebene "DateTime"-Wert in lokaler Zeit (einschließlich Sommerzeit) oder in Weltzeit angegeben worden ist (Abfrage der Kind-Eigenschaft). Die Routine „SetToLocalTime“ stellt ggf. die lokale Zeit her – ignoriert aber die unspezifizierte Kind-Eigenschaft!.

    Beträgt die Zeitdistanz zwischen einem Dialog-Datum und dem aktuellen Datum mehr als zwei, aber weniger als acht Tage, kann man in Dialogen den zugehörigen Wochentag ausgeben, z.B. "vergangener Freitag" bzw. "kommender Freitag".

    Die VB-Funktion "WeekDay" liefert zu einem Datum eine Integer-Kennung für den Wochentag, bei der gemäß Voreinstellung 1 = Sonntag und 7 = Samstag codiert ist.

    Man könnte über die VB-Funktion "WeekdayName" die Bezeichnung des Wochentags entsprechend der Windows-Spracheinstellung auslesen. Da im vorliegenden Fall die Wochentage mit eigenen Bezeichnungen kombiniert werden sollen, ist das nicht unbedingt zu empfehlen. Bei der Windows-Einstellung ENGLISCH ergäbe sich dann z.B. "kommender Wednesday".

    Der Einfachheit halber wird deshalb eine Funktion verwendet, die die deutschen Wochentags-Bezeichnungen sicher stellt.
    Die Übersetzung deutscher Relativzeit-Bezeichnungen in andere Sprachen ist z.T. nicht unbedingt sinnvoll: Z.B. wird der Begriff "vorgestern" ins Englische normalerweise als "the day before yesterday" übersetzt. In dieser Sprache sollte man statt dessen den entsprechenden Wochentag angeben.

    Vorschlag:
    Die Funktion "VerbalisiertesDatum" wertet die Datumsangabe in einer Instanz der „DateTime“-Struktur aus. Zurückgegeben wird entweder das gegebene Datum als deutscher Standard-Datums-String (Funktion: "NurDatum") oder dessen Ersetzung durch einen aussagekräftigen Begriff .
    Der zweite optionale Parameter entscheidet, ob bei einem Datum, das weiter als eine Woche vom gegenwärtigen Datum entfernt liegt, dieses Datum als String (bei: false) oder ein Leerstring (bei: true) zurückgegeben wird. Letzteres ist dann zweckmäßig, wenn das verbale Etikett des Datums nur zusätzlich im Dialog angezeigt werden soll.

    Die Funktion "VerbalisiertesDatum_PlusUhrzeit" hängt die Zeitangabe an die Rückgabe des Datums als Standard-Zeitstring (Funktion: "NurUhrzeit") an. Von Bedeutung ist das z.B. bei der Anzeige von Dateilisten. Es kommt häufig vor, dass mehrere Versionen einer Datei am gleichen Tag erstellt worden sind und deshalb erst durch die ergänzende Anzeige der Uhrzeit ('letzte Änderung') vom Benutzer sicher identifiziert werden können (vgl. Funktion „VerbalisierteDateizeit“)

    Die Funktion "´VerbalisiertesDatum_Intervall" ersetzt das übergebene Datum durch eine Intervallangabe in Tagen, falls die absolute Differenz zum aktuellen Datum maximal 30 Tageswechsel beträgt.
    Solche Angaben sind sinnvoll z.B. bei der Bearbeitung von Bestellungen. Dabei ist es wichtig zu wissen, wie viele Tage seit Auftragseingang bereits vergangen, bzw. wie viele Tage bis zum Erreichen eines vereinbarten Liefertermins noch übrig sind.

    Die Routine "Demo_VerbalisiertesDatum" demonstriert Aufruf und Rückgabe dieser Funktionen.

    Es versteht sich, dass es kaum Sinn macht, solche Angaben in einer Datei oder Datenbank zu speichern oder sie vom Benutzer im Dialog direkt manipulieren zu lassen.

    ' ====================================================================
    ' Start Quellcode
    ' ====================================================================
    Public Sub Demo_VerbalisiertesDatum()
      Dim i As Integer, dt As System.DateTime
     
      ' Hier angeben, ob bei nicht durchgeführter Verbalisierung
      ' die Funktionen das Datum zurückgeben oder einen Leerstring
      Dim NurVerbalisierung As Boolean = False
     
      ' Demo-Ausgabe von verbalisierten Datumsangaben 
      ' 10 Tage vor bis 10 Tage nach dem aktuellen Datum
      Debug.Print("")
      Debug.Print("Verbalisiertes Datum: ")
      For i = -10 To 10
        ' laufenden Schleifenindex-Wert als Tagesanzahl 
        ' zum aktuellen Datum addieren
        dt = Now.Add(New System.TimeSpan(i, 0, 0, 0))
        ' Ausgabe ins Debug-Fenster
        Debug.Print(dt.ToString + " ---> " + _
        VerbalisiertesDatum(dt, NurVerbalisierung))
      Next i
     
      Debug.Print("")
      Debug.Print("Verbalisiertes Datum plus Uhrzeit: ")
      For i = -10 To 10
        ' laufenden Schleifenindex-Wert als Tagesanzahl 
        ' zum aktuellen Datum addieren
        dt = Now.Add(New System.TimeSpan(i, 0, 0, 0))
        ' Ausgabe ins Debug-Fenster
        Debug.Print(dt.ToString + " ---> " + _
        VerbalisiertesDatum_PlusUhrzeit(dt, NurVerbalisierung))
      Next i
     
     
      ' Demo-Ausgabe von verbalisierten Datumsangaben (vor x Tagen) 
      ' 32 Tage vor bis 32 Tage nach dem aktuellen Datum
      Debug.Print("")
      Debug.Print("Verbalisiertes Datum als Tagesdifferenz: ")
      For i = -32 To 32
        ' laufenden Schleifenindex-Wert als Tagesanzahl 
        ' zum aktuellen Datum addieren
        dt = Now.Add(New System.TimeSpan(i, 0, 0, 0))
        Debug.Print(dt.ToString + " ---> " + _
        VerbalisiertesDatum_Intervall(dt, NurVerbalisierung))
      Next i
    End Sub
    Public Function VerbalisiertesDatum( _
      ByVal dt As System.DateTime, _
      Optional ByVal NurVerbalisierung As Boolean = False) As String
     
      ' Ein Datum wird umgewandelt in Angaben wie Heute, Morgen oder
      ' den Wochentag falls es maximal eine Woche vom aktuellen Datum
      ' entfernt ist
     
      ' Bestimmung der Zahl der Tageswechsel zwischen dem aktuellem
      ' Datum und dem Inhalt des übergebenen Parameters
      Dim DatumsDifferenz As Long = _
      TagesWechsel(System.DateTime.Now, dt)
     
      ' ggf. Verbalisierung des Datums: Fallunterscheidungen
      Select Case DatumsDifferenz
        Case Is > 7
          ' zu weit in der Zukunft
          If NurVerbalisierung Then Return ("")
          Return NurDatum(dt)
        Case Is < -7
          ' zu weit in der Vergangenheit
          If NurVerbalisierung Then Return ("")
          Return NurDatum(dt)
        Case 0
          Return "Heute"
        Case -1
          Return "Gestern"
        Case -2
          Return "Vorgestern"
        Case 1
          Return "Morgen"
        Case 2
          Return "Übermorgen"
        Case Is > 2
          ' Wochentag (kommend)
          Return "kommender " + Wochentag(dt)
        Case Else
          ' Wochentag (vergangen)
          Return "vergangener " + Wochentag(dt)
      End Select
    End Function
    Public Function VerbalisiertesDatum_PlusUhrzeit( _
      ByVal dt As System.DateTime, _
      Optional ByVal NurVerbalisierung As Boolean = False) As String
     
      ' Bei dieser Funktion wird ggf. die Uhrzeit an den 
      ' Rückgabestring angehängt
     
      Dim datum As String
     
      datum = VerbalisiertesDatum(dt, NurVerbalisierung)
      If datum <> "" Then datum += (" " + NurUhrzeit(dt))
     
      Return datum
    End Function
    Public Function VerbalisiertesDatum_Intervall( _
      ByVal dt As System.DateTime, _
      Optional ByVal NurVerbalisierung As Boolean = False) As String
     
      ' Ein Datum wird umgewandelt in Angaben zur Tagesdifferenz 
      ' z.b.  'vor drei Tagen' oder 'in 14 Tagen' 
      ' falls es maximal 30 Tage vom aktuellen Datum entfernt ist
     
      ' Zahlen bis 12 werden als Zahlworte zurückgegeben
      Dim Zahlworte As String() = New String(12) _
        {"", "einem", "zwei", "drei", "vier", _
        "fünf", "sechs", "sieben", "acht", _
        "neun", "zehn", "elf", "zwölf"}
     
      ' Bestimmung der Zahl der Tageswechsel zwischen dem 
      ' aktuellen Datum und dem Inhalt des übergebenen Parameters
      Dim DatumsDifferenz As Integer = _
      TagesWechsel(System.DateTime.Now, dt)
     
      ' Fallunterscheidungen
      Select Case DatumsDifferenz
        Case Is > 30
          ' zu weit in der Zukunft
          If NurVerbalisierung Then Return ("")
          Return NurDatum(dt)
        Case Is < -30
          ' zu weit in der Vergangenheit
          If NurVerbalisierung Then Return ("")
          Return NurDatum(dt)
        Case Is > 12
          ' Anzahl der Tage als Zahl zurückgeben
          Return "in " + DatumsDifferenz.ToString + " Tagen"
        Case Is < -12
          ' Anzahl der Tage als Zahl zurückgeben 
          Return "vor " + (System.Math.Abs(DatumsDifferenz)).ToString + " Tagen"                                                                                                  
        Case 0
          Return ("Heute")
        Case 1
          Return ("in einem Tag")
        Case Is > 1
          ' Anzahl der Tage als Zahlwort zurückgeben
          Return "in " + Zahlworte(DatumsDifferenz) + " Tagen"
        Case -1
          Return ("vor einem Tag")
        Case Else
          ' Anzahl der Tage als Zahlwort zurückgeben
          Return "vor " + Zahlworte(System.Math.Abs(DatumsDifferenz)) + " Tagen"
      End Select
    End Function
    Public Function TagesWechsel(ByVal dt1 As System.DateTime, _
      ByVal dt2 As System.DateTime) As Long
     
      ' Zeitdifferenz, die die Zahl der Tageswechsel zwischen den 
      ' beiden Datumsangaben dt1, dt2 berechnet (Basis: lokale Zeit)
     
      dt1 = SetToLocalTime(dt1)
      dt2 = SetToLocalTime(dt2)
     
      TagesWechsel = Microsoft.VisualBasic.DateAndTime.DateDiff( _
      Microsoft.VisualBasic.DateInterval.Day, dt1.Date, dt2.Date)
    End Function
    Public Function SetToLocalTime(ByVal dt As Date) As Date
     
      ' falls im Parameter dt eine UTC-Zeit vorliegt,
      ' wird in die lokale Zeit umgewandelt
      ' falls Kind unbestimmt ist, erfolgt keine Änderung
     
      If dt.Kind = DateTimeKind.Utc Then
        dt = dt.ToLocalTime
      End If
      Return dt
    End Function
    Public Function Wochentag(ByVal dt As System.DateTime) As String
     
      ' Ermittlung des Wochentags zu einem Datum 
      ' ohne Beachtung der Windows-Systemeinstellungen (Sprache)
      ' für die Bezeichnung der Wochentage
     
      Dim Wochentage As String() = New String(7) _
        {"", "Sonntag", "Montag", "Dienstag", "Mittwoch", _
        "Donnerstag", "Freitag", "Samstag"}
     
      ' Der Parameter-Wert 'Sunday' entspricht der Voreinstellung
      Return (Wochentage(Microsoft.VisualBasic.Weekday( _
        dt, Microsoft.VisualBasic.FirstDayOfWeek.Sunday)))
    End Function
    Public Function NurDatum(ByVal dt As System.DateTime) As String
     
      ' Das in einer DateTime-Instanz enthaltene Datum  
      ' wird als Standardstring z.b. 24.3.2007 zurückgeben
      ' Windows-Einstellungen werden ignoriert
     
      Return (dt.Day.ToString + "." + dt.Month.ToString + "." _
        + dt.Year.ToString)
    End Function
    Public Function NurUhrzeit(ByVal dt As System.DateTime) As String
     
      ' Die in einer DateTime-Instanz enthaltene Uhrzeit  
      ' wird als Standardstring 00:00:00 zurückgeben
      ' Windows-Einstellungen werden ignoriert
     
      Return (dt.Hour.ToString + ":" + dt.Minute.ToString + ":" _
        + dt.Second.ToString)
    End Function
    Public Function VerbalisierteDateizeit( _
      ByVal PfadDatei As String) As String
     
      ' Die Funktion gibt das Datum der letzten Änderung einer 
      ' Datei, deren voller Pfad im Parameter "PfadDatei" gegeben 
      ' worden ist, zurück
     
      Err.Clear()
      Try
        With My.Computer.FileSystem
          ' Warnhinweis: Die Methode GetFileInfo löst bei 
          ' Zugriffsversuch auf eine fehlende Datei 
          ' keinen Fehler aus - 'FileExists' ist erforderlich
          If Not .FileExists(PfadDatei) Then
            Return "Fehler: Datei nicht gefunden"
          Else
            Return VerbalisiertesDatum( _
              .GetFileInfo(PfadDatei).LastWriteTime)
          End If
        End With
      Catch
        Return "Fehler: " + Err.Description
      End Try
    End Function
    ' ====================================================================
    ' Ende Quellcode
    ' ====================================================================

    Dieser Tipp wurde bereits 6.729 mal aufgerufen.

    Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

    Über diesen Tipp im Forum diskutieren
    Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

    Neue Diskussion eröffnen

    nach obenzurück


    Anzeige

    Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
    (einschl. Beispielprojekt!)

    Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
    - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
    - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
    Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
     
       

    Druckansicht Druckansicht Copyright ©2000-2015 vb@rchiv Dieter Otter
    Alle Rechte vorbehalten.

    Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

    Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel