【问题标题】:Get LocalDateTime based on year and week of year根据一年中的年份和星期获取 LocalDateTime
【发布时间】:2015-09-28 11:47:08
【问题描述】:

我有两个整数:yearweek。我想从这两个值构造一个LocalDateTime,其中日期表示特定年份中特定周的第一天。

我已经试过了:

LocalDateTime ldt = LocalDateTime.of(year, 1, 1, 0, 0).plusWeeks(week-1);

这不会给出正确的结果,因为一年的第一天并不总是该年第一周的开始。我似乎也不知道如何获得第一周的第一天。

有没有什么简单的方法可以用 Java 8 中的日期和时间 API 做到这一点?

注意:我知道我也可以通过给出here 的答案创建一个解决方法,但这似乎有些牵强。也许不是,如果是,请告诉我!

【问题讨论】:

  • 一年内的周数是特定于语言环境的,因此这两个数据点不会为您提供确切的日期。 AFAIK LocalDateTime 不处理这个事实,但 GregorianCalendar 处理。
  • @biziclop 我认为这正是他想要的。特定于区域设置的第“1”周 - 所以对于某些人来说是前 4 天的一周,对于其他人来说则是其他的。
  • @dognose 那么GregorianCalendar 确实是要走的路。
  • 一周和一年中的一周的定义各不相同。在讨论该主题时始终定义这些术语。也许你的意思是standard ISO 8601 week

标签: java datetime java-8 java-time


【解决方案1】:

以下代码将获取 LocalDateTime 并将其设置为给定年份的给定一周中的第一天:

int week = 1;
int year = 2016;
WeekFields weekFields = WeekFields.of(Locale.getDefault());
LocalDateTime ldt = LocalDateTime.now()
                            .withYear(year)
                            .with(weekFields.weekOfYear(), week)
                            .with(weekFields.dayOfWeek(), 1);
System.out.println(ldt);

请注意,一年中的一周的概念是特定于语言环境的。在这里,我使用了默认语言环境,但您可能需要使用用户提供的语言环境。

如果你想摆脱时间部分,你可以添加一个电话到truncatedTo(ChronoUnit.DAYS)

【讨论】:

    【解决方案2】:
    LocalDate ld = LocalDate.parse("2012-W48-1", DateTimeFormatter.ISO_WEEK_DATE);
    

    【讨论】:

    • 感谢您的回答!我认为这与 assylias 的答案非常相似,也有点不完整。也许你可以编辑它来解释它为什么不同。
    • 类似但避免创建额外的 LocalDate 实例
    【解决方案3】:

    三十加分

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如YearWeek

    如果“周”是指标准 ISO 8601 definition of a week-of-year,其中第 1 周包含一年中的第一个星期四,则让 YearWeek 类为您完成工作。

    int weekBasedYear = 2015;  // Not the calendar year!
    int weekOfYear = 1;
    YearWeek yearWeek = YearWeek.of ( weekBasedYear , weekOfYear );
    

    您可以获得LocalDate 对象中表示的仅日期值。使用DayOfWeek 枚举指定您想要的星期几,其中星期一是一周的第一天,星期日是最后一天。请记住,ISO 周总是从星期一开始,总是在星期日结束。

    LocalDate mondayOfYearWeek = yearWeek.atDay ( DayOfWeek.MONDAY );
    LocalDate sundayOfYearWeek = yearWeek.atDay ( DayOfWeek.SUNDAY );
    

    转储到控制台。请注意该周是如何从上一个日历年(2014 年)开始到 2015 年结束的,因为 2015 年 1 月 1 日是星期四,所以它标志着 ISO 第 1 周。下一个 2015 年 1 月 4 日星期日结束 ISO 第 1 周。

    System.out.println ( "yearWeek: " + yearWeek + " starts on mondayOfYearWeek: " + mondayOfYearWeek + " and ends on sundayOfYearWeek: " + sundayOfYearWeek );
    

    yearWeek:2015-W01 开始于 mondayOfYearWeek:2014-12-29,结束于 sundayOfYearWeek:2015-01-04

    【讨论】:

    • 这很好,但问题是使用另一个依赖项。我希望在 jdk 本身中添加这种直观的 API。
    • @MohammadAdnan ThreeTen-Extra 由同一个人领导,Stephen Colebourne,他领导 java.time 类,它们在 JSR 中的规范310,以及他们的前身Joda-TimeThreeTen-Extra 项目是将来可能加入 java.time 类的类的试验场。我建议你现在就享受它们的用处。
    【解决方案4】:

    您可以尝试解析您感兴趣的日期的字符串表示形式:

    private static final DateTimeFormatter YEAR_WEEK = DateTimeFormatter.ofPattern("YYYY-w-e", Locale.getDefault());
    
    public static LocalDate fromYearWeek(int year, int week) {
      return LocalDate.parse(year + "-" + week + "-1", YEAR_WEEK);
    }
    

    如果您需要 LocalDateTime,则可以使用 localDate.atTime(...)localDate.atStartOfDay() 例如。

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 1970-01-01
      • 2021-12-16
      相关资源
      最近更新 更多