228 votes

Comment utiliser ThreeTenABP dans un projet Android

Je suis en train d'utiliser Android Studio 2.1.2 et ma configuration Java est la suivante :

>java -version
> openjdk version "1.8.0_91"
> OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~15.10.1-b14)
> OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

J'ai cherché pendant des heures pour essayer de comprendre cela. La réponse est venue d'une combinaison de réponses connexes, alors j'ai décidé de documenter ce que j'ai appris pour toute personne d'autre qui pourrait être en difficulté. Voir réponse.

228voto

kael Points 3063

Première Découverte: Pourquoi Vous devez Utiliser ThreeTenABP au Lieu de java.temps, ThreeTen-Backport, ou même Joda-Time

C'est vraiment une version courte de la TRÈS LONG PROCESSUS de définition d'un nouveau standard. Tous ces packages sont à peu près la même chose: les bibliothèques qui offrent un bon, à l'époque moderne fonctionnalité de gestion pour Java. Les différences sont subtiles, mais importantes.

La solution la plus évidente serait d'utiliser le haut- java.time forfait, puisque c'est le nouveau standard de la façon de traiter avec le temps et les dates en Java. C'est une implémentation de la JSR 310, qui a été un nouveau projet de norme pour la gestion du temps basé sur le Joda-Time de la bibliothèque.

Toutefois, java.time a été introduite dans Java 8. Android jusqu'à la Guimauve s'exécute sur l'île de Java 7 ("Android N" est la première version d'introduire Java 8 fonctionnalités de langage). Donc, sauf si vous êtes seulement en ciblant Android N Nougat et au-dessus, vous ne pouvez pas compter sur Java 8 fonctionnalités de la langue (je ne suis pas vraiment sûr que c'est 100% vrai, mais c'est la façon dont je le comprends). Donc, java.time .

L'option suivante peut être Joda-Time, depuis JSR 310 a été basée sur Joda-Time. Cependant, comme le ThreeTenABP readme indique que, pour un certain nombre de raisons, Joda-Time n'est pas la meilleure option.

La prochaine est ThreeTen-Backport, arrière-ports beaucoup (mais pas tous) de Java 8 java.time de la fonctionnalité de Java 7. C'est très bien pour la plupart des cas, mais, comme indiqué dans le ThreeTenABP readme, il a des problèmes de performances avec Android.

Ainsi, la dernière et apparemment correcte option est ThreeTenABP.

Deuxième Découverte: Outils de construction et de Gestion de la Dépendance

Depuis la compilation d'un programme-en particulier à l'aide d'un tas de bibliothèques externes -- est complexe, Java presque invariablement utilise un "outil" pour gérer le processus. Faire, Apache Ant, Apache Maven, et Gradle sont tous les outils de construction qui sont utilisés avec des programmes Java (voir ce post pour les comparaisons). Comme indiqué plus bas, Gradle est choisie outil de construction pour Android des projets.

Ces outils comprennent la gestion de la dépendance. Apache Maven semble être le premier à inclure une centralisation de dépôt de paquets. Maven a introduit le Dépôt Central de Maven, ce qui permet des fonctionnalités équivalentes à php composer avec Packagist et de Rubis gem avec rubygems.org. En d'autres termes, le Dépôt Central de Maven est à Maven (et Gradle) ce Packagist est-à-compositeur -- définitive et sûre source pour de version des paquets.

Troisième Découverte: Gradle Gère les Dépendances dans les Projets Android

En haut de ma liste à faire est de lire le Gradle docs ici, y compris leurs eBooks gratuits. Si j'avais lu ces semaines quand j'ai commencé à apprendre Android, je l'aurait sûrement connu que Gradle pouvez utiliser le Dépôt Central de Maven pour gérer les dépendances dans Android des Projets. En outre, comme détaillé dans ce StackOverflow réponse, comme d'Android Studio 0.8.9, Gradle utilise Maven Central Référentiel implicitement à travers Bintray de JCenter, ce qui signifie que vous n'avez pas à faire toute supplémentaire config pour configurer le repo-vous juste la liste des dépendances.

Quatrième de Découverte: les Dépendances d'un Projet Sont Énumérés dans le [projet dir]/app/build.gradle

Encore une fois, évident pour ceux qui ont une expérience d'utilisation de Gradle en Java, mais il m'a fallu un certain temps pour comprendre cela. Si vous voyez des gens qui disent "Oh, il suffit d'ajouter compile 'this-or-that.jar'" ou quelque chose de similaire, à savoir qu' compile est une directive dans ce build.gradle fichier qui indique au moment de la compilation des dépendances. Voici l'officiel Gradle page sur la gestion de la dépendance.

Cinquième de la Découverte: ThreeTenABP Est Géré par Jake Wharton, pas par ThreeTen

Encore une autre question j'ai passé trop de temps à essayer de comprendre. Si vous recherchez ThreeTen dans Maven Central, vous ne pourrez voir que les paquets pour threetenbp, pas threetenabp. Si vous allez sur le dépôt github pour ThreeTenABP, vous verrez que infâme compile 'this-or-that' ligne sous la section Téléchargement de ce fichier.

Quand j'ai touché ce dépôt github, je ne savais pas ce que la ligne de compilation, et j'ai essayé dans mon terminal (avec une évidente et prévisible échec). Frustré, je n'ai pas de retour jusqu'à ce que longtemps après que j'ai compris le reste, et finalement rendu compte que c'est un Repo Maven ligne pointant vers l' com.jakewharton.threetenabp repo, par opposition à l' org.threeten des pensions. C'est pourquoi j'ai pensé à la ThreeTenABP paquet n'était pas dans le repo Maven.

Résumé: pour le Faire fonctionner

Maintenant, tout cela semble assez facile. Vous pouvez obtenir des temps modernes de la manipulation des fonctions dans un projet Android en vous assurant que votre [project folder]/app/build.gradle le fichier a l' compile 'com.jakewharton.threetenabp:threetenabp:1.0.3' ligne dans son dependencies section:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "me.ahuman.myapp"
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:23.4.0'
    implementation 'com.android.support:design:23.4.0'
    implementation 'com.jakewharton.threetenabp:threetenabp:1.0.3'
}

1 votes

Merci pour le super article. Cependant, je me demande si vous avez considéré JodaTimeAndroid aussi.

0 votes

@Bob, je n'ai pas encore expérimenté JodaTimeAndroid, mais simplement parce que je ne travaille pas vraiment sur quelque chose en ce moment qui le nécessite. De ce dont je me souviens, l'implémentation java.time était bonne (étant essentiellement un port de JodaTime), et je suis sûr qu'en un an ou deux, 90% des utilisateurs seront sur Nougat+, en faisant une solution viable pour le développement.

2 votes

@Bob, JodaTime est essentiellement la même chose que JSR-310 (même fabriqué essentiellement par les mêmes personnes), sauf que JSR-310 aurait soi-disant moins de défauts de conception (voir cet article, par exemple). [...suite ci-dessous]

16voto

Basil Bourque Points 8938

La Réponse acceptée par kael est correcte. En outre, je mentionnerai quelques éléments et fournirai un diagramme sur l'obtention de la fonctionnalité java.time.

java.time intégré dans Android 26+

Si vous visez Android 26 ou une version ultérieure, vous trouverez une implémentation de JSR 310 (classes java.time) incluse dans Android. Pas besoin d'ajouter ThreeTenABP.

APIs presque identiques

Juste pour clarifier, ThreeTenABP pour Android est une adaptation de la bibliothèque ThreeTen-Backport qui apporte la plupart des fonctionnalités java.time à Java 6 et Java 7. Ce backport partage une API presque identique avec java.time.

Supposons que vous ciblez maintenant une version d'Android antérieure à 26, donc vous utilisez ThreeTenABP. Plus tard, vous pourrez éventuellement abandonner le support pour ces anciennes versions d'Android, pour utiliser les classes java.time incluses dans Android. Lorsque cela se produira, vous devrez apporter quelques modifications à votre code autre que (a) changer les instructions import, et (b) modifier les appels que vous avez faits à org.threeten.bp.DateTimeUtils pour utiliser les nouvelles méthodes de conversion qui ont été ajoutées aux anciennes classes date-heure (Date, GregorianCalendar).

Le processus de transition de ThreeTenABP vers java.time devrait être fluide et presque sans douleur.

Quand utiliser quel framework

Voici un tableau montrant les trois frameworks, et indiquant quand utiliser chacun d'eux dans quels scénarios.

Mise à jour : Android Gradle Plugin 4.0.0+ apporte une nouvelle 4ème option, désucre des API pour rendre disponible un sous-ensemble de la fonctionnalité java.time initialement non intégrée dans les anciennes versions d'Android. Voir le haut de la Réponse principale de kael.

Tableau indiquant quelle bibliothèque java.time utiliser avec quelle version de Java ou Android


À propos de java.time

Le framework java.time est intégré dans Java 8 et ultérieure. Ces classes remplacent les anciennes classes date-heure problématiques telles que java.util.Date, Calendar, & SimpleDateFormat.

Pour en savoir plus, consultez le Tutoriel Oracle. Et cherchez sur Stack Overflow de nombreux exemples et explications. La spécification est JSR 310.

Le projet Joda-Time, désormais en mode de maintenance, recommande la migration vers les classes java.time.

Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC conforme à JDBC 4.2 ou ultérieur. Pas besoin de chaînes, pas besoin des classes java.sql.*. Hibernate 5 & JPA 2.2 prennent en charge java.time.

Où obtenir les classes java.time ?

11voto

eLi Points 558

Cette solution couvre tout le ThreeTenABP de l'installation à l'utilisation.

Le projet Open Event Android aide les organisateurs d'événements à organiser l'événement et à générer des applications (format apk) pour leurs événements/conférences en fournissant un point de terminaison API ou un zip généré à l'aide du serveur Open Event. Pour toute application d'événement, il est très important de gérer correctement le fuseau horaire. Dans l'application Android Open Event, il y a une option pour modifier le paramètre du fuseau horaire. L'utilisateur peut voir la date et l'heure de l'événement et des sessions dans le fuseau horaire de l'événement et le fuseau horaire local dans l'application. ThreeTenABP fournit un backport des classes de date et d'heure de Java SE 8 vers Java SE 6 et 7. Dans cet article de blog, j'explique comment utiliser ThreeTenABP pour la gestion des fuseaux horaires sur Android.

1. Ajouter la dépendance

Pour utiliser ThreeTenABP dans votre application, vous devez ajouter la dépendance dans le fichier build.gradle de votre module d'application.

dependencies {
      compile    'com.jakewharton.threetenabp:threetenabp:1.0.5'
      testCompile   'org.threeten:threetenbp:1.3.6'
}

2. Initialiser ThreeTenABP
Maintenant, dans la méthode onCreate() de la classe Application, initialisez ThreeTenABP.

AndroidThreeTen.init(this);

3. Créer la méthode getZoneId()
Créez d'abord la méthode getZoneId() qui renverra ZoneId en fonction des préférences de l'utilisateur. Cette méthode sera utilisée pour formater et analyser les dates ici showLocal est la préférence de l'utilisateur. Si showLocal est vrai, cette fonction renverra Default local ZoneId sinon ZoneId de l'événement.

private static ZoneId geZoneId() {
        if (showLocal || Utils.isEmpty(getEventTimeZone()))
            return ZoneId.systemDefault();
        else
            return ZoneId.of(getEventTimeZone());
}

Ici, la méthode getEventTimeZone() renvoie la chaîne de fuseau horaire de l'événement.

ThreeTenABP a principalement deux classes représentant la date et l'heure.
- ZonedDateTime : ‘2011-12-03T10:15:30+01:00[Europe/Paris]’
- LocalDateTime : ‘2011-12-03T10:15:30’

ZonedDateTime contient des informations sur le fuseau horaire à la fin. LocalDateTime ne contient pas de fuseau horaire.

4. Créer une méthode pour l'analyse et le formatage
Créez maintenant la méthode getDate() qui prendra une chaîne isoDateString et renverra un objet ZonedDateTime.

public static ZonedDateTime getDate(@NonNull String isoDateString) {
        return ZonedDateTime.parse(isoDateString).withZoneSameInstant(getZoneId());;

Créez la méthode formatDate() qui prend deux arguments : le premier est une chaîne de format et le deuxième est une chaîne isoDateString. Cette méthode renverra une chaîne formatée.

public static String formatDate(@NonNull String format, @NonNull String isoDateString) {
        return DateTimeFormatter.ofPattern(format).format(getDate(isoDateString));
}

5.Analyse :
String isoDateString = "2017-11-09T23:08:56+08:00";

DateConverter.setEventTimeZone("Asia/Singapore");
DateConverter.setShowLocalTime(false);
ZonedDateTime dateInEventTimeZone = DateConverter.getDate(isoDateString);

dateInEventTimeZone.toString();  //2017-11-09T23:08:56+08:00[Asia/Singapore]

TimeZone.setDefault(TimeZone.getDefault());
DateConverter.setShowLocalTime(true);
ZonedDateTime dateInLocalTimeZone = DateConverter.getDate(dateInLocalTimeZone);

dateInLocalTimeZone.toString();  //2017-11-09T20:38:56+05:30[Asia/Kolkata]

Formatage :

String date = "2017-03-17T14:00:00+08:00";
String formattedString = formatDate("dd MM YYYY hh:mm:ss a", date));

formattedString // "17 03 2017 02:00:00 PM"

Source :

8voto

Richard Kamere Points 428

Ajoutez ce qui suit dans votre fichier gradle de construction (niveau du module) dans Android Studio :

implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'

Créez la classe Application et initialisez-la comme suit :

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X