How to get a month as an integer from the given date and print as month name format (“MMM”)
How to get a month as an integer from the given date and print as month name format (“MMM”)
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?
SimpleDateFormat
Date
Calendar
SimpleDateFormat
java.time
Possible duplicate of SimpleDateFormat ignoring month when parsing. Or possibly more clearly a duplicate of Getting wrong month when using SimpleDateFormat.parse.
– Ole V.V.
Sep 16 '18 at 5:56
FYI, the terribly troublesome old date-time classes such as
java.util.Date
, java.util.Calendar
, and java.text.SimpleDateFormat
are now legacy, supplanted by the java.time classes built into Java 8 and later. See Tutorial by Oracle.– Basil Bourque
Sep 16 '18 at 6:25
java.util.Date
java.util.Calendar
java.text.SimpleDateFormat
@OleV.V. At first glance, your links do not seem to be spot-on originals. But I appreciate the effort you made. I am sure this is a duplicate though I could not quickly find an exact original.
– Basil Bourque
Sep 16 '18 at 6:27
3 Answers
3
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.
Date
Calendar
SimpleDateFormat
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.
LocalDate
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( "23/01/2018" , f ) ;
Month
Retrieve the month as a Month
enum object.
Month
Month m = ld.getMonth() ;
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:
Month
String
getDisplayName
TextStyle
Locale
Code:
String output = m.getDisplayName( TextStyle.SHORT , Locale.US ) ;
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.
Month
int
Month.getMonthValue()
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
.
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.
java.sql.*
Where to obtain the java.time classes?
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.
Interval
YearWeek
YearQuarter
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:
Calendar
LocalDate
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.
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.
SimpleDateFormat
Date
Calendar
DateTimeFormatter
M
m
SimpleDateFormat
Calendar
java.time
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);
Repeating the bug that caused the asker’s code to give 0 always — now it just gives
Jan
, always, depending on locale. It’s not your fault. It’s primarily because SimpleDateFormat
is troublesome and doesn’t help you detect the error.– Ole V.V.
Sep 16 '18 at 15:53
Jan
SimpleDateFormat
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy
First, the classes
SimpleDateFormat
,Date
andCalendar
are long outdated and were always poorly designed.SimpleDateFormat
in particular is renowned for trouble, Today we have so much better injava.time
, the modern Java date and time API. It’s so much nicer to work with. So I recommend you upgrade to java.time and forget about the old classes.– Ole V.V.
Sep 16 '18 at 5:53