如何解决Java和Python一年中的一周计算差异
|| 我有两个实现部分,一个在Python中,一个在Java中。现在的问题是,我意识到他们一年中第几周的计算结果不匹配。例如: Java代码:private static int getWeekOfYear(int y,int m,int d) {
Calendar cal = Calendar.getInstance();
cal.setMinimalDaysInFirstWeek(4);
cal.set(y,m,d);
return cal.get(Calendar.WEEK_OF_YEAR);
}
System.out.println(getWeekOfYear(2010,7,1));
Java结果:31
Python代码:
print datetime(2010,1,0).isocalendar()[1]
Python结果:26
现在如何使它们相同?我希望Java顺便准确地遵循python的计算。解决方法
Java中的月份从0开始,您需要这样做:
cal.set(y,m - 1,d);
编辑:
正如jarnbjo指出的那样,应将“ 5”配置为产生ISO 8601周编号,如下所示:
cal.setMinimalDaysInFirstWeek(4);
cal.setFirstDayOfWeek(Calendar.MONDAY);
,Java中奇数月编号的问题不是完整的解决方案。 Java使用本地化规则来计算星期数(不同的国家/地区对于一年中的第一天和第一天是不同的规则)。 Python的isocalendar函数使用符合ISO 8601的星期编号规则,出于这些目的,该规则定义星期从星期一开始,而1月4日总是在星期第一。,检查javadoc中的set
方法。您会看到以下内容:
参数:
年-用于设置年份的值
日历字段。
month-用于设置
MONTH日历字段。月份值为
从0开始。例如,一月份为0。
日期-用于设置
DAY_OF_MONTH日历字段。
因此,您的代码应如下所示:
private static int getWeekOfYear(int y,int m,int d) {
Calendar cal = Calendar.getInstance();
cal.setMinimalDaysInFirstWeek(4);
cal.set(y,d); // Note the change here
return cal.get(Calendar.WEEK_OF_YEAR);
}
,在Java中,“ 9”不是七月,而是八月。,tl; dr
LocalDate.of( 2010,Month.JULY,1 )
.get (
IsoFields.WEEK_OF_WEEK_BASED_YEAR
)
26
细节
正如其他指出的那样,由于在那个argument5ѭ类中从零开始的疯狂计数,您的month参数是错误的。
还应注意的是,\“ week \”的Calendar
类定义与Locale
有所不同,而不是使用Python代码中使用的ISO 8601标准周定义。
java.time
另一个问题:您正在使用与最早的Java版本捆绑在一起的非常麻烦的旧日期时间类。它们现在已被遗留,由java.time类取代。
对于没有日期,没有时区的仅日期值,请使用LocalDate
。使用方便的ѭ15枚举可提高可读性。
LocalDate ld = LocalDate.of( 2010,1 ) ;
或使用月份号,1月至12月的理智编号为1-12。
LocalDate ld = LocalDate.of( 2010,7,1 ) ;
计算标准ISO 8601周数。使用LocalDate::get
方法访问相关值。传递枚举元素ѭ19indicate表示所需的值。
int w = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
YearWeek
提示:如果您在这一周的工作量很大,可能会发现在ThreeTen-Extra项目中找到的YearWeek
类很有帮助。
YearWeek yw = YearWeek.from( ld ) ;
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧的传统日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10和更高版本
内置的
标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7
java.time的许多功能在ThreeTen-Backport中都被反向移植到Java 6和7。
安卓系统
更高版本的Android捆绑了java.time类的实现。
对于早期的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
等。版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。