Search code examples
javaandroiddatetimejodatimeandroid-jodatime

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 GMT+02:00 2020 instead of Dec 19. 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?


Solution

  • 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;
    
    public class Main {
        public static void main(String[] args) {
            DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");
            DateTime dateTime = 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 days
            DateTime dateTimeAfter103Days = dateTime.plusDays(103);
            System.out.println(dateTimeAfter103Days);
            System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));
        }
    }
    

    Output:

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

    I recommend you use the modern java.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;
    
    public class Main {
        public static void main(String[] args) {
            // Define formatter for your date-time string
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O u");
    
            // Parse the given date0-time string into OffsetDateTime object
            OffsetDateTime dateTime = OffsetDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
            System.out.println(dateTime);
    
            // Add 103 days to the OffsetDateTime object
            OffsetDateTime dateTimeAfter103Days = dateTime.plusDays(103);
            System.out.println(dateTimeAfter103Days);
        }
    }
    

    Output:

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

    Alternatively,

    import java.time.LocalDateTime;
    import java.time.OffsetDateTime;
    import java.time.ZoneOffset;
    import java.time.format.DateTimeFormatter;
    
    public class Main {
        public static void main(String[] args) {
            // Define formatter for your date-time string
            DateTimeFormatter formatter = 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
            // LocalDateTime
            LocalDateTime dateTime = 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 LocalDateTime
            OffsetDateTime odt = dateTime.atOffset(ZoneOffset.ofHours(3));
            System.out.println(odt);
    
            // Add 103 days to the LocalDateTime object
            LocalDateTime dateTimeAfter103Days = dateTime.plusDays(103);
            System.out.println(dateTimeAfter103Days);
    
            odt = dateTimeAfter103Days.atOffset(ZoneOffset.ofHours(3));
            System.out.println(odt);
        }
    }
    

    Output:

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