Java Calendar giving wrong value after parsing month string - java

I know that Java month begins from 0 and we have to add an offset of 1 to it,but when I use the following code which has a CST time zone,I get value for february month as 6.
I am trying to convert month to its equivalent calendar value such as 1 for January and 2 for Feb and so on.
Calendar cal = Calendar.getInstance();
cal.setTime(new SimpleDateFormat("MMM").parse("FEB"));
int monthInt = cal.get(Calendar.MONTH) + 1;
System.out.println(monthInt);
But when I run it in a machine with time zone as Indian Standard Time(IST-GMT +5.30) I get the expected value as 2.
What is wrong here?Do I need to include any locale to my calendar.I am getting totally meaningless values for months with the above code.

You should instantiate your Calendar with appropriate locales:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("IST"),Locale.US);

tl;dr
Month.JANUARY.getValue()
1
Wrong class
You are trying to represent a month using a class that represents a moment. Square peg, round hole.
But when I run it in a machine with time zone as Indian Standard Time(IST-GMT +5.30) I get the expected value as 2.
Again, this occurs because you used the wrong class, a class that represents a moment in the context of a time zone.
I know that Java month begins from 0
Again, you are using the wrong class. This crazy numbering is one of many reasons why the date-time classes bundled with the earliest versions of Java were supplanted by the java.time classes defined by JSR 310 and built into Java 8 and later. Do not use the legacy classes.
Month
The appropriate class for a month is Month. This modern java.time class has sane numbering, unlike the legacy date-time classes that you should avoid.
convert month to its equivalent calendar value such as 1 for January
Use the Month.JANUARY enum object. As for its number, 1-12 for January-December.
int monthNumber = Month.JANUARY.getValue() ;
1
But I suggest you avoid representing a month by a mere integer number. Instead, use Month enum objects throughout your codebase. This makes your code more self-documenting, ensures valid values, and provides type-safety.
Use this:
public void runMonthlyReport( Month month ) { … }
…instead of this:
public void runMonthlyReport( int monthNumber ) { … }
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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.

Related

Date compare java fail

while comparing future days it occurs some fail in Java. Look at the code if you can
DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
Date date = dateFormat.parse("2258-11-01");
Date date1 = dateFormat.parse("2258-10-31");
System.out.println(date.after(date1));
Output is:false
Anyone has idea why it does't work?
The m format represents a minute in the hour. You probably meant to use M, representing the month in the year:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
You should use the capital MM for month, overwise it does not parse like you want it to.
new SimpleDateFormat("yyyy-MM-dd");
tl;dr
Use the modern java.time classes to parse your strings that happen to be in standard format.
LocalDate.parse( "2258-11-01" )
.isAfter(
LocalDate.parse( "2258-10-31" )
)
true
Details
As others mentioned, the formatting pattern is case-sensitive, and yours is incorrect.
Another problem, you are inappropriately squeezing a date-only value into a type intended for a date with time-of-day in UTC.
Also, you are using the terrible old date-time classes that were supplanted years ago by the modern java.time classes.
Your input strings happen to comply with the excellent ISO 8601 standard. The java.time classes use these formats by default when parsing/generating strings. So no need to even bother with defining a formatting pattern.
LocalDate ld1 = LocalDate.parse( "2258-11-01" ) ;
LocalDate ld2 = LocalDate.parse( "2258-10-31" ) ;
Compare.
boolean isAfter = ld1.isAfter( ld2 ) ; // true
All this has been covered many many times already on Stack Overflow. Please learn to search Stack Overflow thoroughly before posting.
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 SWT DateTime: Determine day of Week

I have a DateTime widget with 3/9/2017. Based on the documentation for DateTime, I don't see a way to determine the day of the week. I'll eventually need a string parsed in this format "Wed Feb 22 14:57:34 UTC 2017" from the DateTime widget, but the first step is to get the day of the week. Is there a way to do this outside of making my own function? And if not, what would you recommend as the best approach for the function, since days of the week are not consistent to dates from year to year?
Let me know if you need any addition information.
Thank you!
Use java.util.Calendar:
Calendar c = Calendar.getInstance();
c.setTime(yourDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
if you need the output to be Tue rather than 3 (Days of week are indexed starting at 1), instead of going through a calendar, just reformat the string: new SimpleDateFormat("EE").format(date) (EE meaning "day of week, short version")
Documentation
tl;dr
LocalDate.of( 2017 , Month.MARCH , 9 )
.getDayOfWeek()
.getDisplayName( TextStyle.FULL , Locale.ITALY )
Or…
OffsetDateTime.now( ZoneOffset.UTC )
.format( DateTimeFormatter.RFC_1123_DATE_TIME )
java.time
The modern approach uses the java.time classes that supplanted the troublesome old date-time classes.
The DayOfWeek enum defines seven objects, one for each day of the week, Monday-Sunday.
The LocalDate class represents a date-only value without time-of-day and without time zone.
DayOfWeek dow = LocalDate.now().getDayOfWeek() ;
Generate a string of the localized name.
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Or Locale.US etc.
To generate your longer string for a moment, use DateTimeFormatter to specify a custom pattern, use a built-in pattern, or automatically localize.
String output = OffsetDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.RFC_1123_DATE_TIME ) ;
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, 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 (<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.

Calendar get year returns wrong result

I want to create a calendar object and set it to a certain year and a week in that year.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.WEEK_OF_YEAR, weekOfYear); // 1
calendar.set(Calendar.YEAR, year); // 2016
setWeekChecked(calendar);
This is the toString of the calendar object as I pass it to the setWeekChecked method:
java.util.GregorianCalendar[time=?,areFieldsSet=false,lenient=true,zone=America/New_York,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2016,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=7,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=5,HOUR_OF_DAY=5,MINUTE=25,SECOND=43,MILLISECOND=219,ZONE_OFFSET=-18000000,DST_OFFSET=0]
In the setWeekChecked method:
public void setWeekChecked(final Calendar cal) {
final int targetWeek = cal.get(Calendar.WEEK_OF_YEAR); // Returns 1
final int targetYear = cal.get(Calendar.YEAR); // Returns 2015??
}
This is the toString of the calendar object now:
java.util.GregorianCalendar[time=1451557543219,areFieldsSet=true,lenient=true,zone=America/New_York,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=11,WEEK_OF_YEAR=1,WEEK_OF_MONTH=5,DAY_OF_MONTH=31,DAY_OF_YEAR=365,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=5,HOUR_OF_DAY=5,MINUTE=25,SECOND=43,MILLISECOND=219,ZONE_OFFSET=-18000000,DST_OFFSET=0]
What am I doing wrong?
I suspect that the calendar is trying to use the current day-of-week (it's Thursday today) in the first week of 2016.
Now, looking at your calendar settings, you've got firstDayOfWeek=1 (so weeks run Sunday to Saturday) and minimalDaysInFirstWeek=1 (so the first week of the year is the one that includes January 1st).
That means that the first week of 2016 in your calendar ran from Decemember 27th 2015 to January 2nd 2016. Therefore Thursday in the first week was December 31st - which is exactly what the calendar you've shown us says.
Fundamentally, calendar arithmetic with "week of year" is tricky because:
There are lots of different culture-specific ways of looking at them
Typically requirements don't specify which of those you're actually interested in
I'd strongly recommend using Joda Time if at all possible to make your date/time-handling code clearer to start with, but you'll still need to work out exactly what you mean by "set it to a certain year and a week in that year". Note that Joda Time separates the concepts of "week-year" (used with week-of-week-year and day-of-week) from "year" (used with month and day-of-month) which helps greatly. You need to be aware that for a given date, the week-year and year may be different.
tl;dr
LocalDate.of( 2016 , Month.JULY , 1 )
.with( IsoFields.WEEK_OF_WEEK_BASED_YEAR , 1 )
Details
The Answer by Jon Skeet is correct. Update: We have a better way.
The java.time classes built into Java 8 and later supplant the troublesome old legacy date-time classes bundled with the earliest versions of Java. And java.time officially supplants Joda-Time, as that project is now in maintenance mode.
As Skeet points out, there are different ways to define week-of-year.
The java.time classes provide support for the standard ISO 8601 definition of week-of-year. This definition is that week number 1 is the first week with a Thursday, and that week starts on a Monday. So the beginning of the week may include one or more days of the previous year, and the last week may include one or more days from the following year. The year always has either 52 or 53 weeks.
See my Answer to a similar Question for more details.
The LocalDate class represents a date-only value without time-of-day and without time zone.
Get a date near the middle of the desired year. That desired year is a week-based year rather than a calendar year, so must avoid the very beginning or ending of the calendar year. In your case, you wanted week-based year of 2016.
LocalDate ld = LocalDate.of( 2016 , Month.JULY , 1 ) ;
Next we adjust that date into the desired week by using IsoFields.WEEK_OF_WEEK_BASED_YEAR.
LocalDate dayIn2016W01 = ld.with( IsoFields.WEEK_OF_WEEK_BASED_YEAR , 1 ) ;
If you want the first day of that week, use another TemporalAdjuster from the TemporalAdjusters class.
LocalDate firstDayOf2016W01 = dayIn2016W01.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) );
Tip: When Android becomes more capable, use the YearWeek class from the ThreeTen-Extra project.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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. Hibernate 5 & JPA 2.2 support java.time.
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….

Java Calendar add issue

I'm having an issue with the Java Calendar add() functionality. The give or take is used to provide a roundabout date for dates to depart on a travel site.
end.add(Calendar.DATE, Integer.parseInt(giveOrTake));
The code is above and the test condition I'm using is to choose 29/07/2012 as the date and 3 days give or take. According to the documentation this should come out as 01/08/2012 but it comes out at 01/07/2012.
I've checked giveOrTake when it's passed to the method and it's fine so I have no idea what is going on. I can hardcode the giveOrTake value and still get the error.
Works for me:
import java.util.*;
public class Test {
public static void main (String []args) {
Calendar calendar = Calendar.getInstance();
calendar.set(2012, Calendar.JULY, 29);
calendar.add(Calendar.DATE, 3);
System.out.println(calendar.getTime()); // August 1st
}
}
My guess is that you've got the month wrong before calling add - note how my call to set above uses 6 as the month, because the call uses 0-based month numbers.
Note that as per my comment on the question, you'd be much better off moving to Joda Time if you can...
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
Also, you are using a date-time object to represent a date-only value, a misfit.
Using java.time
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate ld = LocalDate.of( 2012 , 7 , 29 ) ;
LocalDate threeDaysLater = ld.plusDays( 3 );
ld.toString(): 2012-07-29
threeDaysLater.toString(): 2012-08-01
See code run live in IdeOne.com.
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.
It was an issue with the date format. It was set as yyyymmdd when it should have been 'yyyyMMdd'.

How can I get the number of days in a year using JodaTime?

I've tried the following to no avail:
new Period(Years.ONE).getDays();
new Period(1, 0, 0, 000).getDays();
The answer I want is obviously 365.
The answer you want isn't obviously 365. It is either 365 or 366, you don't take into account leap years in your example.
Detecting a leap year and just hard coding it with a ternary statement would be unacceptable for some reason?
final DateTime dt = new DateTime();
final int daysInYear = dt.year().isLeap() ? 366 : 365;
Of course this would give you the number of days in the current year, how to get number of days in a different year is trivial and a exercise for the reader.
If you want the real number of days for a given year:
int year = 2012;
LocalDate ld = new LocalDate(year,1,1);
System.out.println(Days.daysBetween(ld,ld.plusYears(1)).getDays());
Of course, this returns 365 or 366... normally:
int year = 1582;
LocalDate ld = new LocalDate(year,1,1,GJChronology.getInstance());
System.out.println(Days.daysBetween(ld,ld.plusYears(1)).getDays());
// year 1582 had 355 days
tl;dr
java.time.Year.of( 2017 ).length()
Using java.time
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
The java.time.Year class can represent any particular year.
Year year = Year.of( 2017 );
You may interrogate for information about that year such as its length in number of days or whether it a Leap Year or not.
int countDaysInYear = year.length() ;
boolean isLeapYear = year.isLeap() ; // ISO proleptic calendar system rules.
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.
new DateTime().year().toInterval().toDuration().getStandardDays();

Categories