Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Calendar returning the wrong month number

I'm working on a function to compare the week number of some sqlite stored dates with the week number of the current date.

But the set(y, m, d) method of the Calendar class always returns a date with a wrong month number in my case it return a date with the month set to july instead of june.

Here's my snippet of code :

//Date depuis SQLite/Grab date from SQLite
String[] tokens = extraireTokensDate(s.getDateHeure());

//Comparaison semaine/Week compare
Calendar cal1 = Calendar.getInstance();
Date date = new Date();
cal1.setTime(date);

Log.d("DEBUG", "DATE SQL : "+Integer.parseInt(tokens[0])+" "+Integer.parseInt(tokens[1])+" "+Integer.parseInt(tokens[2]));
Calendar cal2 = Calendar.getInstance();
cal2.set(Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1]), Integer.parseInt(tokens[2]));

SimpleDateFormat sdf = new SimpleDateFormat("W) dd/MM/yyyy");

Log.d("DEBUG", "(Actuel/Now) DATE : "+sdf.format(cal1.getTime()));
Log.d("DEBUG", "(Actuel/Now) Numero de semaine (annee/year) : "+cal1.get(Calendar.WEEK_OF_YEAR));    
Log.d("DEBUG", "(Passe/Past) DATE : "+sdf.format(cal2.getTime()));
Log.d("DEBUG", "(Passe/Past) Numero de semaine (annee/year) : "+cal2.get(Calendar.WEEK_OF_YEAR));

The output of the debugger (dates are French formated)

06-12 19:32:37.035: DEBUG/DEBUG(5777): DATE SQL : 2011 6 12
06-12 19:32:37.045: DEBUG/DEBUG(5777): (Actuel/Now) DATE : 3) 12/06/2011
06-12 19:32:37.045: DEBUG/DEBUG(5777): (Actuel/Now) Numero de semaine/Week number (annee/year) : 24
06-12 19:32:37.055: DEBUG/DEBUG(5777): (Passe/Past) DATE : 3) 12/07/2011
06-12 19:32:37.055: DEBUG/DEBUG(5777): (Passe/Past) Numero de semaine/Week number (annee/year) : 28
06-12 19:32:37.065: DEBUG/DEBUG(5777): DATE SQL : 2011 6 11
06-12 19:32:37.075: DEBUG/DEBUG(5777): (Actuel/Now) DATE : 3) 12/06/2011
06-12 19:32:37.075: DEBUG/DEBUG(5777): (Actuel/Now) Numero de semaine/Week number (annee/year) : 24
06-12 19:32:37.075: DEBUG/DEBUG(5777): (Passe/Past) DATE : 3) 11/07/2011
06-12 19:32:37.075: DEBUG/DEBUG(5777): (Passe/Past) Numero de semaine/Week number (annee/year) : 28
06-12 19:32:37.095: DEBUG/DEBUG(5777): DATE SQL : 2011 6 7
06-12 19:32:37.105: DEBUG/DEBUG(5777): (Actuel/Now) DATE : 3) 12/06/2011
06-12 19:32:37.105: DEBUG/DEBUG(5777): (Actuel/Now) Numero de semaine/Week number (annee/year) : 24
06-12 19:32:37.105: DEBUG/DEBUG(5777): (Passe/Past) DATE : 2) 07/07/2011
06-12 19:32:37.105: DEBUG/DEBUG(5777): (Passe/Past) Numero de semaine/Week number (annee/year) : 27
06-12 19:32:37.125: DEBUG/DEBUG(5777): DATE SQL : 2011 6 3
06-12 19:32:37.125: DEBUG/DEBUG(5777): (Actuel/Now) DATE : 3) 12/06/2011
06-12 19:32:37.125: DEBUG/DEBUG(5777): (Actuel/Now) Numero de semaine/Week number (annee/year) : 24
06-12 19:32:37.135: DEBUG/DEBUG(5777): (Passe/Past) DATE : 2) 03/07/2011
06-12 19:32:37.135: DEBUG/DEBUG(5777): (Passe/Past) Numero de semaine/Week number (annee/year) : 27

Any idea of what I did wrong?

like image 943
DoesNotCompute Avatar asked Oct 18 '25 18:10

DoesNotCompute


2 Answers

It's because the month numbers taken by the set() method are zero-indexed (eg JANUARY = 0), but you're passing in the normal month number (ie January = 1).

I suggest using the provided SimpleDateFormat.parse() method.

like image 69
John Carter Avatar answered Oct 20 '25 08:10

John Carter


java.time

The month numbering in the java.util date-time API was 0-based, which was confusing and error-prone. The modern java.time date-time API, introduced with Java 8 in March 2014, supplanted the error-prone legacy java.util date-time API. It is highly recommended to use java.time API for any new code.

Solution using java.time API

The java.time The API is based on the ISO 8601 standard, which defines the month numbering convention that we use, i.e., 1 for January, 2 for February, and so on. In addition to numbers, this API also allows us to specify months using constants, e.g. Month.MAY. The instances of java.time types are immutable, which makes them immune to many problems.

By the way, while the title and the description of your problem state the problem with the month, your code also has an interesting thing, which is the week number. Note that the week number is Locale-dependent. So, the same date may return a different week number for a different locale e.g. check the 2010 calendar for France and America.

Demo:

public class Main {
    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2013, 6, 20); // 20-Jun-2013
        System.out.println(date1.getMonth());

        LocalDate date2 = LocalDate.of(2013, Month.JUNE, 20); // 20-Jun-2013
        System.out.println(date2.getMonth().getValue());
        System.out.println(date2.getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH));

        // Week number
        LocalDate date3 = LocalDate.of(2010, 12, 31); // 31-Dec-2010
        System.out.println(date3.get(WeekFields.of(Locale.US).weekOfWeekBasedYear()));
        System.out.println(date3.get(WeekFields.of(Locale.FRANCE).weekOfWeekBasedYear()));
    }
}

Output:

JUNE
6
June
1
52

Online Demo

Learn more about the modern Date-Time API from Trail: Date Time.

like image 45
Arvind Kumar Avinash Avatar answered Oct 20 '25 07:10

Arvind Kumar Avinash