Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I change month only in java date object?

I have java date object.

How can I change its month without changing the year.

e.g.

12/1/14

I want to change it to

12/3/14 and to 12/10/14

I basically want to change the month by +/- x month without changing the year.

Can it be done?

like image 937
Elad Benda2 Avatar asked Dec 07 '22 00:12

Elad Benda2


2 Answers

Calendar cal = Calendar.getInstance();
cal.setTime(date); // your date (java.util.Date)
cal.add(Calendar.MONTH, x); // You can -/+ x months here to go back in history or move forward.
return cal.getTime(); // New date

ref : Java Calendar

like image 180
TJ- Avatar answered Dec 25 '22 22:12

TJ-


tl;dr

myJavaSqlDate      // Object of terrible legacy class `java.sql.Date` that *pretends* to represent a date-only value.
.toLocalDate()     // Convert to modern replacement, `java.time.LocalDate`. 
.withMonth( 3 )    // Swap out month for March while keeping the year and day-of-month.

… or:

myJavaUtilDate                      // Object of terrible legacy class `java.util.Date` representing a moment as seen in UTC.
.toInstant()                        // Convert to modern replacement, `java.time.Instant`. 
.withZone(                          // Adjust from UTC (offset of zero) to a specific time zone.
    ZoneId.of( "Africa/Tunis" )     // Real time zone names have format of `Continent/Region`. 
)                                   // Returns a `ZonedDateTime` object.
.toLocalDate()                      // Returns a `LocalDate` object.
.plusMonths( 2 )                    // Add two months while trying to keep same day-of-month. Returns another `LocalDate` object rather than altering the first, per immutable objects pattern.

java.time

LocalDate localDate = LocalDate.of ( 2017, Month.JANUARY, 23 );
LocalDate localDateFeb = localDate.withMonth ( 2 );

…or…

LocalDate localDateFeb = localDate.withMonth ( Month.FEBRUARY.getValue ( ) );

localDate.toString(): 2017-01-23

localDateFeb.toString(): 2017-02-23

The other Answers use the troublesome old date-time classes, now supplanted by the java.time classes.

Adapt from java.sql.Date class

If you have a java.sql.Date class in hand, convert from that terrible legacy class to its modern replacement, java.time.LocalDate. Call the new to…/from… conversion methods added to the old classes.

LocalDate localDate = myJavaSqlDate.toLocalDate() ;
LocalDate later = localDate.plusMonths( 2 ) ;  // or `withMonth( 3 )`.

Adapt from java.util.Date class

If you have a java.util.Date class in hand, convert from that terrible legacy class to its modern replacement, java.time.LocalDate. To get there, we must jump through a couple hoops.

A java.util.Date object represents a moment, not a date, despite the class name. By "moment" I mean a date with time-of-day as seen with an offset-from-UTC of zero hours-minutes-seconds. So we need to convert from this legacy class to its modern replacement, java.time.Instant. Call the new to…/from… conversion methods added to the old classes.

Instant instant = myJavaUtilDate.toInstant() ;

Zone determines date

You want a date. But there is a speed-bump here. Understand that for any given moment, the date varies around the globe by time zone. At a given moment, it may be "tomorrow" in Tokyo Japan while simultaneously still "yesterday" in Toledo Ohio US. So perceiving a date for a given moment requires a time zone.

For a time zone, use class ZoneId. Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;

Apply that time zone to adjust from UTC of an Instant. The adjustment results in a ZonedDateTime. Both the original Instant and the ZonedDateTime represent the very same moment, the same point on the timeline, only their wall-clock time is different.

ZonedDateTime zdt = instant.atZone( z ) ;

From that moment (date with time-of-day) as seen in that particular time zone, we want only the date for your work. So extract a LocalDate object. And add or swap your for your desired month.

LocalDate ld = zdt.toLocalDate() ;
LocalDate later = ld.withMonth( 3 ) ;  // Or `.plusMonths( 2 ) `.

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), the process of 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….

Joda-Time

Update: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.

The Joda-Time library has a LocalDate class to represent a date-only without a time-of-day nor time zone.

You can arbitrarily set the month value. But beware of the issue that not all months have the same number of days, so having day-of-month values of 29, 30, and 31 are a problem.

LocalDate localDate = new LocalDate( 2014 , 12 , 31 ); // December.
LocalDate localDate_Feb = localDate.withMonthOfYear( 2 ); // February.

Dump to console.

System.out.println( "localDate: " + localDate );
System.out.println( "localDate_Feb: " + localDate_Feb ); 

When run.

localDate: 2014-12-31
localDate_Feb: 2014-02-28
like image 30
Basil Bourque Avatar answered Dec 25 '22 23:12

Basil Bourque