AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Klasse für Zeitraum erstellen

Ein Thema von Angel4585 · begonnen am 5. Jan 2012 · letzter Beitrag vom 5. Jan 2012
Antwort Antwort
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#1

Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 11:50
Hallo,

ich möchte eine Klasse erstellen für einen Art Zeitraum.
Zeitraum ist z.B. sowas wie "Dieses Jahr", "Dieser Monat" oder "Letzte 10 Tage".

Wenn ich ein Objekt dieser Klasse erstelle soll mir das Objekt über die Methoden GetStart und GetEnd die DateTime Werte für Start und Ende des Zeitraumes zurückgeben.

Ich hab nur leider keine Idee was für einen Wert ich dem Konstruktor übergeben könnte, damit das Objekt weis "Aha der will als Zeitraum dieses Jahr".
Das Objekt sollte also zum Datum 12.2.2012 zurückgeben 01.01.2011 - 31.12.2012.
Ein Objekt der selben Klasse für "Dieser Monat" sollte mir an o.g. Datum zurückliefern 01.02.2012 - 29.02.2012.

Wenn das Programm eine Zeit lang läuft zb. über eine Monatsgrenze hinweg sollte mir das Objekt automagisch den Zeitraum des dann neuen Monats zurückliefern.

Zudem sollen diese Objekte frei erstellbar sein, sowas wie "Letzte X Jahre", "Letzte X Monate" usw sollten auch zur Laufzeit erzeugbar sein.

Habt ihr mir nen Tipp was für Werte ich beim Erzeugen des Objekts mitgeben könnte damit das automatisch weis was es machen soll?
Bzw. gibt es ein Pattern über das man das lösen könnte?

Edit: schön wäre auch wenn sowas ginge wie "Gleicher Monat im Letzten Jahr"
Martin Weber
Ich bin ein Rüsselmops

Geändert von Angel4585 ( 5. Jan 2012 um 12:11 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 14:11
Ich würde das ganz banal angehen. Eine Klasse mit 2 Properties "FromDateTime" und "ToDateTime", und einer Sammlung an Methoden. Alternativ eine Klasse mit 3 Datums-Properties und Read-Only Properties, die auf entsprechende Getter verweisen. Die verschiedenen Methoden/Getter ließen sich auch noch durch einen Enum ersetzen, und einer generellen "GetRange"-Methode.

Delphi-Quellcode:
type
  TDateTimeRange = class(TObject)
  private
    FFromTime, FToTime: TDateTime;
  public
    property FromTime: TDateTime read FFromTime;
    property ToTime: TDateTime read FToTime;
    function GetYearRange(relativeTo: TDateTime): TDateTimeRange;
    function GetMonthRange(relativeTo: TDateTime): TDateTimeRange;
    function GetDayRange(relativeTo: TDateTime): TDateTimeRange;
    // etc.
  end;

// oder

  TDateTimeRange = class(TObject)
  private
    FFromTime, FToTime, FRelativeTime: TDateTime;
    function GetYearRange: TDateTimeRange;
    function GetMonthRange: TDateTimeRange;
    function GetDayRange: TDateTimeRange;
  public
    constructor Create(aRelativeTime: TDateTime);
    property FromTime: TDateTime read FFromTime;
    property ToTime: TDateTime read FToTime;
    property RelativeTime: TDateTime read FRelativeTime write FRelativeTime;
    property YearRange: TDateTimeRange read GetYearRange;
    property MonthRange: TDateTimeRange read GetMonthRange;
    property DateRange: TDateTimeRange read GetDateRange;
    // etc.
  end;

// ooooder:

  TDateTimeRangeMode = (dtrmYear, dtrmMonth, dtrmDay);

  TDateTimeRange = class(TObject)
  private
    FFromTime, FToTime, FRelativeTime: TDateTime;
    FRangeMode: TDateTimeRangeMode;
    function GetRange: TDateTimeRange;
  public
    constructor Create(aRelativeTime: TDateTime; aRangeMode: TDateTimeRangeMode);
    property FromTime: TDateTime read FFromTime;
    property ToTime: TDateTime read FToTime;
    property RelativeTime: TDateTime read FRelativeTime write FRelativeTime;
    property Range: TDateTimeRange read GetRange;
  end;
Darin ließe sich auch noch statisch eine Factory einbauen, die etwas wie TDateTimeRange.CreateNewRange(aRelativeTime: TDateTime; aRangeMode: TDateTimeRangeMode): TDateTimeRange; bietet, wodurch sich das Problem etwas mildert, dass solche Konstrukte wie oben in nicht-GC Umgebungen ggf. doof zu handhaben sind.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 14:29
Danke erstmal
Da muss ich jetzt aber erstmal durchsteigen, wie würde ich da jetzt einen Zeitraum a la "Die letzten 3 Monate" (aktuell wäre das dann 1.11.11 - 1.1.12) darstellen?

Ich hab derweil auch bissl gebastelt und bin bisher bei folgender Klasse gelandet( ist jetz halt C# aber lesen kann man das ja trotzdem ):
Code:
    public class Period : IPeriod
    {
        public const int DAYS   = 0;
        public const int WEEKS  = 1;
        public const int MONTHS = 2;
        public const int YEARS  = 3;
       
        private int kind;
        private int start;
        private int length;
        private string name;
       
        public Period(int kind, int start, int length, string name)
        {
            this.kind = kind;
            this.start = start;
            this.length = length;
            this.name = name;
        }
       
        public DateTime GetStart()
        {
            DateTime date = DateTime.Today;
            switch(kind){
                case DAYS:
                    date = date.AddDays(start);
                    break;
                case WEEKS:
                    date = date.AddDays(-(int)date.DayOfWeek + 7*start);
                    break;
                case MONTHS:
                    date = date.AddDays(-date.Day+1).AddMonths(start);
                    break;
                case YEARS:
                    date = date.AddDays(-date.DayOfYear+1).AddYears(start);
                    break;
            }
            return date;
        }
       
        public DateTime GetEnd()
        {
            DateTime date = DateTime.Today;
            switch(kind){
                case DAYS:
                    date = date.AddDays(start+length).AddSeconds(-1);
                    break;
                case WEEKS:
                    date = date.AddDays(-(int)date.DayOfWeek + 7*start + 7*length).AddSeconds(-1);
                    break;
                case MONTHS:
                    date = date.AddDays(-date.Day+1).AddMonths(start+length).AddSeconds(-1);
                    break;
                case YEARS:
                    date = date.AddDays(-date.DayOfYear+1).AddYears(start+length).AddSeconds(-1);
                    break;
            }
            return date;
        }
       
        public string GetName()
        {
            return name;
        }
    }
Beim Start wird übergeben was für eine Art von Spanne es ist, also ob Jahre, Monate, Wochen oder Tage.
Dazu wird ein relativer Start übergeben, 0 wäre heute, bzw diese Woche, dieser Monat usw., -1 wäre gestern bzw letzte Woche..
Ausserdem die Länge des Zeitraumes, z.B. 1 (Anzahl der Tage, Wochen etc)

new Period(Period.DAYS,0,1,"Heute") wäre dann Heute 00:00:00 bis Heute 23:59:59
new Period(Period.DAYS,-1,1,"Gestern") wäre dann Gestern 00:00:00 bis Gestern 23:59:59

Durch diese Struktur hab ich die Möglichkeit die drei vier Werte abzuspeichern und später wieder zu laden, was evtl ein interessantes Feature sein könnte.

Bin grad noch dabei verschiedene Sachen damit zu testen.

Bei meinem Glück gibt es mal wieder irgendwas, was dagegen spricht das so zu machen, könnt mich ja zur Erleuchtungbringen
Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 15:07
Da würde ich spontan kleinere Schönheitskorrekturen machen erstmal.
Code:
    public enum RangeKind(Days, Weeks, Months, Years);
    public class Period : IPeriod
    {
        private RangeKind Kind;
        private int Start;
        private int Length;
        private string Name;
       
        public Period(RangeKind kind, int start, int length, string name)
        {
            Kind = kind;
            Start = start;
            Length = length;
            Name = name;
        }
       
        public DateTime StartTime{
                get{
                    DateTime date = DateTime.Today;
                    switch(kind){
                        case Days:
                            date = date.AddDays(start);
                            break;
                        case Weeks:
                            date = date.AddDays(-(int)date.DayOfWeek + 7*start);
                            break;
                        case Months:
                            date = date.AddDays(-date.Day+1).AddMonths(start);
                            break;
                        case Years:
                            date = date.AddDays(-date.DayOfYear+1).AddYears(start);
                            break;
                    }
                    return date;
                }
        }
       
        public DateTime EndTime{
                get{
                    DateTime date = DateTime.Today;
                    switch(kind){
                        case Days:
                            date = date.AddDays(start+length).AddSeconds(-1);
                            break;
                        case Weeks:
                            date = date.AddDays(-(int)date.DayOfWeek + 7*start + 7*length).AddSeconds(-1);
                            break;
                        case Months:
                            date = date.AddDays(-date.Day+1).AddMonths(start+length).AddSeconds(-1);
                            break;
                        case Years:
                            date = date.AddDays(-date.DayOfYear+1).AddYears(start+length).AddSeconds(-1);
                            break;
                    }
                    return date;
                }
        }
       
        public string Name{get{return name;}}
    }
Das aber eher, um "Gepflogenheiten" in C# gerecht zu werden. Aber wenn du schon einen GC und einen Enum hast, würde ich fast auf meinen 3. Vorschlag inkl. der Factory gehen. Ich würde als Zeitparameter (Start) zudem auch eher einen DateTime übergeben, und in der Klasse dann errechnen welcher Wert dem Anfang im gewünschten RangeKind entspricht. Dann ließe sich das ganze immer schön schlank mit "Now" aufrufen lassen.
Man könnte zudem den Enum statt als Feld auch als Index-Parameter für die Properties nehmen, so dass man nachher aufrufen würde "DateTime myStartTime = new Period(Now, "foo").StartTime[Weeks];".
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#5

AW: Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 16:44
Ja das mit dem enum wollte ich so oder so noch machen.

Hmmm also den Zweck von dem Index versteh ich hier nicht ganz.


Es gibt ja auch nicht einen Startwert für Weeks usw sondern es kann beliebig viele geben.

Wenn ich sag der Zeitraum beginnt vor zwei Wochen und dauert 4 Wochen ist es ein anderer Startwert als wenn mein Zeitraum vor 3 Monaten beginnt und 10 Wochen dauert.

Ich seh bei dem Aufruf "DateTime myStartTime = new Period(Now, "foo").StartTime[Weeks];" jetzt nicht wie ich da so flexibel bleib, da ist schliesslich weder Start noch Dauer/Ende des Zeitraumes. Oder meinst du hier mit Weeks also dem Index selbst die Anzahl der Wochen bis jetzt? Das wäre evtl geschickt, aber warum dann über nen Index und nicht als Funktionsparameter?
Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 17:43
Ah! Okay, jetzt verstehe ich was du mit der Länge wolltest . Die würde dann als 3. Parameter erhalten bleiben. Was den Index angeht: In der .NET-Welt sind Getter dieser Art eher selten, und ich glaube ich muss es auch ein wenig als persönliche Vorliebe bezeichnen, tunlichst Properties einzusetzen wo sinnvoll machbar. Der Index ist ja im Grunde nur ein Argument für den Getter, ähnlich wie das ja auch in Delphi geht. Ich sehe aber allmählich ein, dass das hier semantisch am Ende doch eher verwirrend sein könnte

Ich hatte es auch erst so verstanden, dass du nur wissen möchtest, in welcher Woche/Monat/Jahr ein bestimmer Zeitpunkt liegt, und das als Datumswerte der Intervallgrenzen. Aber ich glaube, wir reden mittlerweile etwas mehr über das selbe . Ich brauch Feierabend...
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#7

AW: Klasse für Zeitraum erstellen

  Alt 5. Jan 2012, 20:11
Ich hatte das mal für ein Reporting-Tool gebastelt.
Es ist eine Komponente, der man ein Datum sowie den gewünschten Zeitraum übergibt.
Ein Zeitraum ist "Tag, Woche, Monat, Quartal, Jahr"
In den Eigenschaften "FirstOfPeriod" und "LastOfPeriod" steht dann der erste bzw. letzte Tag des Zeitraums.
In der Eigenschaft "PeriodName" steht der Name des Quartals, also z.B. "9.1.2012" oder "KW 02", "Q 1/11" usw.
Wenn man FirstOfPeriod und LastOfPeriod setzt, ändert sich der Zeitraum auf "Custom" und der PeriodName liefert dann z.B. "1.2.2012 - 4.2.2012"

Dann kann man noch Scherze einbauen, sodaß die Klasse Datumse à la "TODAY", "TOMORROW" "FIRST OF MONTH" oder "NEXT MONDAY" oder irgendwieso versteht und einfach entsprechend ausrechnet.

Ich hatte dann noch Iterationsmethoden "NextDay", "NextWeek".

War echt praktisch. Kann ich hier mal reinstellen, bei Bedarf. Ist aber Rotzencode.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz