【问题标题】:algorithm for calculating a week # from a date with custom start of week? (for iCal)从具有自定义一周开始的日期计算一周的算法? (对于 iCal)
【发布时间】:2012-01-25 08:50:24
【问题描述】:

我只能找到获得 ISO 8601 周的算法(周从星期一开始)。

但是,iCal 规范说

一周定义为 7 天,从 week 定义为一周的开始(参见 WKST)。第一周 日历年是包含至少四 (4) 天的第一周 在那个日历年。

因此,它比 ISO 8601 更复杂,因为一周的开始可以是一周中的任何一天。

是否有一种算法可以确定日期的周数,并具有自定义的一周开始日期?

或者...iCal4j 中有这样的功能吗?根据日期确定星期几?

谢谢!

附言限制:我使用的 JVM 语言无法扩展 Java 类,但我可以调用 Java 方法或实例化 Java 类。

【问题讨论】:

  • 我认为 jodatime 不是一种选择,就像滥用 java.util.Calendar 一样?
  • 根据该链接,iCal 周数的定义方式与 ISO8601 周数相同。看起来你开车的问题在这里处理:stackoverflow.com/q/1801907/93922
  • @TetsujinoOni 不是真的。 iCal 使用 WKST 变量来定义哪一天是一周的开始。虽然默认是星期一,就像 ISO8601 一样,但它可以是一周中的任何一天。
  • 更详细地查看 JodaTime 我认为使用您的 WKST 设置自定义年表以重新设置基准,并结合 weekyear() 和 weekOfWeekyear() 将让您到达目的地。
  • @TetsujinnoOni 我看了org.joda.time.chrono.ISOChronology,但我不能轻易地“重新设置”它。我想我仍然需要编写一个扩展 org.joda.time.chrono.BaseChronology 的新对象,但我无法编写新对象,因为我使用的 JVM 语言不允许我编写新类。

标签: algorithm calendar icalendar week-number ical4j


【解决方案1】:
if (input_date < firstDateOfTheYear(WKST, year))
{
    return ((isLeapYear(year-1))?53:52);
}
else
{
    return ((dayOfYear(input_date) - firstDateOfTheYear(WKST, year).day)/7 + 1);
}

firstDateOfTheYear 返回给定一周开始 (WKST) 和年份的第一个日历日期,例如如果 WKST = 星期四,年份 = 2012,则返回 1 月 5 日。

dayOfYear 返回一年中的连续数字日期,例如2 月 1 日 = 32

示例 #1: 2012 年 1 月 18 日,每周的开始时间是星期一

  • dayOfYear(2012 年 1 月 18 日) = 18
  • firstDateOfTheYear(2012 年星期一)= 2012 年 1 月 2 日

(18 - 2)/7 + 1 = 3 回答周没有。 3

示例 #2: 2012 年 1 月 18 日,每周开始是星期四

  • dayOfYear(2012 年 1 月 18 日) = 18
  • firstDateOfTheYear(2012 年星期四)= 2012 年 1 月 5 日

(18 - 5)/7 + 1 = 2 回答周没有。 2

示例 #3: 2012 年 1 月 1 日,每周的开始时间是星期一

  • firstDateOfTheYear(2012 年星期一)= 2012 年 1 月 2 日
  • IsLeapYear(2012-1) = 假

2012 年 1 月 1 日

【讨论】:

  • 2009 年 1 月 1 日,WKST = 星期一。 2009 年的第一个星期一是第 5 个,但 2009 年 1 月 1 日是第 1 周,而不是前一年的最后一周。这个算法坏了。见personal.ecu.edu/mccartyr/isowdcal.html
  • 好点!这是因为我的第一个条件:'if(input_date 4,那么该天之前的所有日期都必须是第 1 周,随后的几周必须是 + 1。我相信您可以弄清楚如何改进适合该逻辑的伪代码;)
  • 这也使示例 #2 无效。答案应该是第 3 周,因为 2012 年 1 月 5 日之前还有 4 天应该被视为第 1 周。
【解决方案2】:
  1. daysInFirstWeek 为一年中第一周的天数,即一月份。一周从WKST 一天开始。 (例如,如果 1 月 1 日是 WKST 日,则返回 7)

  2. dayOfYear 设置为输入日期年份的第 n 天(例如,2 月 1 日 = 32)

  3. 如果dayOfYear 小于或等于daysInFirstWeek

    3.1。如果daysInFirstWeek大于等于4,weekNo为1,则跳至步骤5。

    3.2。设daysInFirstWeekOfLastYear 为上一年第一周的一月份的天数。一周从WKST 一天开始。

    3.3。如果daysInFirstWeekOfLastYear 是4 或去年是闰年并且daysInFirstWeekOfLastYear 是5,weekNo 是53,否则weekNo 是52,跳到步骤5。

  4. weekNo 设置为ceiling((dayOfYear - daysInFirstWeek) / 7)

    4.1。如果daysInFirstWeek 大于或等于4,则将weekNo 加1

    4.2。如果 daysInFirstWeek 等于 53 并且 inputDate 所在年份 1 月的第一周(从 WKST 开始)的天数 + 1 大于或等于 4,则将 weekNo 设置为 1

  5. 返回weekNo

【讨论】:

  • 我想4.2应该是:4.2。如果 weekNo 等于 53 且 inputDate 所在年份 + 1 的第一周(从 WKST 开始)的天数大于或等于 4,则将 weekNo 设置为 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多