2009-09-30 34 views

Trả lời

72
var currentCulture = CultureInfo.CurrentCulture; 
var weekNo = currentCulture.Calendar.GetWeekOfYear(
       new DateTime(2013, 12, 31), 
       currentCulture.DateTimeFormat.CalendarWeekRule, 
       currentCulture.DateTimeFormat.FirstDayOfWeek); 

Hãy nhận biết rằng đây là khôngISO 8601 tương thích. Tại Thụy Điển, chúng tôi sử dụng tiêu chuẩn ISO 8601 week số nhưng mặc dù nền văn hóa được thiết lập để "sv-SE", CalendarWeekRuleFirstFourDayWeek, và FirstDayOfWeek là Thứ Hai các weekNo biến sẽ được thiết lập để thay vì đúng trong mã trên.

Tôi chỉ thử với cài đặt tiếng Thụy Điển nhưng tôi khá chắc chắn rằng tất cả các quốc gia (Áo, Đức, Thụy Sĩ và nhiều hơn nữa) sử dụng số liệu theo tuần ISO 8601 sẽ bị ảnh hưởng bởi sự cố này.

Peter van OoijenShawn Steele có các giải pháp khác nhau cho vấn đề này.

Dưới đây là một giải pháp nhỏ gọn

private static int WeekOfYearISO8601(DateTime date) 
{ 
    var day = (int)CultureInfo.CurrentCulture.Calendar.GetDayOfWeek(date); 
    return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.AddDays(4 - (day == 0 ? 7 : day)), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 
} 

Nó được thử nghiệm vào những ngày sau

var datesAndISO8601Weeks = new Dictionary<DateTime, int> 
         { 
          {new DateTime(2000, 12, 31), 52}, 
          {new DateTime(2001, 1, 1), 1}, 
          {new DateTime(2005, 1, 1), 53}, 
          {new DateTime(2007, 12, 31), 1}, 
          {new DateTime(2008, 12, 29), 1}, 
          {new DateTime(2010, 1, 3), 53}, 
          {new DateTime(2011, 12, 31), 52}, 
          {new DateTime(2012, 1, 1), 52}, 
          {new DateTime(2013, 1, 2), 1}, 
          {new DateTime(2013, 12, 31), 1}, 
         }; 

foreach (var dateWeek in datesAndISO8601Weeks) 
{ 
    Debug.Assert(WeekOfYearISO8601(dateWeek.Key) == dateWeek.Value, dateWeek.Key.ToShortDateString() + " should be week number " + dateWeek.Value + " but was " + WeekOfYearISO8601(dateWeek.Key)); 
} 
+1

Câu trả lời rất hay. Cảm ơn – roosteronacid

+0

vấn đề tương tự với phần còn lại của scandinavia Tôi nghĩ rằng, tôi là danish và tôi đã tự hỏi tại sao các thử nghiệm của tôi cho thấy 31/12 là tuần # 53 quá như Google Calender của tôi nói tuần của nó # 1. – BerggreenDK

+0

tại sao sử dụng "var" ở khắp mọi nơi? – AndreaCi

1
My.Computer.Info.InstalledUICulture.DateTimeFormat.Calendar.GetWeekOfYear(yourDateHere, CalendarWeekRule.FirstDay, My.Computer.Info.InstalledUICulture.DateTimeFormat.FirstDayOfWeek) 

Something như thế này ...

4
public static int GetWeekNumber(DateTime dtPassed) 
    { 
      CultureInfo ciCurr = CultureInfo.CurrentCulture; 
      int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 
      return weekNum; 
    } 
4

Check-out GetWeekOfYear trên MSDN có ví dụ này:

using System; 
using System.Globalization; 


public class SamplesCalendar { 

    public static void Main() { 

     // Gets the Calendar instance associated with a CultureInfo. 
     CultureInfo myCI = new CultureInfo("en-US"); 
     Calendar myCal = myCI.Calendar; 

     // Gets the DTFI properties required by GetWeekOfYear. 
     CalendarWeekRule myCWR = myCI.DateTimeFormat.CalendarWeekRule; 
     DayOfWeek myFirstDOW = myCI.DateTimeFormat.FirstDayOfWeek; 

     // Displays the number of the current week relative to the beginning of the year. 
     Console.WriteLine("The CalendarWeekRule used for the en-US culture is {0}.", myCWR); 
     Console.WriteLine("The FirstDayOfWeek used for the en-US culture is {0}.", myFirstDOW); 
     Console.WriteLine("Therefore, the current week is Week {0} of the current year.", myCal.GetWeekOfYear(DateTime.Now, myCWR, myFirstDOW)); 

     // Displays the total number of weeks in the current year. 
     DateTime LastDay = new System.DateTime(DateTime.Now.Year, 12, 31); 
     Console.WriteLine("There are {0} weeks in the current year ({1}).", myCal.GetWeekOfYear(LastDay, myCWR, myFirstDOW), LastDay.Year); 

    } 

} 
1

Tôi biết đây là muộn, nhưng vì nó đã đưa ra trong tìm kiếm của tôi, tôi nghĩ tôi sẽ ném một khác nhau giải pháp in Đây là giải pháp aC#.

(int)(Math.Ceiling((decimal)startDate.Day/7)) + (((new DateTime(startDate.Year, startDate.Month, 1).DayOfWeek) > startDate.DayOfWeek) ? 1 : 0);   
+0

Điều này trả về "5" cho ngày 29/12/2016 - nó sẽ trả về 52 – DNKROZ

0

var cultureInfo = CultureInfo.CurrentCulture; var calendar = cultureInfo.Calendar;

 var calendarWeekRule = cultureInfo.DateTimeFormat.CalendarWeekRule; 
     var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek; 
     var lastDayOfWeek = cultureInfo.LCID == 1033 //En-us 
      ? DayOfWeek.Saturday 
      : DayOfWeek.Sunday; 

     var lastDayOfYear = new DateTime(date.Year, 12, 31); 

     //Check if this is the last week in the year and it doesn`t occupy the whole week 
     var weekNumber = calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek); 
     return weekNumber == 53 && lastDayOfYear.DayOfWeek != lastDayOfWeek 
       ? 1 
       : weekNumber; 

Nó hoạt động tốt cho cả nền văn hóa Mỹ và Nga. ISO 8601 cũng sẽ chính xác, vì tuần tiếng Nga bắt đầu vào thứ Hai.

1

Nếu bạn muốn Số Tuần ISO 8601, trong đó tuần bắt đầu bằng thứ hai, tất cả tuần là bảy ngày và tuần 1 là tuần chứa ngày thứ năm đầu tiên của năm, đây có thể là giải pháp.

Vì dường như không có văn hóa .Net mang lại số tuần ISO-8601 chính xác, tôi sẽ bỏ qua việc xác định tuần được xây dựng trong suốt, và thực hiện phép tính theo cách thủ công, thay vì khống chế chính xác một kết quả chính xác một phần.

Những gì tôi đã kết thúc với là phương pháp mở rộng sau:

public static int GetIso8601WeekNumber(this DateTime date) 
{ var thursday = date.AddDays(3 - ((int)date.DayOfWeek + 6) % 7); 
    return 1 + (thursday.DayOfYear - 1)/7; 
} 

Trước hết, ((int) date.DayOfWeek + 6)% 7) xác định số ngày trong tuần, 0 = thứ hai, 6 = chủ nhật.

date.AddDays (- ((int) date.DayOfWeek + 6)% 7) xác định ngày thứ hai bắt đầu số tuần được yêu cầu.

Ba ngày sau là Thứ Năm mục tiêu, trong đó xác định những gì năm tuần đó tham gia.

Nếu bạn chia (zero based) ngày số trong năm bởi bảy (làm tròn xuống), bạn sẽ có được (số không tuần) trong năm.

Trong C#, kết quả tính toán số nguyên được làm tròn hoàn toàn.

Các vấn đề liên quan