- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将我的应用程序从 Joda-Time 迁移到 Java 8 java.time
.
我遇到的一件事是使用 DateTimeFormatter
中的模式打印基于周的年份.
注意:我看过这个问题: Java Time's week-of-week-based-year pattern parsing with DateTimeFormatter
根据文档
y year-of-era year 2004; 04
Y week-based-year year 1996; 96
然而,当我尝试这两个时,似乎 Y
总是返回与 y
相同的值.
我的测试代码:
DateTimeFormatter yearF = DateTimeFormatter.ofPattern("yyyy").withZone(ZoneOffset.UTC);
DateTimeFormatter weekYearF = DateTimeFormatter.ofPattern("YYYY").withZone(ZoneOffset.UTC);
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR_OF_ERA) .appendLiteral(" ") .append(yearF)
.appendLiteral(" -- ")
.appendValue(IsoFields.WEEK_BASED_YEAR) .appendLiteral(" ") .append(weekYearF)
.toFormatter()
.withZone(ZoneOffset.UTC);
System.out.println(dateTimeFormatter.toString());
ZonedDateTime dateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(946778645000L), ZoneOffset.UTC);
for (int i = 2000 ; i < 2020; i ++ ) {
System.out.println(dateTime.withYear(i).format(dateTimeFormatter));
}
输出:
Value(YearOfEra)' '(Value(YearOfEra,4,19,EXCEEDS_PAD))' -- 'Value(WeekBasedYear)' '(Localized(WeekBasedYear,4,19,EXCEEDS_PAD))
2000 2000 -- 1999 2000
2001 2001 -- 2001 2001
2002 2002 -- 2002 2002
2003 2003 -- 2003 2003
2004 2004 -- 2004 2004
2005 2005 -- 2004 2005
2006 2006 -- 2006 2006
2007 2007 -- 2007 2007
2008 2008 -- 2008 2008
2009 2009 -- 2009 2009
2010 2010 -- 2009 2010
2011 2011 -- 2010 2011
2012 2012 -- 2012 2012
2013 2013 -- 2013 2013
2014 2014 -- 2014 2014
2015 2015 -- 2015 2015
2016 2016 -- 2015 2016
2017 2017 -- 2017 2017
2018 2018 -- 2018 2018
2019 2019 -- 2019 2019
查看重要的年份(如 2000 年、2005 年、2009 年和 2016 年).appendValue(IsoFields.WEEK_BASED_YEAR)
的输出和 .ofPattern("YYYY")
是不同的。
在Java Time's week-of-week-based-year pattern parsing with DateTimeFormatter据说这与本地化有关(可以清楚地看出 toString()
与 DateTimeFormatter
的差异)。
现在有一些我不理解/需要的东西:
所以“基于周的年份”随区域设置而变化,很好。然而,我不明白的是,在某些语言环境中,周基准年显然始终与“正常”年相同。这是为什么?
为什么没有解析YYYY
被映射到 ISO-8601 定义而不是(非常困惑!)本地化形式。
我在哪里可以找到这方面的适当文档?来自 Oracle 的明显“官方”文档至少可以说是模糊的。回答:我找到了更广泛的文档 DateTimeFormatterBuilder .
最佳答案
week-based-year 字段,根据 javadoc , 取决于两件事:一周的第一天是哪一天,以及第一周的最少天数。
ISO 标准将星期一定义为一周的第一天,并且第一周至少有 4 天:
System.out.println(WeekFields.ISO.getFirstDayOfWeek()); // Monday
System.out.println(WeekFields.ISO.getMinimalDaysInFirstWeek()); // 4
(WeekFields.ISO.weekBasedYear()
等同于 IsoFields.WEEK_BASED_YEAR
,带 minor differences regarding another calendar systems )
例如,考虑 2009 年 1 月 2 日nd,这是一个星期五。检查 javadoc for the week-based-year field :
Week one(1) is the week starting on the getFirstDayOfWeek() where there are at least getMinimalDaysInFirstWeek() days in the year. Thus, week one may start before the start of the year.
考虑到 ISO 定义(周从星期一开始,第一周的最少天数为 4),第 1 周从 2008 年 12 月 29 日th 开始,到 1 月 4th 结束2009(这是从星期一开始的第一周,2009 年至少有 4 天),因此 2009 年 1 月 2 日nd 的week-based-year 等于2009(采用 ISO 定义):
// January 2st 2009
LocalDate dt = LocalDate.of(2009, 1, 2);
System.out.println(dt.get(WeekFields.ISO.weekBasedYear())); // 2009
System.out.println(dt.get(WeekFields.ISO.weekOfWeekBasedYear())); // 1
// WeekFields.ISO and IsoFields are equivalent
System.out.println(dt.get(IsoFields.WEEK_BASED_YEAR)); // 2009
System.out.println(dt.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR)); // 1
但是如果我考虑一个 WeekFields
实例用于 en_MT
locale (English (Malta)) ,一周的第一天是星期天,第一周的最少天数是4:
WeekFields wf = WeekFields.of(new Locale("en", "MT"));
System.out.println(wf.getFirstDayOfWeek()); // Sunday
System.out.println(wf.getMinimalDaysInFirstWeek()); // 4
System.out.println(dt.get(wf.weekBasedYear())); // 2008
System.out.println(dt.get(wf.weekOfWeekBasedYear())); // 53
2009 年从星期日开始且至少有 4 天的第一个星期是从 1 月 4th 到 10th 的那一周。因此,根据 en_MT
语言环境的周定义,2009 年 1 月 2 日nd 属于 53th 周 基于周的年份 2008。
现在,如果我使用 ar_SA
locale (Arabic (Saudi-Arabia)) ,一周从周六开始,第一周最少天数为1:
WeekFields wf = WeekFields.of(new Locale("ar", "SA"));
System.out.println(wf.getFirstDayOfWeek()); // Saturday
System.out.println(wf.getMinimalDaysInFirstWeek()); // 1
System.out.println(dt.get(wf.weekBasedYear())); // 2009
System.out.println(dt.get(wf.weekOfWeekBasedYear())); // 1
对于此语言环境,第 1 周从 2008 年 12 月 27 日 开始,到 2009 年 1 月 2 日 结束(这是从星期六开始的第一周,并且至少2009 年为 1 天)。因此,week-based-year 2009 年 1 月 2 日 nd 在 ar_SA
语言环境中也是 2009(与我使用 IsoFields
,即使周定义与 ISO 完全不同)。
虽然 IsoFields.WEEK_BASED_YEAR
使用 ISO 的定义,模式 YYYY
将使用 WeekFields
实例对应于格式化程序中设置的语言环境(或JVM 默认语言环境(如果未设置)。
根据每个语言环境的定义(一周的第一天和第一周的最少天数),来自本地化模式的基于周的年份(YYYY
) 可能与 ISO 字段具有相同(或不同)的值。
虽然一周可以在另一年开始或结束听起来很奇怪,javadoc说这是完全有效的:
The first and last weeks of a year may contain days from the previous calendar year or next calendar year respectively.
java.time
的模式字母were based on CLDR (Unicode Common Locale Data Repository)。 This link about Week based patterns说:
The year indicated by Y typically begins on the locale’s first day of the week and ends on the last day of the week
无论如何,CLDR 都是关于本地化的,因此 Y
也已本地化 - 如 Stephen Colebourne's comment 所述下面:
The whole purpose of CLDR is localization, so yes, the "Y" pattern letter is localized. While I understand the desire for a pattern letter that always operates using the ISO rules, it doesn't exist and getting CLDR to add it would be hard to impossible. (Java is following CLDR closely)
我的结论是,如果您想要 ISO 周字段,请不要使用本地化模式。或者,作为一种 - 不理想,非常丑陋 - 解决方法,使用与 ISO 的周定义相匹配的语言环境(在我的 JVM 中,Locale.FRENCH
可以解决问题,因为 WeekFields.ISO.equals( WeekFields.of(Locale.FRENCH))
返回 true
)。唯一的问题是区域设置也会影响其他字段(如果您有月份或星期几名称,例如 MMM
或 EEE
,以及任何其他区域设置敏感数据).
关于java - DateTimeFormatter 基于周年的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46389117/
我从NVIDIA手册Eg中复制了以下代码:__threadfence()。他们为什么有 在以下代码中使用了__threadfence()。我认为使用__syncthreads()而不是__thread
我在使用 SVN 更改列表和 svn diff 时遇到了一些麻烦.特别是我想获取特定修订范围的特定文件列表的更改历史记录。 SVN 变更列表似乎是完美的解决方案,所以我的方法是: svn change
我有两个 IP 地址列表。我需要将它们合并到三个文件中,交集,仅来自 list1 的文件和仅来自 list2 的文件。 我可以用 awk/diff 或任何其他简单的 unix 命令来做到这一点吗?如何
假设自上次更新(恢复)到我的 a.b 文件以来我做了一些更改。 此 a.b 文件也在存储库中更改。 现在我想将我所做的更改与 repos 更改进行比较。 如果我 svn revert 文件,我可以看到
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我使用的是 openssl 1.0.1c , linux x86_64 我正在创建包含“hello”的文件(没有换行符) openssl dgst -sha256 hello_file i get :
假设我们有几个库。 有什么区别核心和 普通 图书馆?他们应该如何被认可,我们是否组织了两者的职责? +Common -Class1 +Core -Class2 +Lib1 has : Comm
如何在 SQLite 中计算以毫秒为单位的最小时间间隔? 好的,提供一些背景信息, 这是我的 table 的样子: link_budget table 所以有这个时间列,我想发出一个请求,以毫秒为单位
我想知道,乐观并发控制 (OCC) 和多版本并发控制 (MVCC) 之间的区别是什么? 到目前为止,我知道两者都是基于更新的版本检查。 在 OCC 中,我读到了没有获取读取访问锁的事务,仅适用于以后的
说到 SignalR,我有点菜鸟。刚刚开始四处探索和谷歌搜索它,我想知道是否有人可以向我解释完成的事情之间的一些差异。 在我见过的一些示例中,人们需要创建一个 Startup 类并定义 app.Map
我在 Ogre 工作,但这是一个一般的四元数问题。 我有一个对象,我最初对其应用旋转四元数 Q1。后来,我想让它看起来好像我最初通过不同的四元数 Q2 旋转了对象。 我如何计算四元数,该四元数将采用已
我了解 javascript 模块模式,但我使用两种类型的模块模式,并且想从架构 Angular 了解它们之间的区别。 // PATTERN ONE var module = (function()
我有两个具有完全相同键的 JSON。 val json1 = """{ 'name': 'Henry', 'age' : 26, 'activities' : {
我发现使用 VBA 在 Excel 中复制单个文件有两种不同的方法。一是文件复制: FileCopy (originalPath), (pathToCopyTo) 另一个是名称: Name (orig
我想知道查找两个 float 组之间差异的绝对值的最有效方法是什么? 是否是以下内容: private float absDifference(float[] vector1, float[] vec
我有一个关于 wicket getApplication 的问题。 getApplication() 和 getSession().getApplication 有什么区别? 部署 wicket 应用
我刚刚开始使用activemq,我有一个关于追溯消费者的问题,为了启用这个功能,你需要有一个持久的订阅。但是在主题上启用和不启用追溯的持久订阅有什么区别? activemq 文档说。 http://a
我有两个具有完全相同键的 JSON。 val json1 = """{ 'name': 'Henry', 'age' : 26, 'activities' : {
得到另一个 Erlang 二进制表示查询('因为这就是我最近正在阅读的内容,并且需要二进制协议(protocol)实现)。 如果我正确理解了类型说明符,那么对于“浮点”类型值,8 字节表示似乎很好(这
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
我是一名优秀的程序员,十分优秀!