[Résolu] Date et représentation locale [code Mis À Jour]
Bonjour à tous,
J'ai trois textfields dans lesquels l'utilisateur va mettre des parties de date, j'aimerai mettre en placeholder par exemple pour une représentation française "Jour" dans le premier, "Mois" dans le deuxième et "année" dans le dernier. Mais pour un anglais : "Month", "Day", "Year".
Comment savoir dans quel ordre vont être les jours,mois et année pour la représentation de l'utilisateur ?
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Merci Céroce,
Le problème avec un UIDatePicker c'est qu'il est difficile d'entrer des dates éloignées dans le temps. Mon app est une sorte de quizz, et si la réponse à la question est janvier 1515, ou -15 avant J-C, ca ne le prends pas en compte et un datePicker n'est pas approprié a cause du scroll.
Du coup pour les année j'ai pensé faire un UIPicker avec plusieurs components, un pour les siècle de -30 à 30 et un pour les les dizaines d'année de 00 à 99. Puis éventuellement un date picker pour les jours et les mois, mais malheureusement ça ne m'aide pas pour le placement relatif des années, mois et jours.
Tu peux demander à iOS la langue courante, non ? Et ajuster ton système de saisie en conséquence.
Note que c'est les américains (pas les anglais) qui mettent le mois avant le jour.
Pas du tout sûr que cela soit le mieux, mais:
Compare chaque zzzRange.location
Arg .. maudits britishs (pardon Johanna). Pas mal ton idée, Larme.
Ceci dit, iOS connait 5 versions de la langue anglais :
English (U.S.)
English (India)
English (U.K.)
English (Canada)
English (Australia)
Tu peux tester ça, pour déterminer l'interface à utiliser pour ton quizz.
Merci Larme,
J'avais pensé à faire un truc dans le genre, mais merci pour la comparaison de location, j'avais oublié ça et je comptais me prendre plus le chou. ça résout à priori le problème mais comme toi je ne suis pas sûr que cela soit le mieux, si il y a d'autres solutions je suis preneur, mais merci.
Edit : Et merci pour la précision !
merci Draken, à priori j'ai fais quelques tests et c'est toujours bon grâce à la current local, pas de test à faire, ça me donne direct le bon ordre. Encore une fois nickel le bout de code Larme, j'aurai fais ça différemment mais ta manière de faire est vraiment plus courte !
- Le japon compte les années d'après l'empereur courant. 2016 ça n'a pas de sens pour eux. Au Japon nous sommes en année Heisei 28.
- Dans le calendrier Japonais, une année ne commence pas forcément le premier janvier. Elle commence à la mort d'un empereur et l'arrivée de son successeur. Les années ne durent donc pas forcément 365 jours, certaines durent 6 jours, comme ça a été le cas en 1926 à l'ère Shoewa
- Le calendrier Islamique est lunaire, et les mois sont basées sur les phases de la lune. Du coup le nombre de jours dans un mois est très variable
- Le calendrier Hébreu est lunisolaire. Cela veut dire que le concept "d'année" (= dans notre calendrier, c'est le temps que met la terre pour faire un tour complet autour du soleil) ou de jour (= le temps que met la terre pour faire un tour sur elle-même) n'est pas le même dans le calendrier Hébreu
- Toujours dans le calendrier Hébreu, à l'image de notre 29 février qu'on rajoute tous les 4 ans ou presque, eux ils rajoutent... un mois entier (Adar I) 7 années sur 19, en plein milieu de l'année.
- Du coup avec tout ça, certaines dates qui peuvent sembler valide ne le sont en fait pas. Par exemple le 8 Janvier de l'année 64 Shoewa n'a jamais existé et n'est pas une date valide.
Et ce ne sont que quelques exemples choisis parmi tant d'autres...Du coup tu vois bien que si tu cherche à implémenter un DatePicker-like toi-même, tu t'amuserais bien avec ce genre de cas tordus...
Plus d'infos sur le blog de Dave Delong, le développeur Apple qui a implémenté UIDatePicker dans iOS : http://davedelong.tumblr.com/post/140216824433/intercalation
Laisse tomber l'idée d'un UiDatePicker et crée un composant graphique personnalisé à usage unique, pour sélectionner les dates. Tu t'en fiches d'afficher des dates impossibles, puisque c'est un quizz avec forcément du vrai et du faux. Tu peux utiliser des UICollectionView pour ça, avec un scrolling vertical pour faire défiler les éléments de date.
A noter que Ali oublie de parler du calendrier maya basé sur des cycles revenants à intervalles réguliers, comme le pictun (7.800 ans), le calabtun (157.000 ans), l'alautun (63 millions d'années) et le hablatun (un milliard d'années). De grands optimistes ces mayas..
ok draken, mais j'avoue ne pas trop voir où tu veux en venir avec la UICollectionView, j'ai du mal à voir comment on peut représenter des dates dans une collectionView... Un léger croquis même sommaire serait bien utile s'il te plais ! Sinon pour la selection facile de l'année, même pour les langues qui ont un calendrier différent, je pourrai mettre un UITextField et permettre à l'utilisateur d'écrire une année et faire scroller le datePicker jusqu'à l'année écrite.
Par contre Ali, pourquoi quand je demande le monthSymbols.count sur un NSDateFormatter il me donne 12 quelque soit la locale choisie ? D'après les explications données plus haut, je devrais avoir un mois de plus quand c'est en hébreux et sur la bonne année ? Pareil pour l'année, j'ai beau crée une date et la traduire en Japonnais ou en hébreux, il y a toujours marqué 2016.
// Par exemple dans le playground :
Edit : En fait quand j'affiche un datePicker avec comme locale Japanese ou Hebrew, ca me donne les mêmes résultats que quand je print les monthSymbol. Je suppose donc que tout va bien.
Edit 2 : le problème de 2016 et du nombre de mois venait des réglages du calendrier dans les settings de l'iPhone, comme Ali le suggère sur une autre discussion ici.
Une UICollectionView permet de faire défiler des cellules avec un contenu personnalisé, comme une UITableView en plus évoluée.
Tu pourrais en avoir plusieurs sur ton écran, pour faire scroller les éléments constitutifs de ta date :
- Une pour les jours (avec 31 case)
- Une pour les mois (avec 12 cases)
Et 4 collectionViews pour la date, pour chaque digit.
- Un pour les milliers allant de -2 à +2 (si ton échelle varie entre -2999 ans et + 2999 ans)
- Un pour les siècles allant de 0 à 9
- Un pour les dizaines (0 à 9)e
- Un pour les unités (0 à 9)
Tu peux aussi faire évoluer l'interface en fonction de la question, ou restreindre l'échelle temporelle. Par exemple si la question porte sur la seconde guerre mondiale, la réponse est forcément comprise en 1939 et 1945. Ou sur l'histoire de la musique au XX° siècle, c'est après 1900, etc ..
A mon avis il est préférable, pour un quizz, d'afficher le nom des mois plutôt qu'un simple chiffre. On a tous appris en cours d'histoire que le débarquement a eu lieu en Normandie le 11 Juin 1944, et non le 14/07/1944. La mémoire humaine fonctionne de manière symbolique et non littérale.
Je joins à ce topic l'image d'un minuteur (version Mac). C'est le même principe, avec quelques effets de lumière pour donner une impression de relief. Il n'y a que 3 barres (heure/minute/seconde), mais l'idée est là .
L'exemple le plus parlant, pour un parisien (ou un chinois), c'est de parler du nouvel an chinois qui se produit entre le 21 Janvier et le 20 Février (calendrier luni-solaire, basé sur le cycle solaire et les phases de la lune). Il y a toujours une foule monstre pour assister au spectacle dans les rues du quartier chinois de Paris (13e arrondissement).
Ok Draken, super ! Merci pour ton aide aide et l'illustration, c'est top ! Je connais bien les collectionView, et j'hésitais justement à te demander si par hasard tu ne pensais pas plutôt à un pickerView, en tout cas ce comportement est facilement faisable avec, il suffit de faire des components et c'est exactement l'image que tu me montres (on dirait une cellule de collectionView(meme si elle est seule), avec un picker à 3 components, deux boutons et deux labels). Avec des collectionVIew, ça fait peut-être sortir le gros arsenal un peu tôt. Je comprenais mal pourquoi tu voulais mettre plusieurs collectionView mais maintenant c'est parfaitement clair.
Oui pour les mois, c'est ce que je suis entrain de regarder dans toutes les langues et à priori ça va le faire. Je regarde aussi pour ajuster l'affichage avec un segmented control, pareil ca va être facile. Je suis entrain de faire un sample, justement avec des pickerViews, je le posterai ce soir ou demain matin si je n'ai pas fini ce soir. Si jamais le comportement (ou le design) ne me conviens pas je verrais avec des collectionView.
Oui, j'ai écrit n'importe quoi. C'est nettement mieux avec un pickerView. Honte à moi ..
Bonjour à tous,
Alors comme prévu je vous tiens au courant de l'avancé, désolé pour le retard, j'ai peaufiné au maximum car je voulais vous montrer quelque chose de potable et j'ai fais du mieux que j'ai pu.
J'ai pas mal de choses à dire, j'ai pas mal ramé comme le prévoyait Ali .
•J'ai d'abord tenté de tout prendre en compte, mais le calendrier Japonais posait problème, donc j'ai implémentés les méthodes que j'ai mis en commentaire et j'ai disable le segmentedControl qui s'occupe de changer le calendrier dans le storyBoard. En fait je n'arrive pas à déterminer la place de l'ère dans le calendrier Japonais, mais en écrivant ces lignes, je me dis que je pourrais tester dans
si rangeOfString("G") retourne nil ou non, et ainsi adapter le nombre de components dans le picker view.
• Mais il y a quand même une question à laquelle je n'ai pas trouvé de réponse; comment font les japonais pour exprimer une date négative pour eux sachant que le calendrier japonais commence en 645 pour nous ? Par exemple -15 avant J-C ? Bon il semblerait qu'ils utilisent aussi le calendrier grégorien mais je me demande quand même.
• Dans le Sample vous pouvez rajouter des cases à l'enum RegionFormat et le segmentedControl s'adaptera tout seul.
Petite capture d'écran (Voyez le design digne des plus grands maitres) :
Dixit Wikipédia :
https://fr.wikipedia.org/wiki/Dates_en_japonais
Ok top Draken merci, j'ai lu cette page, et après avoir lu ton extrait, je suis retourné sur la page et j'ai relu la page deux fois avant de retrouver l'extrait... Une seule conclusion, j'ai besoin de lunette. D'accord je vois, de toute façon je vais essayer de faire au plus simple, pour que n'importe qui puisse répondre à une question. Me reste plus qu'à trouver si le signe existe dans le calendar ou la locale.
Edit: il y est dans un NSDateFormater.eraSymbols.
J'ai jeté un oe“il au code pour te donner quelques idées d'améliorations.
Pour moi, le code est plutôt propre mais trop complexe; je pense même que tu as déjà du mal à le faire évoluer. Tes méthodes sont trop longues. Je pense que c'est en grande partie parce que tout se mélange: gestion du view controller, du picker, des représentation internes des dates.
La première amélioration concrète est de séparer la gestion du view controller de celle du picker. Typiquement, si on veut reprendre ton picker dans une appli, on ne peut pas, parce qu'on a tout le view controller et ses segmented controls.
Donc, crée un simple objet qui se conforme aux protocoles UIPickerDataSource et UIPickerDelegate et vois comment tu peux y transférer le code petit à petit.*
Mets ton code sur github dès aujourd'hui, comme ça nous pouvons aussi voir sa dernière version et le modifier.
*quand un chirurgien opère, même s'il a le coe“ur et un rein à transplanter, il va ouvrir le patient plusieurs fois, pas faire un grand trou pour changer tout en même temps.
Merci beaucoup Céroce pour ce retour et ces conseils, c'est très apprécié ! Je suis toujours ouvert à d'autres remarques, même négatives !
• Pour la complexité du code, je ne sais pas, l'histoire de range et d'index relatifs est un peu compliqué à comprendre c'est vrai, mais c'est extrêmement efficace, au début je faisais des switch case et c'était rapidement bien trop long. Comme je disais il faudrait peut-être enlever les doublons de code pour les mettre dans une méthodes, lorsque je fais les tests pour savoir si rangeOfString("") retourne nil pour avoir l'index du mois par exemple dans la représentation locale.
Sinon j'ai l'impression que c'est malheureusement la logique qu'implique de travailler avec ces composants, je ne vois vraiment pas comment faire plus simple, enfin je ne dis pas que ce n'est pas possible. Par contre forcément comme j'ai réfléchi dessus deux jours, le code me parle plus, mais le but en effet serait qu'il parle à n'importe qui.
• Les méthodes sont longues je te l'accorde, je sais que c'est un mauvais travers, un thread ici en parlait récemment, j'y travaille, c'est pas évident, mais je prend bonne note.
• Ok pour gitHub j'ai deux petit truc à faire et je le mets en ligne !
• Bon et finalement pour les calendriers ça devrait aller, je commence à comprendre un peu plus finement comment ça fonctionne donc je vais tester ça et réactiver le segmentedControl qui permet de changer de calendrier.
• Oui très bien vue, ce n'est pas trop réutilisable. Par contre quand tu dis un simple objet qui se conforme aux protocoles de UIPickerView.. Tu veux bien dire un composant qui hérite de NSObject et qui va implémenter <UIPickerViewDataSource,UIPickerViewDelegate> ? Pourquoi ne pas créer un objet qui hérite simplement de UIPickerView ? Pardon pour cette question bête mais j'ai peur de ne pas saisir toutes les implications que cela entraine. Merci !
Dans d'autre frameworks que Cocoa, on hérite de la vue pour lui transmettre des informations (donc, on hérite de l'équivalent de UIPickerView). Avec Cocoa, la vue demande à un autre objet, sa datasource, de lui transmettre les informations à afficher. C'est une forme de délégation.
Cette manière de faire est meilleure parce qu'elle évite justement de sous-classer la vue.
Imagine qu'on dispose déjà d'une sous-classe de UIPickerView, qui modifie son apparence.
Maintenant, on veut à la fois cette apparence et l'affichage tel que tu l'as codé. Si toi, tu as aussi codé par une sous-classe, alors on est bloqué, parce qu'on ne peut pas hériter des deux sous-classes à la fois.
Alors que si tu utilises un objet tiers, ça ne pose pas de problème.
C'est là que je veux en venir. Quand une méthode fait 100 lignes, évidemment qu'il devient difficile de se repérer dedans, et que c'est un problème. Mais surtout, ça veut dire qu'elle fait un tas de choses qui ne sont pas corrélées, donc elle est compliquée.
C'est pour ça que je reviens sur cette histoire de méthodes d'une dizaine de lignes: ce n'est pas une règle absolue, mais plus de dix lignes indique que la méthode fait sans doute trop de choses différentes, et que ça mérite notre attention.
Merci beaucoup c'est bien compris, je vois mieux le problème et la différence. Non en effet je ne passe pas par une sous-classe, le code est comme tu l'a lus, c'est à dire avec un UIPicerView natif.
D'accord je m'y applique dorénavant.
J'ai mis le projet sur gitHub, je prends la bête en main aussi :
https://github.com/aymericbaur/datePicker-component.git
Merci !
Excellent l'article de Dave Delong, merci pour le lien.
Je vcite : "Sur Mercure, le jour est plus court que l'année..." ::)
Il y a aussi des planètes un peu étrange, des étoiles à neutrons en fait, gravitant autour d'une autre étoile, tournant sur elles-même 20 à 30 fois par minute ! A réserver aux amateurs de lever de soleil !
Bonjour à tous,
Je reviens sur les calendriers, car vraiment ce n'est pas évident. J'ai passé quelque temps sur le calendrier japonais et j'ai dû hardcoder le comportement, car comme on a dit plus haut, l'ère est importante dans le calendrier japonais. Mais ce n'est pas évolutif, et il va falloir prendre en compte tous les calendriers qui ont une représentation différente du temps (c'est à dire pour moi où il n'y a pas vraiment d'année 0 mais une successions d'ères ou de cycles).
• J'ai donc pensé avoir un d'attribut pour les calendriers afin de savoir si l'ère est importante afin d'adapter le nombre de picker, leurs largeurs et les datas (pour en revenir au calendrier japonais, l'ère étant déterminée par le règne de l'empereur en cours, il n'y à pas besoin de chiffres pour les milliers à priori, mais une largeur plus grande pour le nom des empereurs).
• Le problème est maintenant avec le calendrier chinois. Un datePicker natif, lorsqu'il est configuré avec un calendrier chinois, affiche le nom des années cyclique. Or je n'arrive pas à avoir le nom en String de ces années. Un petit exemple avec le playground :
Mon principal problème comme expliqué dans les commentaires est que je n'arrive pas à avoir le nom des cycles en chinois traduit. J'ai l'impression que c'est une partie privée et qu'on y a pas accès. En tous cas je n'ai rien trouvé dans la documentation de NScalendar et NSDateFormater, donc est-ce que mon sentiment est fondé ?
De plus dans le cadre de mon quizz, si quelqu'un utilisaint un calendrier chinois, doit répondre à une question historique, les cycles n'ayant pas de compte, on se réfère au règne de l'empereur pour définir une date :
Donc il faudrait proposer cela aussi, mais ça devient vraiment compliqué pour un petit truc. Ou alors proposer le choix d'un calendrier grégorien si le calendrier local ne l'est pas. Mais ça ne résout pas le problème des noms de cycles.
Bref je me suis bien pris la tête, et j'hésite du coup à ne proposer que le calendrier grégorien dans tous les formats de région et basta, gérer tous les calendriers est vraiment galère, même si c'est dommage, le calendrier heureux et bouddhiste fonctionne bien sans modification ::) . L'appli n'est prévue que pour l'Europe dans un premier temps, et j'ai déjà perdu pas mal de temps avec ça même si ça m'a fait découvrir de nouvelles choses Il me reste encore à nettoyer le code comme suggéré par Céroce.
Si quelqu'un à tout de même une idée pour récupérer le nom des cycles je suis preneur !
Merci !
Tu es certain d'avoir besoin d'un quizz en langue chinoise ? Je ne connais pas ton cahier de charges, mais il est rare qu'un quizz historique soit international. Nous n'avons pas la même culture historique que les asiatiques, et même que les américains d'ailleurs.. Chaque culture a tendance à privilégier sa propre histoire.
On parle surtout de l'histoire de France dans les école françaises. De l'histoire américaine aux USA et de la culture chinoise en chine. 1515 Marignan fait tilt chez les français, je doute fort que cela parle à un américain ou un chinois moyen, n'ayant pas étudié l'histoire européenne à l'université.
De la même manière le français moyen ne sais pas grand chose sur la guerre du Pacifique, a part peut-être quelque noms comme Pearl Harbour, Midway et Hiroshima. Alors que les japonais et les asiatiques ont étudiés ça en détail à l'école, pendant qu'on parlait surtout du déroulement européen de la seconde guerre mondiale chez nous. Le 14 Juin 1944 évoque-t-il quelque chose chez le chinois moyen ?
Il y a une localisation des dates, mais aussi du contenu historique. Ce qui a pour conséquence qu'un quizz trop spécifique à un endroit de la planète n'a pas beaucoup d'intérêt pour les gens des autres continents, donc un public restreint. Sauf peut-être des quizz spéciaux adaptés aux touristes, genre "quizz sur les monuments de Paris à visiter absolument".
EDIT :
D'après Wikipédia, la chine utilise officiellement le calendrier grégorien depuis .. 1912 ! Le japon depuis 1873 !
A moins de créer un quizz sur les documents officiels japonais, tu n'as peut-être pas besoin du cycle des empereurs japonais, pour la version nippone de ton application.
Du coup cela peut aussi se traduire littéralement par "Mois1, Mois2, Mois3, Mois4, ... Mois12"
Je ne connais pas le chinois, mais si c'est dans la même veine que le japonais, cela pourrait donc expliquer que le nom des mois du calendrier chinois affichés dans la locale anglais donnent le résultat que tu observes.
D'après Wiki, tous les pays du monde ont adoptés Grégor, sauf :
Céroce a raison, c'est clairement un non-problème. Ces pays ne sont certainement pas de gros clients pour des applications iOS. A part peut-être l'Arabie Saoudite. Mais je doute que les salafistes du coin soient très demandeurs de quizzs historiques occidentaux.