I wanna programmatically convert an integer in the range 1-12 to corresponding month name. (e.g. 1 -> January, 2 -> February) etc using Java Calendar class in one statement.
Note : I want to do it using Java Calendar class only. Don't suggest any switch-case or string array solution.
Thanks.
The Calendar class is not the best class to use when it comes obtaining the localized month name in one statement.
The following is an example of obtaining the month name of a desired month specified by a int value (where January is 1), using only the Calendar class:
// Month as a number.
int month = 1;
// Sets the Calendar instance to the desired month.
// The "-1" takes into account that Calendar counts months
// beginning from 0.
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, month - 1);
// This is to avoid the problem of having a day that is greater than the maximum of the
// month you set. c.getInstance() copies the whole current dateTime from system
// including day, if you execute this on the 30th of any month and set the Month to 1
// (February) getDisplayName will get you March as it automatically jumps to the next
// Month
c.set(Calendar.DAY_OF_MONTH, 1);
// Returns a String of the month name in the current locale.
c.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
The above code will return the month name in the system locale.
If another locale is required, one can specify another Locale by replacing the Locale.getDefault() with a specific locale such as Locale.US.
Use DateFormatSymbols
Proudly copied and pasted from bluebones.net:
import java.text.*;
String getMonthForInt(int m) {
String month = "invalid";
DateFormatSymbols dfs = new DateFormatSymbols();
String[] months = dfs.getMonths();
if (m >= 0 && m <= 11 ) {
month = months[m];
}
return month;
}
Did you read the API? The method getDisplayName(...) looks like a good place to start. Doing it in one statement is a terrible requirement.
tl;dr
Month.of( 12 ).getDisplayName( TextStyle.FULL , Locale.US )
…or…
Month.DECEMBER.getDisplayName( TextStyle.FULL , Locale.US )
December
Using java.time
The modern way to get the localized name of a month is with the java.time.Month enum. This class is part of the java.time package than now supplants the troublesome old legacy date-time classes such as Date and Calendar.
To localize, specify:
TextStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example code.
Month month = Month.of( 7 );
String outputConstantName = month.toString();
String outputMonthNameEnglish = month.getDisplayName( TextStyle.FULL , Locale.US );
String outputMonthQuébec = month.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );
month.toString(): JULY
outputMonthNameEnglish: July
outputMonthQuébec: juillet
Using the Month enum objects by name rather than month number can be handy, easier to read, and less error-prone.
String output = Month.JULY.getDisplayName( TextStyle.FULL , Locale.US ) ;
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?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
I am new to Java and couldnt retrieve the month while using the below code instead month value is set to 0. Please advise the mistakes that i have done here.
*
for(int i=0;i<this.input.size();i++)
{
SimpleDateFormat sf = new SimpleDateFormat("dd/mm/yyyy");
Date purchasedate;
try {
String details = input.get(i);
String[] detailsarr = details.split(",");
purchasedate = sf.parse(detailsarr[1]);
Calendar cal = Calendar.getInstance();
cal.setTime(purchasedate);
int month = cal.get(Calendar.MONTH);
*
After getting the above month as an integer, Could you please advise if there is anyway to print the above month value as "MMM" format?
tl;dr
LocalDate.parse( // Represent a date-only value, without time-of-day and without time zone.
"23/01/2018" , // Tip: Use standard ISO 8601 formats rather than this localized format for data-exchange of date-time values.
DateTimeFormatter.ofPattern( "dd/MM/uuuu" )
) // Return a `LocalDate` object.
.getMonth() // Return a `Month` enum object representing the month of this date.
.getDisplayName( // Automatically localize, generating text of the name of this month.
TextStyle.SHORT , // Specify (a) how long or abbreviated, and (b) specify whether used in stand-alone or combo context linguistically (irrelevant in English).
Locale.US // Specify the human language and cultural norms to use in translation.
) // Returns a `String`.
See this code run live at IdeOne.com.
Jan
java.time
The modern approach uses the java.time classes that supplanted the terrible Date/Calendar/SimpleDateFormat classes.
ISO 8601
Tip: When exchanging date-time values as text, use the ISO 8601 standard formats rather than using text meant for presentation to humans. For a date-only value, that would be YYYY-MM-DD such as 2018-01-23.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( "23/01/2018" , f ) ;
Month enum
Retrieve the month as a Month enum object.
Month m = ld.getMonth() ;
Localize
Ask that Month enum to generate a String with text of the name of the month. The getDisplayName method can automatically localize for you. To localize, specify:
TextStyle to determine how long or abbreviated should the string be. Note that in some languages you may need to choose stand-alone style depending on context in which you intend to use the result.
Locale to determine:
The human language for translation of name of day, name of month, and such.
The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Code:
String output = m.getDisplayName( TextStyle.SHORT , Locale.US ) ;
Use enum, not integer
Notice that we had no use of an integer number to represent the month. Using an enum object instead makes our code more self-documenting, ensures valid values, and provides type-safety.
So I strongly recommend passing around Month objects rather than mere int integer numbers. But if you insist, call Month.getMonthValue() to get a number. The numbering is sane, 1-12 for January-December, unlike the legacy classes.
int monthNumber = ld.getMonthValue() ;
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
java.time
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
String dateStringFromInput = "29/08/2018";
LocalDate purchasedate = LocalDate.parse(dateStringFromInput, dateFormatter);
int monthNumber = purchasedate.getMonthValue();
System.out.println("Month number is " + monthNumber);
Running the above snippet gives this output:
Month number is 8
Note that contrary to Calendar LocalDate numbers the months the same way humans do, August is month 8. However to get the month formatted into a standard three letter abbreviation we don’t need the number first:
Locale irish = Locale.forLanguageTag("ga");
DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMM", irish);
String formattedMonth = purchasedate.format(monthFormatter);
System.out.println("Formatted month: " + formattedMonth);
Formatted month: Lún
Please supply your desired locale where I put Irish/Gaelic. Java knows the month abbreviations in a vast number of languages.
What went wrong in your code?
Apart from using the long outdated date and time classes, SimpleDateFormat, Date and Calendar, format pattern letters are case sensitive (this is true with the modern DateTimeFormatter too). To parse or format a month you need to use uppercase M (which you did correctly in your title). Lowercase m is for minute of the hour. SimpleDateFormat is troublesome here (as all too often): rather than telling you something is wrong through an exception it just tacitly defaults the month to January. Which Calendar in turn returns to you as month 0 because it unnaturally numbers the months from 0 through 11.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Question: Why is January month 0 in Java Calendar?
Simple way of doing this is
Calendar cal = Calendar.getInstance();
Date d = cal.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MMM");
System.out.println(sdf.format(d));
In your case modify snippet like below:
SimpleDateFormat sf = new SimpleDateFormat("dd/mm/yyyy");
Date purchasedate;
try {
String details = input.get(i);
String[] detailsarr = details.split(",");
purchasedate = sf.parse(detailsarr[1]);
SimpleDateFormat sdf = new SimpleDateFormat("MMM");
String month = sdf.format(purchasedate);
}
I have a string containing a date in the form
04-Jan-15
and need to get the week number of the year out of it.
for the above example week 1(or 2 depending on locale and weekdays in December. never mind that).
I have this:
String[] startDate=dates[0].split("-");
int month,day,year;
year=2000+Integer.parseInt(startDate[2]);
day=Integer.parseInt(startDate[0]);
switch (startDate[1]){
case "Jan":
{
month=1;
break;
}
........
........
case "Dec":
{
month=12;
break;
}
}
Calendar temp=new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try {
Date tempDate = sdf.parse(day+"/"+month+"/"+year);
System.out.println("DATE:"+tempDate);
temp.setTime(tempDate);
System.out.println("Calendar Month:"+temp.MONTH);
System.out.println("Calendar Week:"+temp.WEEK_OF_YEAR);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This returns
DATE:Sun Jan 04 00:00:00 EET 2015
Calendar Month:2
Calendar Week:3
I tried (earlier) this
temp.set(year, month, day);
and was still getting wrong results.
Any idea?
tl;dr
For culturally-defined weeks…
LocalDate.parse(
"04-Jan-15" ,
DateTimeFormatter.ofPattern( "dd-MMM-uu" , Locale.US )
).get(
WeekFields.of( Locale.FRANCE ).weekOfWeekBasedYear( )
) // Gets week number for a culturally-defined week-of-year.
For standard weeks…
LocalDate.parse(
"04-Jan-15" ,
DateTimeFormatter.ofPattern( "dd-MMM-uu" , Locale.US )
).get(
IsoFields.WEEK_OF_WEEK_BASED_YEAR
) // Gets standard ISO 8601 week number.
java.time
You are using troublesome old date-time classes that are now legacy, supplanted entirely by the java.time classes. Much simpler now to solve your problem.
Parse your input string. Specify a Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
String input = "04-Jan-15";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uu" , Locale.US );
LocalDate ld = LocalDate.parse( input , f );
Dump to console.
System.out.println( "input: " + input + " = " + ld );
input: 04-Jan-15 = 2015-01-04
Week number
Week number is culturally defined. To access week-of-year, you must specify a Locale whose culture you want to use in defining a week.
Locale locale = Locale.FRANCE;
WeekFields fields = WeekFields.of( locale );
TemporalField field = fields.weekOfWeekBasedYear( );
int weekNumber = ld.get( WeekFields.of( Locale.FRANCE ).weekOfWeekBasedYear( ) ); // Gets week number for a culturally-defined week-of-year.
ISO 8601 defines standard week numbers where week # 1 contains the first Thursday of the year, and begins on a Monday. The java.time class offer this approach built-in in the IsoFields class.
int weekNumber = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) // Gets standard ISO 8601 week number.
ISO 8601
By the way, that input string format is not good. When exchanging date-time values as text, always use ISO 8601 standard formats. These are used by default in java.time when parsing/generating strings.
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
MONTH and WEEK_OF_YEAR in class Calendar are constants, not the month and week of year of any particular Calendar object.
You use these constants with the get(...) method. The constant indicates which field you want to get. Like this:
System.out.println("Calendar Month:" + temp.get(Calendar.MONTH));
System.out.println("Calendar Week:" + temp.get(Calendar.WEEK_OF_YEAR));
Also, there's a much easier way to parse a string like 04-Jan-15 into a Date object than doing it manually:
String text = "04-Jan-15";
DateFormat df = new SimpleDateFormat("dd-MMM-yy", Locale.US);
Date date = df.parse(text);
(Why are you first parsing the string manually, then converting it into another format dd/MM/yyyy and then parsing that again? That's much more complicated than necessary).
I am trying to get day ,month and year from a Julian date.
String date = "13136";//Julian date
Date convertedDate = new SimpleDateFormat("yyDDD").parse(date);
System.out.println(convertedDate);
It prints
Thu May 16 00:00:00 BST 2013
which is correct.
Now I want to get Day , Month and Year from it
Calendar cal = Calendar.getInstance();
cal.setTime(convertedDate);
System.out.println(cal.get(Calendar.MONTH));
It prints 4 .
It should print 5 instead of 4 . Why is it not printing as correct ? What I have done wrong here?
As per the javadoc of Calendar.MONTH:
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
So months starts from zero so your output 4 is correct, for general usecase in your code it would be safe to add 1 to it unless you use this values as MONTH value in Calendar again.
As the javadocs state, months begin at zero: 0 = January, 1 = February, and so on.
tl;dr
LocalDate.parse (
"13136",
DateTimeFormatter.ofPattern ( "uuDDD" )
).getMonthValue()
5
…for month of May 2013.
Ordinal, not Julian
Your use of the word “Julian” is technically incorrect, though common. Folks seem to confuse day-of-year (1-365 or 1-366) with practice of counting the number of days elapsed since January 1, 4713 BC used in some scientific fields.
The terms “ordinal date” or day-of-year are more clear.
ISO 8601
Your format for ordinal dates is not standard. Whenever possible, use the standard ISO 8601 formats:
YYYY-DDD
YYYYDDD
java.time
The modern way is with the java.time classes that supplant the troublesome old legacy date-time classes.
DateTimeFormatter
Note that the formatting pattern codes in DateTimeFormatter class are similar to the legacy class but not exactly the some.
String input = "13136"; //Julian date
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuDDD" );
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate localDate = LocalDate.parse ( input, f );
Dump to console.
System.out.println ("localDate: " + localDate );
localDate: 2013-05-16
Month
You can ask about the month of that LocalDate. The Month enum pre-defines a dozen objects, one for each month of the year. And unlike the crazy legacy classes, these are sanely numbered 1-12 for January-December.
If you are passing the month number around your code, I suggest you instead pass around these enum objects. Doing so gives you type-safety, valid values, and self-documenting code.
Month month = localDate.getMonth();
You can get the localized name of that month if needed.
String output = month.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ); // Or Locale.US, Locale.ITALY, whatever.
If you truly do need the number of the month 1-12, ask in either way.
int monthNumber = month.getValue() ;
int monthNumber = localDate.getMonthValue() ;
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?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
This question already has answers here:
Why dec 31 2010 returns 1 as week of year?
(6 answers)
Closed 5 years ago.
I'm trying to understand how java.util.Calendar.get(java.util.Calendar.WEEK_OF_YEAR) works, but it seems that I'm missing some points.
String time = "1998-12-31"; // year month day
java.util.Calendar date = java.util.Calendar.getInstance();
date.setTime((new java.text.SimpleDateFormat("yyyy-MM-dd")).parse(time));
System.err.println("Week of year = " + date.get(java.util.Calendar.WEEK_OF_YEAR));
// Week of year = 1 Why ???
Why date.get(java.util.Calendar.WEEK_OF_YEAR) returns 1 for the last week of the year?
Moreover, WEEK_OF_YEAR for "1998-01-01" is 1 and for "1998-12-23" it is 52.
Does anybody have an explanation for this behavior?
From java.util.Calendar javadoc:
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.
So it's locale-specific. In your case, if the week contains days from new year, it is counted as week 1 from the new year.
You can change this behavior by using Calendar#setMinimalDaysInFirstWeek(int).
tl;dr
java.time.LocalDate.parse( "1998-12-31" )
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
53
Or, add a library, and then…
org.threeten.extra.YearWeek.from( // Convert from a `LocalDate` object to a `YearWeek` object representing the entire week of that date’s week-based year.
LocalDate.parse( "1998-12-31" ) // Parse string into a `LocalDate` objects.
).getWeek() // Extract an integer number of that week of week-based-year, either 1-52 or 1-53 depending on the year.
53
Details
I'm trying to understand how java.util.Calendar.get(java.util.Calendar.WEEK_OF_YEAR) works
Don’t! That class is a bloody mess, and best left forgotten.
The answer by npe is correct. In Calendar, the definition of a week varies by locale. A well-intentioned feature, but confusing.
Standard week definition
There are many ways to define “a week” and “first week of the year”.
However, there is one major standard definition: the ISO 8601 standard. That standard defines weeks of the year, including the first week of the year.
the week with the year's first Thursday
A standard week begins with Monday and ends with Sunday.
Week # 1 of a standard week-based-year has the first Thursday of the calendar-year.
java.time
The java.time classes supplanted the troublesome legacy date-time classes. These modern classes support the ISO 8601 week through the IsoFields class, holding three constants that implement TemporalField:
WEEK_OF_WEEK_BASED_YEAR
WEEK_BASED_YEAR
WEEK_BASED_YEARS
Call LocalDate::get to access the TemporalField.
LocalDate ld = LocalDate.parse( "1998-12-31" ) ;
int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;
ld.toString(): 1998-12-31
weekOfWeekBasedYear: 53
yearOfWeekBasedYear: 1998
Notice the day after, the first day of the new calendar year 1999, also is in the same week, week # 53 of week-based 1998.
LocalDate firstOf1999 = ld.plusDays( 1 );
int weekOfWeekBasedYear_FirstOf1999 = firstOf1999.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear_FirstOf1999 = firstOf1999.get( IsoFields.WEEK_BASED_YEAR ) ;
firstOf1999.toString(): 1999-01-01
weekOfWeekBasedYear_FirstOf1999: 53
yearOfWeekBasedYear_FirstOf1999: 1998
ISO 8601 string format
The ISO 8601 standard defines a textual format as well as a meaning for week-based-year values: yyyy-Www. For a specific date, add day-of-week numbered 1-7 for Monday-Sunday: yyyy-Www-d.
Construct such a string.
String outputWeek = ld.format( DateTimeFormatter.ISO_WEEK_DATE ) ; // yyyy-Www
1998-W53
String outputDate = outputWeek + "-" + ld.getDayOfWeek().getValue() ; // yyyy-Www-d
1998-W53-4
YearWeek
This work is much easier if you add the ThreeTen-Extra library to your project. Then use the YearWeek class.
YearWeek yw = YearWeek.from( ld ) ; // Determine ISO 8601 week of a `LocalDate`.
Generate the standard string.
String output = yw.toString() ;
1998-W53
And parse.
YearWeek yearWeek = YearWeek.parse( "1998-W53" ) ;
yearWeek.toString(): 1998-W53
Determine a date. Pass a java.time.DayOfWeek enum object for day-of-week Monday-Sunday.
LocalDate localDate = yw.atDay( DayOfWeek.MONDAY ) ;
localDate.toString(): 1998-12-28
I strongly recommending adding this library to your project. Then you can pass around smart objects rather than dumb ints. Doing so makes your code more self-documenting, provides type-safety, and ensures valid values.
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.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This section left intact as history.
The excellent Joda-Time framework uses ISO 8601 for its defaults. Its classes include this week-of-year information. Joda-Time is a popular replacement for the notoriously troublesome java.util.Date & java.util.Calendar classes bundled with Java.
Example Code
Here is some example code to get first moment of the first day of the first week of the year of the current date-time.
Note the call to withTimeAtStartOfDay to get the first moment of the day.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime now = new DateTime( timeZone );
DateTime firstWeekStart = now.withWeekOfWeekyear(1).withDayOfWeek(1).withTimeAtStartOfDay();
DateTime firstWeekStop = firstWeekStart.plusWeeks( 1 );
Interval firstWeek = new Interval( firstWeekStart, firstWeekStop );
Dump to console…
System.out.println( "now: " + now );
System.out.println( "firstWeekStart: " + firstWeekStart );
System.out.println( "firstWeekStop: " + firstWeekStop );
System.out.println( "firstWeek: " + firstWeek );
When run…
now: 2014-02-07T12:49:33.623+01:00
firstWeekStart: 2013-12-30T00:00:00.000+01:00
firstWeekStop: 2014-01-06T00:00:00.000+01:00
firstWeek: 2013-12-30T00:00:00.000+01:00/2014-01-06T00:00:00.000+01:00
This question already has answers here:
Why is January month 0 in Java Calendar?
(18 answers)
Closed 2 years ago.
Calendar rightNow = Calendar.getInstance();
String month = String.valueOf(rightNow.get(Calendar.MONTH));
After the execution of the above snippet, month gets a value of 10 instead of 11. How come?
Months are indexed from 0 not 1 so 10 is November and 11 will be December.
They start from 0 - check the docs
As is clear by the many answers: the month starts with 0.
Here's a tip: you should be using SimpleDateFormat to get the String-representation of the month:
Calendar rightNow = Calendar.getInstance();
java.text.SimpleDateFormat df1 = new java.text.SimpleDateFormat("MM");
java.text.SimpleDateFormat df2 = new java.text.SimpleDateFormat("MMM");
java.text.SimpleDateFormat df3 = new java.text.SimpleDateFormat("MMMM");
System.out.println(df1.format(rightNow.getTime()));
System.out.println(df2.format(rightNow.getTime()));
System.out.println(df3.format(rightNow.getTime()));
Output:
11
Nov
November
Note: the output may vary, it is Locale-specific.
As several people have pointed out, months returned by the Calendar and Date classes in Java are indexed from 0 instead of 1. So 0 is January, and the current month, November, is 10.
You might wonder why this is the case. The origins lie with the POSIX standard functions ctime, gmtime and localtime, which accept or return a time_t structure with the following fields (from man 3 ctime):
int tm_mday; /* day of month (1 - 31) */
int tm_mon; /* month of year (0 - 11) */
int tm_year; /* year - 1900 */
This API was copied pretty much exactly into the Java Date class in Java 1.0, and from there mostly intact into the Calendar class in Java 1.1. Sun fixed the most glaring problem when they introduced Calendar – the fact that the year 2001 in the Gregorian calendar was represented by the value 101 in their Date class. But I'm not sure why they didn't change the day and month values to at least both be consistent in their indexing, either from zero or one. This inconsistency and related confusion still exists in Java (and C) to this day.
Months start from zero, like indexes for lists.
Therefore Jan = 0, Feb = 1, etc.
From the API:
The first month of the year is JANUARY
which is 0; the last depends on the
number of months in a year.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html
tl;dr
LocalDate.now() // Returns a date-only `LocalDate` object for the current month of the JVM’s current default time zone.
.getMonthValue() // Returns 1-12 for January-December.
Details
Other answers are correct but outdated.
The troublesome old date-time classes had many poor design choices and flaws. One was the zero-based counting of month numbers 0-11 rather than the obvious 1-12.
java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
Now in maintenance mode, the Joda-Time project also advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.
Months 1-12
In java.time the month number is indeed the expected 1-12 for January-December.
The LocalDate class represents a date-only value without time-of-day and without time zone.
Time zone
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
int month = today.getMonthValue(); // Returns 1-12 as values.
If you want a date-time for a time zone, use ZonedDateTime object in the same way.
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
int month = now.getMonthValue(); // Returns 1-12 as values.
Convert legacy classes
If you have a GregorianCalendar object in hand, convert to ZonedDateTime using new toZonedDateTime method added to the old class. For more conversion info, see Convert java.util.Date to what “java.time” type?
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
int month = zdt.getMonthValue(); // Returns 1-12 as values.
Month enum
The java.time classes include the handy Month enum, by the way. Use instances of this class in your code rather than mere integers to make your code more self-documenting, provide type-safety, and ensure valid values.
Month month = today.getMonth(); // Returns an instant of `Month` rather than integer.
The Month enum offers useful methods such as generating a String with the localized name of the month.
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
cal.get(Calendar.MONTH) + 1;
The above statement gives the exact number of the month. As get(Calendar.Month) returns month starting from 0, adding 1 to the result would give the correct output. And keep in mind to subtract 1 when setting the month.
cal.set(Calendar.MONTH, (8 - 1));
Or use the constant variables provided.
cal.set(Calendar.MONTH, Calendar.AUGUST);
It would be better to use
Calendar.JANUARY
which is zero ...