2012-03-12 36 views
6

Tôi đang thực hiện một biểu đồ bao phủ "1930-1940", "1940-1950", "1950-1960", "1960-1970", ...Đây có phải là cách tốt nhất để đại diện cho thập kỷ với TimeSpan không?

tôi muốn đại diện cho điều này với một DateTimeTimespan, nhưng tôi không thực sự chắc chắn làm thế nào để làm cho TimeSpan, và tôi thấy khó để xác minh nếu timespans của tôi đúng.

Đây có phải là cách tôi nên sử dụng TimeSpan hoặc chồng chéo không? Nếu nó trùng lặp thì làm thế nào tôi có thể sửa nó?

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? 
} 

EDIT: Tôi cũng có điều này. Và nếu khoảng thời gian của tôi quá nhỏ hoặc cuối cùng thì nó có thể gây ra một số vấn đề.

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

tại sao bạn không chỉ đại diện cho họ như ints? –

+0

Tại sao DateTime _and_ TimeSpan? Tất cả bạn cần là n + 1 giá trị DateTime. –

+4

A 'TimeSpan' đơn giản và số lượng là thời gian, không gắn liền với bất kỳ điểm nào trong thời gian (một khoảng thời gian 10 năm chỉ là - nó có thể là một khoảng 10 một thế kỷ trước hoặc một thiên niên kỷ do đó). – Oded

Trả lời

7

Bạn nên tạo ra một loại giá trị DateRange vì sử dụng một DateTimeTimeSpan như thế. Hãy xem here để biết ví dụ. Sau đó bạn có thể có một phương pháp nhà máy cung cấp cho bạn một phạm vi trong một thập kỷ: . Bằng cách này, bạn nâng mức trừu tượng và xử lý các khái niệm mà bạn đang đề cập đến trong chính mã đó.

bạn IsInsidePeriod là một thao tác đơn giản cho DateRange:

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

(giả sử cả startendbao gồm)

Bây giờ, nếu bạn chỉ cần để đối phó với thập kỷ, bạn không thực sự cần một lớp học đầy đủ DateRange, chỉ cần điều này:

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); 
    } 

} 

Hoặc có thể là tổng quát hơn YearRange.

+0

thập kỷ là khoảng thời gian 10, mã thập phân của bạn không hoạt động :-) – Lloyd

+1

@Lloyd Năm cuối của một thập kỷ là 9 năm sau năm bắt đầu. 10 năm sau sẽ là khởi đầu của một thập kỷ nữa – RichK

0

Bạn có thể đơn giản hóa phương pháp IsInPeriod của bạn để một cái gì đó như thế này:

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

Như những người khác đã đề cập, TimeSpan không mua bất cứ thứ gì và được overcomplicating vấn đề mô tả của bạn. Đặc biệt chú ý đến các toán tử so sánh. Bạn có thể muốn kết thúc là độc quyền thay vì bao gồm hoặc ngược lại.

1

Nếu tất cả những gì bạn muốn làm là giải quyết các vấn đề hiện tại của bạn thì mã này hoạt động, tôi chán, tôi sẽ xem xét một số nghiên cứu về phạm vi DateTime, so sánh (đặc biệt là cách làm việc với các múi giờ khác nhau v.v. khoảng thời gian.

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)); 
    } 
} 
Các vấn đề liên quan