简体   繁体   中英

Week number is wrong in android calendar

Week number is wrong in android calendar

In some of device getting as week 53, but in some other devices getting as week 1 for end of the year

Calendar calender = Calendar.getInstance(); int week = calender.get(Calendar.WEEK_OF_YEAR);

First Week

Calendar defines a locale-specific seven day week using two parameters: the first day of the week and the minimal days in first week (from 1 to 7). These numbers are taken from the locale resource data when a Calendar is constructed. They may also be specified explicitly through the methods for setting their values.

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() days of that month or year . Weeks numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow it. Note that the normalized numbering returned by get() may be different. For example, a specific Calendar subclass may designate the week before week 1 of a year as week n of the previous year.

From Java documentation ( 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

Not sure of the direct answer to your Question, but likely to be differing Locale values in play. In Calendar the definition of a week varies by the locale.

But this is moot . You should be using the java.time classes that replaced Calendar class.

java.time

Calendar is part of the troublesome old date-time classes that are now legacy, supplanted by the java.time classes. For earlier Android, see the last bullets below.

You must define what you mean by week number. There are different ways to define a week and week number.

By default, the java.time classes use the standard ISO 8601 definition : Week # 1 has the first Thursday of the calendar year, and starts on Monday (as you asked for). So years have either 52 or 53 weeks. The first and last few days of the calendar year may land in the prior/following week-based year.

The LocalDate class represents a date-only value without time-of-day and without time zone.

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

Interrogate for the standard week number. You can ask for either of these TemporalField objects: 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 ) ;

Dump to console using standard ISO 8601 format of YYYY-Www-D .

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

See this code run live at IdeOne.com .

2012-08-07 is ISO 8601 week: 2012-W32-2

By the way, if Android is ever able to run the ThreeTen-Extra library, you'll find its YearWeek class useful.


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 , & SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.

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?

Here you can view the reference by oracle

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

And I have placed a quick solution to find the week count of current day. You can alter and optimize as your way. Also set your GMT value according to your need.

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;
}

At the end just call the method getWeeksOfMonth();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM