Skip to content Skip to sidebar Skip to footer

Joda Time Plusdays Getting Wrong Date

I am using this code: DateTime(date)//Thu Aug 06 00:00:00 GMT+03:00 2020 .plusDays(days) // 103 .toDate() And the result is Fri Dec 18 23:00:00 GM

Solution 1:

You could use java.time and it is supported in lower Android APIs, because there's API desugaring in Android now.

There's a zone-aware class (java.time.ZonedDateTime) and an offset-aware one (java.time.OffsetDateTime), but your example String just contains an offset from GMT / UTC. That's why I would use an OffsetDateTime that parses the exact moment in time and then adds a day.

Here's a simple example that defines a formatter which parses the given String and uses it for the output:

publicstaticvoidmain(String[] args) {
    // example StringStringdate="Fri Dec 18 23:00:00 GMT+02:00 2020";
    // create a formatter that is able to parse and output the StringDateTimeFormatterdtf= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss OOOO uuuu",
                                                        Locale.ENGLISH);
    // parse the String using the formatter defined aboveOffsetDateTimeodt= OffsetDateTime.parse(date, dtf);
    System.out.println("OffsetDateTime parsed is\t" + odt.format(dtf));
    
    // add a day to the date partOffsetDateTimedayLater= odt.plusDays(1);
    System.out.println("Adding a day results in\t\t" + dayLater.format(dtf));
}

This outputs

OffsetDateTime parsed is    Fri Dec 18 23:00:00 GMT+02:00 2020
Adding a day results in     Sat Dec 19 23:00:00 GMT+02:00 2020

If you are interested in outputting dates only (no time part or offset), there's another handy thing in those classes, that is easy extraction of date- or time-part. You can do the following with an OffsetDateTime, for example:

// extract the part that only holds information about day of month, month of year and year
LocalDate dateOnly = odt.toLocalDate();
// print the default format (ISO standard)
System.out.println(dateOnly);
// or define and use a totally custom format
System.out.println(dateOnly.format(
                        DateTimeFormatter.ofPattern("EEEE, 'the' dd. 'of' MMMM uuuu",
                                                    Locale.ENGLISH)
                    )
);

That would output

2020-12-18
Friday, the 18. of December 2020

In case you are dealing with a DatePicker datePicker, you can receive selected values by getYear(), getMonth() and getDayOfMonth(), then create a

LocalDatelocalDate= LocalDate.of(datePicker.getYear(),
                                   datePicker.getMonth(), 
                                   datePicker.getDayOfMonth());

and then simply add a day by localDate.plusDays(1);

Solution 2:

With some dates it work well, with other the result date-1, I guess the problem is with number of days in month, but does plusDays() not consider it?

It does consider it. The problem with the two date-time strings you have mentioned is that they belong to different Zone-Offset (the first one is with UTC+3 and the second one with UTC+2). Given below is how to do it with the same Zone-Offset.

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

publicclassMain {
    publicstaticvoidmain(String[] args) {
        DateTimeFormatterformatter= DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");
        DateTimedateTime= DateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
        System.out.println(dateTime);
        // With Zone-Offset of UTC+2
        System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));

        // Add 103 daysDateTimedateTimeAfter103Days= dateTime.plusDays(103);
        System.out.println(dateTimeAfter103Days);
        System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));
    }
}

Output:

2020-08-05T21:00:00.000Z2020-08-05T23:00:00.000+02:002020-11-16T21:00:00.000Z2020-08-05T23:00:00.000+02:00

I recommend you use the modernjava.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time. If your Android API level is still not compliant with Java8, check How to use ThreeTenABP in Android Project and Java 8+ APIs available through desugaring.

The following table shows an overview of modern date-time classes: enter image description here

With modern date-time API:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

publicclassMain {
    publicstaticvoidmain(String[] args) {
        // Define formatter for your date-time stringDateTimeFormatterformatter= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O u");

        // Parse the given date0-time string into OffsetDateTime objectOffsetDateTimedateTime= OffsetDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
        System.out.println(dateTime);

        // Add 103 days to the OffsetDateTime objectOffsetDateTimedateTimeAfter103Days= dateTime.plusDays(103);
        System.out.println(dateTimeAfter103Days);
    }
}

Output:

2020-08-06T00:00+03:002020-11-17T00:00+03:00

Alternatively,

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

publicclassMain {
    publicstaticvoidmain(String[] args) {
        // Define formatter for your date-time stringDateTimeFormatterformatter= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");

        // If you do not need Zone Id or Zone Offset information, you can go for// LocalDateTimeLocalDateTimedateTime= LocalDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
        System.out.println(dateTime);

        // You can convert LocalDateTime object into an OffsetDateTime by applying the// Zone-Offset e.g. the following line applies UTC+03:00 hours to LocalDateTimeOffsetDateTimeodt= dateTime.atOffset(ZoneOffset.ofHours(3));
        System.out.println(odt);

        // Add 103 days to the LocalDateTime objectLocalDateTimedateTimeAfter103Days= dateTime.plusDays(103);
        System.out.println(dateTimeAfter103Days);

        odt = dateTimeAfter103Days.atOffset(ZoneOffset.ofHours(3));
        System.out.println(odt);
    }
}

Output:

2020-08-06T00:002020-08-06T00:00+03:002020-11-17T00:002020-11-17T00:00+03:00

Post a Comment for "Joda Time Plusdays Getting Wrong Date"