【问题标题】:Get localized week number with JodaTime使用 JodaTime 获取本地化的周数
【发布时间】:2017-02-16 10:18:38
【问题描述】:

我正在尝试使用 JodaTime 获取当前周数。

在法国,星期是这样定义的:

  • 一周从星期一开始(而在美国,一周从星期日开始)。
  • 一年中的第一周是包含 1 月 4 日的那一周(而 IMO,在美国是包含 1 月 1 日的那一周。对吗?我验证了 here)。

示例:2012 年 1 月 1 日是星期日。 因此,

  • 根据法国日历,它属于201152周。
  • 根据美国日历,属于20121

使用JodaTime,我发现我可以使用以下方法DateTime#getWeekOfWeekyear()获取周数。

我认为通过指定正确的时区,我会得到一个本地化的结果:

DateTime dtFr = new DateTime(2012, 1, 1, 11,11, DateTimeZone.forTimeZone(TimeZone.getTimeZone("Europe/Paris")));
DateTime dtUS = new DateTime(2012, 1, 1, 11,11, DateTimeZone.forTimeZone(TimeZone.getTimeZone("US/Arizona")));
LOGGER.info("weekYear (FR) : " + dtFr.weekyear().get());
LOGGER.info("weekOfWeekYear (FR) : " + dtFr.getWeekOfWeekyear());
LOGGER.info("weekYear (US) : " + dtUS.weekyear().get());
LOGGER.info("weekOfWeekYear (US) : " + dtUS.getWeekOfWeekyear());

输出是:

2014-03-05 11:28:08,708 - INFO - c.g.s.u.JodaTest - weekYear (FR) : 2011
2014-03-05 11:28:08,709 - INFO - c.g.s.u.JodaTest - weekOfWeekYear (FR) : 52
2014-03-05 11:28:08,709 - INFO - c.g.s.u.JodaTest - weekYear (US) : 2011
2014-03-05 11:28:08,709 - INFO - c.g.s.u.JodaTest - weekOfWeekYear (US) : 52

我已经预料到了:

  • weekYear(美国):2012
  • weekOfWeekYear(美国):1

我的代码有问题吗?

【问题讨论】:

    标签: java jodatime


    【解决方案1】:

    对本地化周数问题的悲哀回答:JodaTime 不支持它,仅支持 ISO-8601 定义的周数。我知道对于许多用户来说,这就像一个节目终结者。这里旧的 java.util.*-stuff 显然更好。

    在 JodaTime 中实现此功能的唯一方法是引入一个专门的日期时间字段,但正如项目负责人自己承认的那样,实施起来肯定不容易。这已经是noticed in year 2007,但此后没有发生任何事情。

    顺便说一句,时区与本地化周数问题无关,因此您无法通过任何类型的时区配置来解决这个旧的 Joda 问题。

    【讨论】:

      【解决方案2】:

      我知道这个问题已经存在 3 年了,但是随着 Java 8 及更高版本中内置的 java.time 类,现在可以使用优雅的短代码解决这个问题,而无需 Joda-Time:

      import java.time.DayOfWeek;
      import java.time.LocalDate;
      import java.time.temporal.WeekFields;
      
      public class USWeek {
      
          public static final WeekFields US_WEEK_FIELDS = WeekFields.of(DayOfWeek.SUNDAY, 4);
          // equivalent to: public static final WeekFields US_WEEK_FIELDS = WeekFields.SUNDAY_START;
          // equivalent to: public static final WeekFields US_WEEK_FIELDS = WeekFields.of(Locale.US);
      
          public static int getWeek(LocalDate date) {
              return date.get(US_WEEK_FIELDS.weekOfWeekBasedYear());
          }
      
          public static int getYear(LocalDate date) {
              return date.get(US_WEEK_FIELDS.weekBasedYear());
          }
      }
      

      注意:在此代码中,美国周定义是硬编码的。 WeekFields 对象也可以通过调用WeekFields.of( Locale )Locale 定义。

      【讨论】:

        【解决方案3】:

        根据此方法的 Joda Time 描述 -

        Joda Time

        描述是-

        public int getWeekOfWeekyear()
        Get the week of weekyear field value.
        This field is associated with the "weekyear" via getWeekyear(). In the standard ISO8601 week algorithm, the first week of the year is that in which at least 4 days are in the year. As a result of this definition, day 1 of the first week may be in the previous year.
        
        Specified by:
        getWeekOfWeekyear in interface ReadableDateTime
        Returns:
        the week of a week based year
        

        代码没有错。

        【讨论】:

        • 可以使用at least 4 days are in the year 部分。但是,如果我将 2011 替换为 2009 :2009 年 1 月 1 日是星期四。因为美国的星期从星期日开始,所以这一周只有 2009 年的 3 天。因此,根据美国日历,它应该是 2008 年的第 52 周,但我的代码将两个日历都显示为 2009 年的第一周。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 1970-01-01
        • 1970-01-01
        • 2014-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多