为什么 SQL Server 周数与 Java 周数不同?
我正在使用 Java 6 和 SQL Server 2008 开发一个报告系统。对于某些查询,我想按周数查看数据。我正在使用 Java 来填充数据中的空白以形成连续的时间线,我发现
java.util.Calendar cal = new java.util.GregorianCalendar();
cal.set(2012, 0, 1);
cal.get(Calendar.WEEK_OF_YEAR);
并
org.joda.time.DateTime date = new org.joda.time.DateTime(2012, 01, 01, 0, 0);
date.getWeekOfWeekyear();
返回不同的周数
DATEPART(WEEK, '2012-01-01')
是否有解决此差异的方法,或者我必须选择使用 SQL Server < em>或 Java 周数?
TIA
I'm working on a reporting system using Java 6 and SQL Server 2008. For some queries I want to look at the data by week number. I'm using Java to fill in gaps in the the data to make a continuous time line and I have found that
java.util.Calendar cal = new java.util.GregorianCalendar();
cal.set(2012, 0, 1);
cal.get(Calendar.WEEK_OF_YEAR);
and
org.joda.time.DateTime date = new org.joda.time.DateTime(2012, 01, 01, 0, 0);
date.getWeekOfWeekyear();
return a different week number to
DATEPART(WEEK, '2012-01-01')
Is there an approach to resolving this difference or will I have to choose to use SQL Server or Java week numbers?
TIA
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Java 在计算周数时更为复杂,而 SQL-Server DATEPART(WEEK... 则更为简单。我发现以下记录 此处
"设置或获取 WEEK_OF_MONTH 或 WEEK_OF_YEAR 字段时,日历必须确定第一周一个月或一年的第一周被定义为从 getFirstDayOfWeek() 开始并至少包含 getMinimalDaysInFirstWeek() 的最早的 7 天时间段“
我认为这默认为 ISO 标准,即一年中的第一周,其中星期四(周一至周日,一年中至少有 4 天)。在 SQL Server 中,
DATEPART(WEEK, ..)
函数要简单得多,它只是计算1 月 1 日与输入日期之间的周边界数(由DATEFIRST
定义),因此 1 月 1 日将始终为第 1 周。您可能希望考虑使用:这获取 ISO 标准定义的周数,即第一周一年中的星期四(周一至周日,一年中至少有 4 天)。
正如所述,由于 SQL Server 的计算更加简单,因此无法对其进行配置,这意味着您需要在 Java 中配置周数。只需确保您在 Java 中使用
getFirstDayOfWeek()
和getMinimalDaysInFirstWeek()
的正确值设置日历:然后您就可以确保周数一致。
Java is more sophisticated when it comes to calculating week numbers, whereas SQL-Server DATEPART(WEEK... is more simplistic. I found the following documented here
"When setting or getting the WEEK_OF_MONTH or WEEK_OF_YEAR fields, Calendar must determine the first week of the month or year as a reference point. The first week of a month or year is defined as the earliest seven day period beginning on getFirstDayOfWeek() and containing at least getMinimalDaysInFirstWeek() "
I think this defaults to the ISO standards which is the first week of the year with a thursday in (Monday-Sunday weeks where at least 4 days are the year). Consider using:In SQL Server the
DATEPART(WEEK, ..)
function is much more simplistic, it simply calculates the number of week boundaries (as defined byDATEFIRST
) between the first of january, and the input date, so the 1st January will always be week 1. You may wish to consider using:This gets the week number as defined by the ISO standards, which is the first week of the year with a thursday in (Monday-Sunday weeks where at least 4 days are the year).
Since, as stated SQL Server is more simplistic in it's calculations, this can't be configured, which means that you will need to configure your week numbers within Java. Simply ensure you set up your calendar in Java with the correct values for
getFirstDayOfWeek()
andgetMinimalDaysInFirstWeek()
:Then you can esnsure consistent week numbers.
根据各自的文档, java.util .calendar、joda 和 DATEPART 均返回 1 到 53 之间的整数表示星期。该值基于一周第一天的定义和默认日历(例如公历、中国)。我会检查您的默认值或看看每个人认为一周的第一天是什么。
According to their respective docs, java.util.calendar, joda, and DATEPART all return an integer between 1 and 53 indicating the week. This value is based on what is defined as the first day of the week and the default calendar (e.g. Gregorian, Chinese). I would check your defaults or see what each thinks the first day of the week is.
我认为这可能与 2011 年有关,并且根据 SQLServer 的说法,它有 53 周。查看 一月/新年 SQL 问题!,这解决方案可能有助于更好地处理 SQLServer 内容:
DATEPART(WEEK, DATEADD(WEEK, -1, '2012-01-01'))
I think it might have something to do with 2011 and the idea that it has 53 weeks according to SQLServer. Looking at Jan / New Year SQL problems!, this solution might help to handle the SQLServer stuff better:
DATEPART(WEEK, DATEADD(WEEK, -1, '2012-01-01'))
tl;dr
一周的多种定义
一周有多种定义。
对于某些人来说,一周的第一天是星期日,其他人是星期一,还有一些人是其他日子。
对于某些人来说,一年的第一周包含 1 月 1 日,而另一些人则将第一周视为包含上述一周开始日的一周,而另一些人则将第一周视为包含特定的一周中的某一天。
因此,在不研究文档的情况下,您不应该永远不要假设“周”或“周数”的含义。
避免遗留日期时间类
一般来说,您应该避免与最早版本的 Java 捆绑在一起的旧遗留日期时间类,因为它们设计不佳、令人困惑且麻烦。
具体来说,
java.util.Calendar
类的周定义因语言环境而异。因此,如果您想要可靠的恒定结果,请不要使用此选项。ISO 8601
ISO 8601 标准定义了日期时间值的格式和相关问题。它具体定义了一周和一年中的一周的含义:
Joda-Time
Joda-Time 库使用 ISO 8601 周和周的标准定义-年。
但是,请注意 Joda-Time 项目现已位于 维护模式,团队建议迁移到 java.time。
java.time
java.time 类使用 ISO 8601 一周的定义:第 1 周第一个星期四,一周为星期一至星期日。
IsoFields
< /a> class 定义基于周的年份。我们可以要求:WEEK_OF_WEEK_BASED_YEAR
)WEEK_BASED_YEAR
)。首先我们获取当前的日期时间。
询问该日期时间对象,询问标准的基于周的年份。
转储到控制台。
有关更多信息,请参阅类似的问题:如何根据 ISO8601 周数计算日期Java。
WeekFields
在 java.time 中,您还可以调用
WeekFields
类,如WeekFields.ISO.weekBasedYear ()
。应该与 Java 8 或更高版本中的IsoFields
具有相同的效果(修复了一些错误 在 Java 8 的早期版本中)。关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如
java.util.Date
,.Calendar
, &java.text.SimpleDateFormat
。Joda-Time 项目,现已在 维护模式,建议迁移到 java.time。
要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310。
从哪里获取 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如
间隔
,YearWeek
,YearQuarter
和 更多。tl;dr
Many definitions of a week
There are many definitions of a week.
For some people the first day of a week is a Sunday, others Mondays, and still others some other day.
For some people the first week of the year contains January 1st, while some other folks count the first week as the one containing that start-of-week day mentioned above, while others count week one as containing a specific day-of-week.
So you should never assume the meaning of a "week" or "week number" without studying the documentation.
Avoid legacy date-time classes
In general, you should avoid the old legacy date-time classes bundled with the earliest versions of Java as they are poorly-designed, confusing, and troublesome.
Here specifically, the
java.util.Calendar
class has a definition of week that varies by locale. So do not use this if you want reliable constant results.ISO 8601
The ISO 8601 standard defines formats and related issues for date-time values. It specifically defines the meaning of a week and week-of-year:
Joda-Time
The Joda-Time library uses the ISO 8601 standard definition of week and week-of-year.
However, be aware that the Joda-Time project is now in maintenance mode, with the team advising migration to java.time.
java.time
The java.time classes use the ISO 8601 definition of a week: Week # 1 has first Thursday, with week running Monday-Sunday.
The
IsoFields
class defines a week-based year. We can ask for the:WEEK_OF_WEEK_BASED_YEAR
)WEEK_BASED_YEAR
).First we get the current date-time.
Interrogate that date-time object, asking about the standard week-based year.
Dump to console.
For more info, see this similar Question: How to calculate Date from ISO8601 week number in Java.
WeekFields
In java.time you can also call upon the
WeekFields
class, such asWeekFields.ISO.weekBasedYear()
. Should have the same effect asIsoFields
in later versions of Java 8 or later (some bugs were fixed in earlier versions of Java 8).About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as
java.util.Date
,.Calendar
, &java.text.SimpleDateFormat
.The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as
Interval
,YearWeek
,YearQuarter
, and more.