2012-03-12 10 views
6

robię wykres że pokrycie "1930-1940", "1940-1950", "1950-1960", "1960-1970", ...Czy to najlepszy sposób na reprezentowanie dziesięcioleci w TimeSpan?

chcę reprezentować to z DateTime i Timespan, ale nie jestem pewien, jak zrobić TimeSpan, i trudno sprawdzić, czy moje timespans są poprawne.

Czy w ten sposób powinienem użyć TimeSpan, czy to się nakłada? Jeśli to się nakłada, to jak mogę to naprawić?

List<DateTime> list1 = new List<DateTime>(); 
List<TimeSpan> list2 = new List<TimeSpan>(); 

int startYearInt = 1930; 

int times = 0; 
const int intervalSize = 10; 
for (int i = startYearInt; i < 2020; i += intervalSize) 
{ 
    DateTime sYear = new DateTime(startYearInt + (intervalSize * times++), 1, 1); 
    TimeSpan period = (sYear.AddYears(intervalSize)) - sYear; 

    list1.Add(sYear); 
    list2.Add(period); // <<-- Don't know if if this is correct? 
} 

EDYCJA: Mam to również. A jeśli Mój przedział czasowy jest zbyt mały lub trwa do końca, może powodować pewne problemy.

public bool IsInsidePeriod(DateTime dt) 
{ 
    return dt >= FromYearDateTime && dt < FromYearDateTime.Add(periodTimeSpan); 
} 
+0

dlaczego po prostu nie przedstawiają je jako wskazówki? –

+0

Dlaczego DateTime _i_ TimeSpan? Wszystko czego potrzebujesz to n + 1 wartości DateTime. –

+4

'TimeSpan' jest prosty i ilość Czas nie jest związany z żadnymi punktami w czasie (10-letni okres to po prostu 10-krotna rozpiętość) lata temu lub tysiąc lat temu). – Oded

Odpowiedz

7

Lepiej tworząc rodzaj DateRange wartość niż przy użyciu DateTime i TimeSpan takiego. Na przykład patrz here. Możesz wtedy zastosować metodę fabryczną, która daje zakres przez dekadę: . W ten sposób podnosisz poziom abstrakcji i radzisz sobie z koncepcjami, które odnoszą się do w samym kodzie.

Twój IsInsidePeriod jest prostą operacją dla DateRange:

public bool Includes(DateTime date) { 
    return start <= date && date <= end; 
} 

(zakładając zarówno start i endwłącznie)

Teraz, jeśli tylko trzeba do czynienia z dziesięcioleci, ty tak naprawdę nie potrzebujesz pełnej klasy DateRange, tylko ta:

class Decade { 

    public int StartYear { get; private set; } 
    public int EndYear { get { return StartYear + 9; } } 

    public Decade(int startYear) { 
    StartYear = startYear; 
    } 

    public bool Includes(DateTime date) { 
    return StartYear <= date.Year && date.Year <= EndYear; 
    } 

    public override string ToString() { 
    return string.Format("{0}-{1}", StartYear, EndYear + 1); 
    } 

} 

A może bardziej ogólny YearRange.

+0

Dekada to okres 10, Twój kod Dekady nie działa :-) – Lloyd

+1

@Lloyd Ostatni rok dekady to 9 lat po rozpoczęciu roku. 10 lat później byłby początek kolejnej dekady – RichK

0

Można uprościć metodę IsInPeriod do czegoś takiego:

public bool IsInsidePeriod(DateTime dateToCompare, DateTime startDate, DateTime endDate) 
{ 
    return startDate <= dateToCompare && dateToCompare < endDate; 
} 

Jak wspominają inni, TimeSpan nie kupuje nic i jest overcomplicating swoją opisany problem. Zwróć szczególną uwagę na operatorów porównania. Możesz chcieć, aby każdy koniec był wyłączny, a nie integracyjny lub odwrotnie.

1

Jeśli wszystko prosicie zrobić, to rozwiązać bieżące problemy następnie poniższy kod prac, hej Jestem znudzony, chciałbym jednak rozważyć robi rozeznanie w zakresie DateTime, porównań (zwłaszcza jak praca z różnych stref czasowych i etc odstępach czasu.

DateTime on MSDN

class Program 
{ 
    static void Main(string[] args) 
    { 
     int interval = 10; 
     DateTime isInRangeDate = DateTime.UtcNow; 

     for (int i = 1930; i < 2020;) 
     { 
      DateRange range = new DateRange(1, 1, i, interval); 
      Console.WriteLine(string.Format("{0}: Is in range - {1}", range.ToString(), range.IsInsidePeriod(isInRangeDate))); 


      i = range.EndDate.Year; 
     }    

     Console.ReadLine(); 
    } 
} 


public class DateRange 
{ 
    public DateTime StartDate { get; private set; } 
    public DateTime EndDate { get; private set; } 

    public override string ToString() 
    { 
     return string.Format("{0}-{1}", this.StartDate.Year, this.EndDate.Year); 
    } 

    public DateRange(int day, int month, int year, int addYears) 
    { 
     StartDate = new DateTime(year, month, day, 0, 0, 0); 
     EndDate = StartDate.AddYears(addYears); 
    } 

    public bool IsInsidePeriod(DateTime dt) 
    { 
     return ((dt.Date >= StartDate) && (dt.Date < EndDate)); 
    } 
} 
Powiązane problemy