我正在使用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 或 Java周数?
TIA
答案 0 :(得分:6)
Java在计算周数方面更为复杂,而SQL-Server DATEPART(WEEK ......则更为简单。我发现以下内容记录了here
"设置或获取WEEK_OF_MONTH或WEEK_OF_YEAR字段时,日历必须将月份或年份的第一周确定为参考点。一个月或一年的第一周被定义为从getFirstDayOfWeek()开始并且至少包含getMinimalDaysInFirstWeek()"
的最早七天时段。 我认为这默认为ISO标准,这是一周中的第一周(周一至周日周,其中至少4天是一年)。考虑使用:
在SQL Server中,DATEPART(WEEK, ..)
函数更简单,它只是计算1月1日和输入日期之间的星期边界数(由DATEFIRST
定义),因此第1个1月将始终为第1周。您可能希望考虑使用:
SELECT DATEPART(ISO_WEEK, '01/01/2012')
这将获得ISO标准定义的周数,这是一周中的第一周(周一至周日,每年至少4天)。
由于SQL Server在其计算中更加简单,因此无法配置,这意味着您需要在Java中配置周数。只需确保使用正确的getFirstDayOfWeek()
和getMinimalDaysInFirstWeek()
值设置您的日历:
public static Calendar getISOCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.setMinimalDaysInFirstWeek(4);
calendar.setFirstDayOfWeek(Calendar.MONDAY);
return calendar;
}
然后你可以确保一致的周数。
public static void main(String args[]) {
Calendar calendar = getISOCalendar();
calendar.set(2012,0,1);
System.out.println(calendar.get(Calendar.WEEK_OF_YEAR));
}
------
52
答案 1 :(得分:1)
根据各自的文档,java.util.calendar,joda和DATEPART都返回1到53之间的整数,表示一周。此值基于定义为一周的第一天和默认日历(例如格里高利,中文)。我会检查你的默认值,或者看看每个人在一周的第一天的想法是什么。
答案 2 :(得分:0)
我认为它可能与2011年有关,并认为根据SQLServer它有53周的想法。看看Jan / New Year SQL problems!,这个解决方案可能有助于更好地处理SQLServer:
DATEPART(WEEK, DATEADD(WEEK, -1, '2012-01-01'))
答案 3 :(得分:0)
int iso8601WeekNumber =
ZonedDateTime.now( ZoneId.of ( "America/Montreal" ) )
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
一周有很多定义。
对于某些人来说,一周的第一天是星期日,其他星期一,还有一天是其他人。
对于某些人来说,一年中的第一周包含1月1日,而其他一些人将第一周计算为包含上述开始日期的那一周,而其他人将第一周视为包含特定日期的一周-周。
所以,如果不学习文档,你应该永远不要假设“周”或“周数”的含义。
通常,您应该避免使用与最早版本的Java捆绑在一起的旧旧日期时间类,因为它们设计不当,令人困惑且麻烦。
具体来说,java.util.Calendar
类按区域设置有周定义。因此,如果您需要可靠的恒定结果,请不要使用它。
ISO 8601标准定义了日期时间值的格式和相关问题。它specifically defines一周和一周的意思:
Joda-Time库使用星期和星期的ISO 8601标准定义。
但是,请注意Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time。
java.time类使用一周的ISO 8601定义:第1周有第一个星期四,第一周是星期一到星期日。
IsoFields
类定义了基于周的年份。我们可以要求:
WEEK_OF_WEEK_BASED_YEAR
)WEEK_BASED_YEAR
)。首先我们得到当前的日期时间。
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
询问该日期时间对象,询问标准的基于周的年份。
int week = now.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekYear = now.get ( IsoFields.WEEK_BASED_YEAR );
转储到控制台。
System.out.println ( "now: " + now + " is week: " + week + " of weekYear: " + weekYear );
现在:2016-01-17T20:55:27.263-05:00 [美国/蒙特利尔]是星期:2周,年:2016
有关详细信息,请参阅此类似问题:How to calculate Date from ISO8601 week number in Java。
WeekFields
在java.time中,您还可以调用WeekFields
类,例如WeekFields.ISO.weekBasedYear()
。在Java 8或更高版本的更高版本(早期版本的Java 8中的某些bugs were fixed)中应该与IsoFields
具有相同的效果。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,.Calendar
和& java.text.SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 4 :(得分:-1)
System.out.println("get date range from week number and year in java");
System.out.println(); // print a blank line
// get the input from the user
Scanner sc = new Scanner(System.in);
System.out.print("Enter the week : ");
int weekNumber = sc.nextInt();
System.out.print("Enter the Year: ");
int year = sc.nextInt() ;
Calendar cal = Calendar.getInstance();
//cal.setTime(new Date());
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, weekNumber);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println(formatter.format(cal.getTime())); // start date
cal.add(Calendar.DAY_OF_WEEK, 6);
System.out.println(formatter.format(cal.getTime())); // end date