根据ISO规范,在C#中计算给定周数和年份的一周的开始和结束日期。

4

我需要生成一个报告,显示一年的52周(或某些年份为53周)及其开始和结束日期。有一个ISO规范可以实现此功能,但看起来非常复杂!我希望有人知道如何在C#或Visual Basic中实现它(实际上是为Visual Basic 6编写的,但我将尝试移植它)。

8个回答

5
您可以使用Calendar.GetWeekOfYear方法获取日期的周数,使用CalendarWeekRule.FirstFourDayWeek值指定如何确定周数,并使用DayOfWeek.Monday指定第一个工作日。这遵循ISO规范。
示例:
int week = Calendar.GetWeekOfYear(DateTime.Today, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

要获取一年中第一周的第一天,您可以从1月4日开始往回找,直到找到星期一为止:
DateTime t = new DateTime(DateTime.Today,Year, 1, 4);
while (t.DayOfWeek != DayOfWeek.Monday) t = t.AddDays(-1);

+1 看起来是最好的解决方案 - 它是Visual Basic,正如@Jimbo所需。我认为在我的场景(http://stackoverflow.com/questions/9741424/looking-for-definitive-iso-week-calculator-in-visual-basic-in-visual-studio-exp)中它将很有用。 - therobyouknow
我该使用什么来导入日历库?默认情况下,日历并未定义,因此我需要从某个地方导入它,但是从哪里导入呢? - therobyouknow
1
@therobyouknow:如果您查看Calendar类的参考文档http://msdn.microsoft.com/en-us/library/system.globalization.calendar.aspx,您会发现它位于“System.Globalization”命名空间中,因此这就是您需要导入的命名空间。由于它位于“mscorlib.dll”程序集中,因此您无需添加任何引用。 - Guffa
+1 感谢 @Guffa,我也自己找到了这个解决方案。所以要使用这个解决方案,我需要 1) 实例化一个继承自抽象 Calendar 类的具体类的实例,例如:GregorianCalendar,因为它是事实上的标准:Dim myCalendar As Calendar = New GregorianCalendar,然后 2) 使用该实例 Dim week As Integer = myCalendar.GetWeekOfYear(DateTime.Today, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday) - therobyouknow
@therobyouknow:是的,看起来没问题。我记得这个方法应该是静态的,但是查看了参考资料后发现它不是静态的。 - Guffa
开始/回到1月4日的原因是什么?1月4日有什么重要意义? - variable

2

这应该可以工作。我之前在报告中使用过它。虽然我同意它不是很美观:

DateTime GetWeekStartDate(int year, int week)
{
    DateTime jan1 = new DateTime(year, 1, 1);
    int day = (int)jan1.DayOfWeek - 1;
    int delta = (day < 4 ? -day : 7 - day) + 7 * (week - 1);

    return jan1.AddDays(delta);
}

这个函数可以计算特定周的起始日期。结束时间很明显是7天后(不包括当天)。

您可能会发现我的代码有用。虽然它几乎没有文档说明,但它实现了一些 WeekAndYear 结构的其他操作。还有很大的改进空间。最值得注意的是,它定义了 <> 操作符,但是没有其他操作符,这非常糟糕……但是它应该能让你开始工作。

不过要移植到 VB6 可能有点困难 :P


2

+1 我借鉴了那段代码,并使其返回一组iso周。 - ShuggyCoUk
哎呀,那段代码实际上是最棘手的部分。即使你出于某种原因想将其作为单个基本类型返回(我认为这是个坏主意),你也应该使用二进制 & 和右移操作,而不是除法和取模运算。 - Thorarin

2
这些函数满足了我的要求(适用于ASP Classic,因此涉及数据类型)。希望它们也能帮助其他人...
Function WeekNumber(dDate)
    Dim d2
    d2 = DateSerial(Year(dDate - WeekDay(dDate - 1) + 4), 1, 3)
    WeekNumber = Int((dDate - d2 + WeekDay(d2) + 5) / 7)
End Function

Function YearStart(iWhichYear)
    Dim iWeekDay
    Dim iNewYear
    iNewYear = DateSerial(iWhichYear, 1, 1)
    iWeekDay = (iNewYear - 2) Mod 7
    If iWeekDay < 4 Then
        YearStart = iNewYear - iWeekDay
    Else
        YearStart = iNewYear - iWeekDay + 7
    End If
End Function

Function WeeksInYear(iYear)
    WeeksInYear = WeekNumber(DateAdd("d", -1, YearStart(iYear + 1)))
End Function

Function WeekStart(iYear, iWeek)
    WeekStart = DateAdd("ww", iWeek - 1, YearStart(iYear))
End Function

Function WeekEnd(iYear, iWeek)
    WeekEnd = DateAdd("d", 6, DateAdd("ww", iWeek - 1, YearStart(iYear)))
End Function

1

这将给你本周的开始

dateAdd(DateAdd(DateInterval.Day, (Now.Day * -1), Now)

要获取本周的结束日期,只需将本周的开始日期加上7天即可


1

使用Calendar.GetWeekOfYear方法获取当前日期时间的周数,其余部分应该很简单。

对于vb6来说,这就不那么简单了,你最好找一个好的库来为你完成繁重的工作。



0

答案如下,也是最易理解的。

 '1 declaramos las variables 
 Public firstdayweek As Date 'variable para capturar el valor de inicio de semana de una fecha dada
 Public lastdayweek As Date 'variable para el valor de la fecha final de una semana de una fecha dada
  

 Friend Property _NSemana As Integer 'indica el numero de la semana 

 Friend Property _iniciosemana As Date 'contiene la primer fecha de la semana dada
  
  'Fuciones para codigo 
  'Funcion para calcular la semana actual en la que estamos
 Function semana() As Date
          _NSemana = (DateDiff(DateInterval.WeekOfYear, DateTime.Today,                                                           New DateTime(DateTime.Today.Year, 1, 1)) *-1)
 End Function
  
  'esta funcion es la que llamaremos para setear cada valor puedes colocarlo en cualquier evento
  
  Public Sub damerangosemana()
  semana()
  _iniciosemana = RangoSemana((_NSemana + 1), Today.Year)
  firstdayweek = _iniciosemana
  lastdayweek = FinSemana(_iniciosemana)
 End Sub
  
  'con esta funcion capturamos el dia de la semana y asignamos la fecha incial 
  Public Function RangoSemana(ByVal WeekNumber As Integer, ByVal year1 As Integer) As Date
  Dim numdia As Integer = 0
  Dim oneDate As String
  Dim PrimerDia As Date

  oneDate = "1/1/" & year1.ToString
  PrimerDia = DateAndTime.DateValue(oneDate)
  'dayOfYear = inDate.DayOfYear
  Select Case PrimerDia.DayOfWeek
   Case DayOfWeek.Sunday
    numdia = 7
   Case DayOfWeek.Monday
    numdia = 1
   Case DayOfWeek.Tuesday
    numdia = 2
   Case DayOfWeek.Wednesday
    numdia = 3
   Case DayOfWeek.Thursday
    numdia = 4
   Case DayOfWeek.Friday
    numdia = 5
   Case DayOfWeek.Saturday
    numdia = 6
  End Select

  Dim x As Date = DateAdd(DateInterval.Day, 0 - numdia, CType(oneDate, Date))
  Dim startdate As Date = DateAdd(DateInterval.WeekOfYear, WeekNumber - 1, x)
  Return startdate
 End Function
  
  'funcion para calcular la fecha final
  Public Function FinSemana(ByVal Date1 As Date) As Date
  Return DateAdd(DateInterval.Day, 7, Date1)
 End Function


  
  


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接