Joda time plus

Sep 07 2020

J'utilise ce code:

 DateTime(date)//Thu Aug 06 00:00:00 GMT+03:00 2020
                .plusDays(days) // 103
                .toDate()

Et le résultat est Fri Dec 18 23:00:00 GMT+02:00 2020au lieu de Dec 19. Avec certaines dates ça marche bien, avec d'autres le résultat date-1, je suppose que le problème est avec le nombre de jours dans le mois, mais ne le plusDays()considère pas?

Réponses

2 LiveandLetLive Sep 07 2020 at 09:32

Avec certaines dates, cela fonctionne bien, avec d'autres le résultat date-1, je suppose que le problème est avec le nombre de jours dans le mois, mais est-ce que plusDays () ne le considère pas?

Il le considère. Le problème avec les deux chaînes date-heure que vous avez mentionnées est qu'elles appartiennent à un décalage de zone différent (le premier est avec UTC + 3 et le second avec UTC + 2). Vous trouverez ci-dessous comment le faire avec le même décalage de zone.

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)));
    }
}

Production:

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

Je vous recommande d'utiliser l' API date-heure moderne java.time et l'API de mise en forme correspondante (package, java.time.format). Pour en savoir plus sur l'API date-heure moderne, consultez Trail: Date Time . Si votre niveau d'API Android n'est toujours pas compatible avec Java8, consultez Comment utiliser ThreeTenABP dans Android Project et les API Java 8+ disponibles via le désugarage .

Le tableau suivant présente un aperçu des classes date-heure modernes :

Avec l'API date-heure moderne:

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);
    }
}

Production:

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

Alternativement,

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);
    }
}

Production:

2020-08-06T00:00
2020-08-06T00:00+03:00
2020-11-17T00:00
2020-11-17T00:00+03:00
3 deHaar Sep 07 2020 at 09:33

Vous pouvez l'utiliser java.timeet il est pris en charge dans les API Android inférieures, car il existe maintenant des API de désucidation dans Android .

Il existe une classe sensible à la zone ( java.time.ZonedDateTime) et une classe sensible au décalage ( java.time.OffsetDateTime), mais votre exemple Stringcontient simplement un décalage par rapport à GMT / UTC. C'est pourquoi j'utiliserais un OffsetDateTimequi analyse le moment exact dans le temps, puis ajoute un jour.

Voici un exemple simple qui définit un formateur qui analyse le donné Stringet l'utilise pour la sortie:

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

Cette sortie

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

Si vous êtes intéressé par la sortie de dates uniquement (pas de partie de temps ni de décalage), il y a une autre chose pratique dans ces classes, c'est l'extraction facile de la partie de la date ou de l'heure. Vous pouvez faire ce qui suit avec un OffsetDateTime, par exemple:

// 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)
                    )
);

Cela produirait

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

Si vous avez affaire à un DatePicker datePicker, vous pouvez recevoir des valeurs sélectionnées par getYear(), getMonth()et getDayOfMonth(), puis créer un

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

puis ajoutez simplement un jour par localDate.plusDays(1);