首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SimpleDateFormat周年

SimpleDateFormat周年
EN

Stack Overflow用户
提问于 2020-01-06 03:33:45
回答 1查看 555关注 0票数 2

java8 GregorianCalendar DOC

一周的一年与WEEK_OF_YEAR周期同步。第一周和最后一周(包括在内)之间的所有周都具有相同的周年值。因此,一周的第一天和最后一天可能有不同的日历年值。

例如,1998年1月1日是星期四。如果getFirstDayOfWeek()是星期一,getMinimalDaysInFirstWeek()是4 (ISO8601标准兼容设置),那么1998年的第一周从1997年12月29日开始,到1998年1月4日结束。1997历年最后三天的周年是1998年。但是,如果getFirstDayOfWeek()是星期日,那么1998年的第一周从1998年1月4日开始,到1998年1月10日结束;1998年的前三天是1997年第53周的一部分,他们的周是1997年。

正如DOC所说,如果我把FirstDayOfWeek设为SUNDAY,MinimalDaysInFirstWeek设置为4,那么1998-01-01的周年应该是1997年,但是junit的结果是1998年。

代码语言:javascript
复制
Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, 1998);
    calendar.set(Calendar.MONTH, 0);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    calendar.setMinimalDaysInFirstWeek(4);
    calendar.setFirstDayOfWeek(Calendar.SUNDAY);

    System.out.println(calendar.getTimeZone());
    System.out.println(calendar.getMinimalDaysInFirstWeek());
    System.out.println(calendar.getFirstDayOfWeek());

    SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd");
    System.out.println(sdf.format(calendar.getTime()));

结果是:sun.util.calendar.ZoneInfoid=“亚洲/上海”,offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null

4.

1

1998-01-01

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-06 18:11:14

TL;DR:格式化程序使用自己的一周编号

日期格式化程序使用的是它自己的周编号方案,而不是日期(在您的例子中是Calendar对象)。我正在使用java.time (现代java.time和time )进行演示。具体来说,我使用的是LocalDateLocalDate总是国际标准化组织日历系统中的一个日期。

代码语言:javascript
复制
    LocalDate date = LocalDate.of(1998, Month.JANUARY, 1);
    DateTimeFormatter baseFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd");

    DateTimeFormatter chinaFormatter = baseFormatter.withLocale(Locale.CHINA);
    System.out.println("China:   " + date.format(chinaFormatter));

    DateTimeFormatter franceFormatter = baseFormatter.withLocale(Locale.FRANCE);
    System.out.println("France:  " + date.format(franceFormatter));

    DateTimeFormatter irelandFormatter = baseFormatter.withLocale(Locale.forLanguageTag("en-IE"));
    System.out.println("Ireland: " + date.format(irelandFormatter));

这个片段的输出是:

中国: 1998-01-01法国: 1998-01-01爱尔兰: 1997-01-01

  • 如果您的默认区域是中国,则您的格式化程序使用中国周。它们从周日开始,第一周是包含1月1日的一周(另一个例子是美国)。因此,1998年1月1日必须属于1998年周年度。
  • 法国使用ISO编号:周从星期一开始,在这种情况下,1998年的第一周从1997年12月29日开始。所以我们又回到了1998年。
  • 爱尔兰是少数几个使用混合计划的国家之一:第一周的最小天数是4天(就像ISO那样),周日是一周的第一天(比如中国和美国)。因此,使用爱尔兰的格式化程序作为地区国家,您将得到您想要的结果,1997年。

从日期获得一个星期的1997年度的另一种方法是将您自己的WeekFields对象放在一起。那你就不用担心现场了。

代码语言:javascript
复制
    WeekFields myWeekFields = WeekFields.of(DayOfWeek.SUNDAY, 4);
    int weekYear = date.get(myWeekFields.weekBasedYear());
    System.out.println("Week year: " + weekYear);

周年:1997年

java.time??

您正在使用的日期和时间类( CalendarSimpleDateFormat )设计得很糟糕,而且已经过时了。

从您的文档链接中可以看出,您使用的是Java 8,如果是这样的话,您完全没有理由使用旧类。像我上面所做的那样使用java.time。Java 6和7的后端也存在。

问题中的代码为什么不起作用?

您正在使用Calendarcalendar.getTime()中抽出时间。这将返回一个Date (另一个设计糟糕且长期过时的类)。Date是一个时间点,仅此而已。它没有任何关于周数或周年的概念。您将这个Date传递给您的SimpleDateFormat,它无法检测到Date最初来自一个Calendar对象,该对象在一周的第一周和第一天设置了特定的天数。相反,SimpleDateFormat使用了自己对周的定义。它总是那么做。由于您没有显式地为SimpleDateFormat设置区域设置或日历,所以它使用了JVM的默认区域设置。这产生了1998年的一个星期,在绝大多数地方也是如此。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59606376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档