1

Hi i am trying to get the current year in the below code however it is returning a 1970 year instead of 2020 last month this was working correctly but since we in January 2020, it is now returning a date from 1970, please assist

  public String firstDateOfNextMonth(){
      DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      Calendar today = Calendar.getInstance();
      Calendar next = Calendar.getInstance();
      today.clear();
      Date date;

      next.clear();
      next.set(Calendar.YEAR, today.get(Calendar.YEAR));
      next.set(Calendar.MONTH, today.get(Calendar.MONTH)+ 1);
      next.set(Calendar.DAY_OF_MONTH, 1);


      date = next.getTime();

      Log.d(TAG, "The Date: " + dateFormat.format(date));
      return  dateFormat.format(date);

  }
  • 1
    Assuming that you are coding for Android, consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use `java.time`, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Jan 03 '20 at 22:10

6 Answers6

5

If you have Java 8 or above, then you have java.time and you won't have to rely on outdated datetime implementations and you can do it this way:

public static String getFirstOfNextMonth() {
    // get a reference to today
    LocalDate today = LocalDate.now();
    // having today, 
    LocalDate firstOfNextMonth = today
            // add one to the month
            .withMonth(today.getMonthValue() + 1)
            // and take the first day of that month
            .withDayOfMonth(1);
    // then return it as formatted String
    return firstOfNextMonth.format(DateTimeFormatter.ISO_LOCAL_DATE);
}

which prints the following when called today (2020-01-03) like System.out.println(getFirstOfNextMonth());:

2020-02-01

You might have to involve an external library, the ThreeTenAbp if you want it to work in Android below API level 26. Its use is explained in this question.

deHaar
  • 17,687
  • 10
  • 38
  • 51
  • 2
    It’s not only a lot shorter, it’s first and foremost a lot clearer than the code in the question. Thanks. In the department of tiny details, my version might be `YearMonth.now(ZoneId.systemDefault()).plusMonths(1).atDay(1).toString()`, – Ole V.V. Jan 03 '20 at 22:15
3

tl;dr

LocalDate                             // Represent a date-only value without a time-of-day and without a time zone.
.now(                                 // Determine the current date as seen through the wall-clock time used by people in certain region (a time zone).
    ZoneId.of( "America/Montreal" )   // Real time zone names have names in the format of `Continent/Region`. Never use 2-4 letter pseudo-zones such as `IST`, `PST`, or `CST`, which are neither standardized nor unique.
)                                     // Return a `LocalDate`.
.with(                                // Move from one date another by passing a `TemporalAdjuster` implementation.
    TemporalAdjusters                 // Class providing several implementations of `TemporalAdjuster`.
    .firstDayOfNextMonth()            // This adjuster finds the date of the first of next month, as its name suggests.
)                                     // Returns another `LocalDate` object. The original `LocalDate` object is unaltered.
.toString()                           // Generate text in standard ISO 8601 format of YYYY-MM-DD.

See this code run live at IdeOne.com.

2020-02-01

Details

You are using terrible date-time classes that were made obsolete years ago by the unanimous adoption of JSR 310 defining the java.time classes.

Table of date-time types in Java, both modern and legacy

The Answer by deHaar is correct. Here is an even shorter solution.

TemporalAdjuster

To move from one date to another, the java.time classes include the TemporalAdjuster interface. Pass one of these objects to the with method found on many of the other java.time classes.

TemporalAdjusters.firstDayOfNextMonth()

Several implementations of that interface are found in the class TemporalAdjusters (note the s plural). One of those is firstDayOfNextMonth(), just what you need.

Get today's date. A time zone is required, as for any given moment the date varies around the globe by time zone. If omitted, your JVM's current default time zone is implicitly applied. Better to be explicit.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate today = LocalDate.now( z ) ;

Get your TemporalAdjuster object.

TemporalAdjuster ta = TemporalAdjusters.firstDayOfNextMonth() ;

Apply that adjuster to get another LocalDate object. Note that java.time classes are immutable by design. So we get a new object rather than altering the original.

LocalDate firstOfNextMonth = today.with( ta ) ;

We can shorten this code to a one-liner, if desired.

LocalDate firstOfNextMonth = 
        LocalDate
        .now( 
            ZoneId.of( "Africa/Tunis" ) 
        )
        .with(
            TemporalAdjusters.firstDayOfNextMonth()
        )
;

Text

Your desired output format of YYYY-MM-DD complies with the ISO 8601 standard used by default in the java.time classes when parsing/generating text. So no formatting pattern need be specified.

String output = firstOfNextMonth.toString() ;

2020-02-01


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?

Table of which java.time library to use with which version of Java or Android

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
2

not sure why the today date gets cleared, remove today.clear() at line 4

Beppe C
  • 11,256
  • 2
  • 19
  • 41
2

today.clear(); initalize all elements of a date with the value 0 removing this line will give you the right answer

FredvN
  • 504
  • 1
  • 3
  • 14
0

You are using Calendar.clear() which clears all the fields of your calendar, and essentially reverts it to 1/1/1970 (epoch time 0).

remove today.clear() and you'll get the correct answer

see more here

Nir Levy
  • 12,750
  • 3
  • 21
  • 38
0

Remove next.clear();. As Calendar next= Calendar.getInstance(); initiates next with the current date, in your cases Fri Jan 03 2020 15:07:53. And when you do next.clear(), it sets to the inital epoch.

Epoch, also known as Unix timestamps, is the number of seconds (not milliseconds!) that have elapsed since January 1, 1970 at 00:00:00 GMT (1970-01-01 00:00:00 GMT).

sankalpvk18
  • 130
  • 1
  • 6