安卓日历中的周数是错误的



安卓日历中的周数错误

在某些设备中,作为第 53 周,但在其他一些设备中,作为年底的第 1 周

日历

日历 = 日历.getInstance((; int week = calender.get(Calendar.WEEK_OF_YEAR(;

第一周

日历使用两个定义特定于区域设置的七天一周 参数:一周的第一天和第一天的最小天数 周(从 1 到 7(。这些数字取自区域设置资源 构造日历时的数据。它们也可以被指定 显式通过设置其值的方法。

设置或获取WEEK_OF_MONTH或WEEK_OF_YEAR字段时,日历必须将月份或年份的第一周确定为 参考点。一个月或一年的第一周定义为 最早的七天周期从getFirstDayOfWeek((开始,并且 至少包含该月的 getMinimalDaysInFirstWeek(( 天或 年。编号的周 ..., -1, 0 在第一周之前;周数 2, 3,...跟着它走。请注意,规范化编号返回的 get(( 可能不同。例如,特定的日历子类可能 将一年第 1 周之前的一周指定为前一周的第 n 周 年。

来自 Java 文档 (https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html(

tl;dr

LocalDate.of( 2018 , Month.DECEMBER , 31 )
         .get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) 

1

现场

不确定您的问题的直接答案,但可能有不同的Locale价值观。在Calendar中,一周的定义因区域设置而异。

但这毫无意义。您应该使用替换Calendar类的java.time类。

java.time

Calendar是麻烦的旧日期时间类的一部分,这些类现在是遗留的,被java.time类所取代。对于早期的Android,请参阅下面的最后一个项目符号。

您必须定义周数的含义。有不同的方法可以定义周数和周数。

缺省情况下,java.time 类使用标准的 ISO 8601 定义:第 # 1 周具有日历年的第一个星期四,并从星期一开始(按照您的要求(。所以年份有 52 周或 53 周。日历年的第一天和最后几天可能会落在上一个/下一个基于周的年份。

LocalDate类表示没有时间且没有时区的仅日期值。

LocalDate ld = LocalDate.of( 2012 , Month.AUGUST , 7 ) ;

询问标准周数。您可以请求以下TemporalField对象中的任何一个:IsoFields.WEEK_BASED_YEAR & IsoFields.WEEK_OF_WEEK_BASED_YEAR

int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;

使用标准 ISO 8601 格式的 YYYY-Www-D 转储到控制台。

String isoOutput = yearOfWeekBasedYear + "-W" + String.format("%02d", weekOfWeekBasedYear) + "-" + dayOfWeekNumber  ;
System.out.println( ld + " is ISO 8601 week: " + isoOutput ) ;

查看此代码在 IdeOne.com 实时运行。

2012-08-07 是 ISO 8601 周: 2012-W32-2

顺便说一下,如果Android能够运行ThreeTen-Extra库,你会发现它的YearWeek类很有用。


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧传统日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。

从哪里获得java.time类?

    Java SE
  • 8Java SE 9 及更高版本
    • 内置。
    • 具有捆绑实现的标准 Java API 的一部分。
    • Java 9添加了一些小功能和修复。
  • Java SE
  • 6Java SE 7
    • 许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7。
  • 人造人
    • java.time 类的 Android 捆绑包实现的更高版本。
    • 对于早期的Android,ThreeTenABP项目适应了ThreeTen-Backport(如上所述(。请参阅如何使用ThreeTenABP...

在这里你可以查看预言机的参考

https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html

我放置了一个快速解决方案来查找当天的周数。您可以按照自己的方式进行更改和优化。还可以根据需要设置您的GMT值。

public static int getWeeksOfMonth() {
    DATESTATUS = false;
    VALUESTATUS = false;
    int weekCount;
    WEEK_OF_MONTH= -1;
    // get the supported ids for GMT+04:00 (Pacific Standard Time)
    String[] ids = getAvailableIDs(4 * 60 * 60 * 1000);
    // if no ids were returned, something is wrong. get out.
    if (ids.length == 0)
        return WEEK_OF_MONTH;
    // create a Pacific Standard Time time zone
    SimpleTimeZone pdt = new SimpleTimeZone(4 * 60 * 60 * 1000, ids[0]);
    // create a GregorianCalendar with the Pacific Daylight time zone
    // and the current date and time
    Calendar calendar = new GregorianCalendar(pdt);
    Date trialTime = new Date();
    calendar.setTime(trialTime);
    weekCount = calendar.get(Calendar.WEEK_OF_YEAR);
    return recursiveWeekCountCheck(calendar, weekCount);
}
private static int recursiveWeekCountCheck(Calendar calendar, int weekCount) {
    if (calendar.get(Calendar.MONTH) == Calendar.DECEMBER && weekCount == 1) {
        DATESTATUS = true;
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        weekCount = calendar.get(Calendar.WEEK_OF_YEAR);
        recursiveWeekCountCheck(calendar, weekCount);
    }
    if (!VALUESTATUS){
        VALUESTATUS = true;
        if (DATESTATUS) {
            weekCount++;
            WEEK_OF_MONTH = weekCount;
        } else {
            WEEK_OF_MONTH = weekCount;
        }
    }
    return WEEK_OF_MONTH;
}

最后只需调用方法getWeeksOfMonth((;

最新更新