`uuuu 'contre `yyyy 'dans' DateTimeFormatter ' formatage des codes de modèle en Java?


Le DateTimeFormatter la documentation de la classe dit à propos de ses codes de formatage pour l'année:

U année année 2004; 04

Y année de l'ère année 2004; 04

Année: Le nombre de lettres détermine la largeur minimale du champ en dessous de laquelle le remplissage est utilisé. Si le nombre de lettres est de deux, une forme réduite à deux chiffres est utilisée. Pour l'impression, ce sorties la droite deux chiffres. Pour l'analyse, cela analysera en utilisant la valeur de base de 2000, ce qui donne une année comprise entre 2000 et 2099 inclus. Si le nombre de lettres est inférieur à quatre (mais pas deux), le signe n'est sorti que pour les années négatives selon SignStyle.NORMAL. Sinon, le signe est sorti si la largeur du pad est dépassée, selon SignStyle.EXCEEDS_PAD.

Aucune autre mention de "l'ère".

Quelle est Donc la différence entre ces deux codes, u contre y, year contre year-of-era?

Quand dois-je utiliser quelque chose comme ce modèle uuuu-MM-dd et quand yyyy-MM-dd lorsque je travaille avec des dates en Java?

Semble que l'exemple de code écrit par ceux qui sont au courant utilise uuuu, mais pourquoi?

Autres classes de mise en forme telles que l'héritage SimpleDateFormat ont seulement yyyy, donc je suis confus pourquoi java.le temps apporte ce uuuu pour "année de l'ère".

Author: Basil Bourque, 2016-12-16

3 answers

Dans le cadre de java.time-package, nous pouvons dire:

  • Il est plus sûr d'utiliser "u" au lieu de "y" parce que DateTimeFormatter insistera sinon pour avoir une ère en combinaison avec " y " (=année de l'ère). Ainsi, l'utilisation de " u " éviterait certaines exceptions inattendues possibles dans un formatage/analyse strict. Voir aussi ce , DONC post. Une autre chose mineure qui est améliorée par le symbole"u" par rapport à "y" est l'impression / l'analyse des années grégoriennes négatives (en loin passé).

  • Sinon, nous pouvons clairement affirmer queutiliser "u" au lieu de "y" brise les habitudes de longue date en programmation Java . Il n'est pas non plus intuitivement clair que "u" désigne tout type d'année car a) la première lettre du mot anglais "year" n'est pas en accord avec ce symbole et b) SimpleDateFormat a utilisé "u" dans un but différent depuis Java-7 (ISO-day-number-of-week). La confusion est garantie-pour toujours?

  • Nous devrions également voir que l'utilisation d'époques (symbole "G") dans le contexte de l'ISO est en général dangereuse si l'on considère les dates historiques . Si "G "est utilisé avec" u", les deux champs ne sont pas liés l'un à l'autre. Et si "G "est utilisé avec" y", le formateur est satisfait mais utilise toujours le calendrier grégorien proleptique lorsque la date historique impose différents calendriers et la gestion de la date.

Renseignements généraux:

Lors du développement et de l'intégration du JSR 310 (java.time-paquets) le les concepteurs ont décidé d'utiliser Common Locale Data Repository (CLDR)/LDML-spec comme base des symboles de motif dans DateTimeFormatter. Le symbole "u" était déjà défini dans CLDR comme année grégorienne proleptique, donc cette signification a été adoptée pour le nouveau JSR-310 à venir (mais pas pour SimpleDateFormat pour des raisons de rétrocompatibilité).

Cependant, cette décision de suivre CLDR n'était pas tout à fait cohérente car JSR-310 avait également introduit de nouveaux symboles de motif qui n'existaient pas et n'existent toujours pas dans CLDR, voir aussi ceci vieux - CLDR billet. Le symbole suggéré "I" a été changé par CLDR en "VV" et finalement dépassé par JSR-310, y compris nouveaux symboles "x" et "X". Mais" n "et" N " n'existent toujours pas dans CLDR, et puisque cet ancien ticket est fermé, il n'est pas clair du tout si CLDR le supportera jamais dans le sens de JSR-310. De plus, le ticket ne mentionne pas le symbole "p" (instruction de remplissage dans JSR-310, mais non définie dans CLDR). Nous n'avons donc toujours pas d'accord parfait entre le motif définitions dans différentes bibliothèques et langues.

Et à propos de "y": Il ne faut pas non plus négliger le fait que CLDR associe cette année de l'ère à au moins une sorte d'année mixte Julien/grégorien et non à l'année grégorienne proleptique comme le fait JSR-310 (laissant de côté la bizarrerie des années négatives). Donc pas d'accord parfait entre CLDR et JSR-310 ici aussi.

 41
Author: Meno Hochschild, 2020-07-02 05:30:43

Dans la section javadoc Patterns pour le formatage et l'analyse pour DateTimeFormatter, il répertorie les 3 symboles pertinents suivants:

Symbol  Meaning        Presentation  Examples
------  -------        ------------  -------
 G       era            text          AD; Anno Domini; A
 u       year           year          2004; 04
 y       year-of-era    year          2004; 04

Juste pour comparaison, ces autres symboles sont assez faciles à comprendre:

 D       day-of-year    number        189
 d       day-of-month   number        10
 E       day-of-week    text          Tue; Tuesday; T

Le day-of-year, day-of-month, et day-of-week sont les jour à l'intérieur de l'étendue donnée (année, mois, semaine).

Donc, year-of-era signifie l'année dans la portée donnée (era), et juste au-dessus era est montré avec une valeur d'exemple de AD (l'autre valeur étant bien sûr BC).

year est le signée année, lorsque l'année 0 est 1 BC, year -1 est 2 BC, et ainsi de suite.

Pour illustrer: Quand Jules César a-t-il été assassiné ?

  • , le 15 Mars 44 avant j.-c. (utilisant le modèle MMMM d, y GG)
  • 15 mars -43 (en utilisant le motif MMMM d, u)

La distinction n'aura bien sûr d'importance que si l'année est nulle ou négative, et comme c'est rare, la plupart des gens s'en moquent, même bien qu'ils le devraient.

Conclusion: Si vous utilisez y, vous devez également utiliser G. Comme G est rarement utilisé, le symbole correct de l'année est u, pas y, sinon une année non positive s'affichera incorrectement.

Ceci est connu comme défensive de programmation:

La programmation défensive est une forme de conception défensive destinée à assurer le fonctionnement continu{[58] } d'un logiciel en cas d'imprévu circonstances.


Remarque que DateTimeFormatter est cohérente avec SimpleDateFormat:

Letter  Date or Time Component  Presentation  Examples
------  ----------------------  ------------  --------
G       Era designator          Text          AD
y       Year                    Year          1996; 96

Les années négatives ont toujours été un problème, et ils l'ont maintenant corrigé en ajoutant u.

 28
Author: Andreas, 2016-12-16 06:22:48

Longue histoire courte

  1. Dans 99% des cas, vous pouvez lancer une pièce, cela ne fera aucune différence si vous utilisez yyyy ou uuuu (ou si vous utilisez yy ou uu pour une année à 2 chiffres).
  2. Cela dépend de ce que vous voulez arriver au cas où un an plus tôt que 1 CE (1 AD) se produirait. Le fait est que dans 99% des programmes, une telle année ne se produira jamais.

Deux autres réponses ont déjà présenté les faits de la façon dont u et y fonctionnent très bien, mais je me sentais toujours il manquait quelque chose, donc je contribue à la réponse légèrement plus basée sur l'opinion.

Pour le formatage

En supposant que vous ne vous attendez pas à ce que 1 CE soit formaté un an avant, la meilleure chose à faire est de vérifier cette hypothèse et de réagir de manière appropriée au cas où elle se briserait. Par exemple, selon les circonstances et les exigences, vous pouvez imprimer un message d'erreur ou lancer une exception. Un très doux échec chemin d'accès peut être d'utiliser un modèle avec y (année de l'ère) et G (ère) en ce cas et un modèle avec u ou y dans le cas normal et actuel de l'ère. Notez que si vous imprimez la date actuelle ou la date à laquelle votre programme a été compilé, vous pouvez être sûr qu'il est dans l'ère commune et peut choisir d'ignorer la vérification.

Pour l'analyse

Dans beaucoup (la plupart?) l'analyse des cas signifie également la validation, ce qui signifie que vous n'avez aucune garantie à quoi ressemble votre chaîne d'entrée. Généralement il s'agit de l'utilisateur ou d'un autre système. Un exemple: une chaîne de date se présente sous la forme 2018-09-29. Ici, le choix entre uuuu et yyyy devrait dépendre de ce que vous voulez arriver dans le cas où la chaîne contient une année de 0 ou négative (par exemple, 0000-08-17 ou -012-11-13). En supposant que ce serait une erreur, la réponse immédiate est: utilisez yyyy pour qu'une exception soit levée dans ce cas. Encore plus fin: utilisez uuuu et après l'analyse, effectuez une vérification de la plage de la date analysée. Cette dernière approche permet à la fois une validation plus fine et un meilleur message d'erreur en cas de validation erreur.

Cas particulier (déjà mentionné par Meno Hochschild): Si votre formateur utilise un style de résolveur strict et contient y sans G, l'analyse échouera toujours car à proprement parler, l'année de l'ère est ambiguë sans ère: 1950 peut signifier 1950 CE ou 1950 BCE (1950 BC). Donc, dans ce cas, vous avez besoin de u (ou de fournir une ère par défaut, cela est possible via un DateTimeFormatterBuilder).

Longue histoire courte encore

Vérification explicite de la plage de vos dates, en particulier votre ans, c'est mieux que de compter sur le choix entre uuuu et yyyy pour attraper des années inattendues très tôt.

 7
Author: Ole V.V., 2018-08-13 11:23:56