Uważaj, miesiące Java są liczone od zera, więc 0 = styczeń, 1 = luty itd.
Nick Holt,
masz rację, więc jeśli trzeba zmienić język, wystarczy zmienić ustawienia regionalne. Dzięki
atomsfat
2
@NickHolt UPDATE Nowoczesne java.timeMonthwyliczenie jest oparte na jedynkach : 1-12 dla stycznia-grudnia. Podobnie jak w przypadku [ java.time.DayOfWeek](https://docs.oracle.com/javase/9/docs/api/java/time/DayOfWeek.html): 1-7 for Monday-Sunday per ISO 8601 standard. Only the troublesome old legacy date-time classes such as Kalendarza] istnieją szalone schematy numeracji. Jeden z wielu powodów, dla których należy unikać klas starszych, obecnie całkowicie wypieranych przez klasy java.time .
JDK 1.7 /IllegalArgumentException : Illegal pattern character 'L'
AntJavaDev
26
tl; dr
Month// Enum class, predefining and naming a dozen objects, one for each month of the year. .of(12)// Retrieving one of the enum objects by number, 1-12. .getDisplayName(TextStyle.FULL_STANDALONE ,Locale.CANADA_FRENCH // Locale determines the human language and cultural norms used in localizing. )
java.time
Od Java 1.8 (lub 1.7 i 1.6 z ThreeTen-Backport ) możesz używać tego:
Zauważ, że integerMonthjest oparty na 1, czyli 1 oznacza styczeń. Zakres obejmuje zawsze od 1 do 12 w okresie styczeń-grudzień (tj. Tylko kalendarz gregoriański).
powiedzmy, że masz miesiąc majowy String po francusku, używając metody, którą opublikowałeś (maj po francusku to Mai), jak mogę uzyskać liczbę 5 z tego ciągu?
test użytkownika
@usertest Napisałem wstępną klasę MonthDelocalizerw mojej odpowiedzi, aby pobrać Monthobiekt z przekazanego zlokalizowanego ciągu nazwy miesiąca: mai→ Month.MAY. Pamiętaj, że rozróżnianie wielkości liter ma znaczenie: w języku francuskim Maijest nieważne i powinno mai.
Basil Bourque,
Jest rok 2019. Dlaczego to nie jest najlepsza odpowiedź?
anothernode
16
Użyłbym SimpleDateFormat. Ktoś poprawi mnie, jeśli istnieje łatwiejszy sposób na zrobienie miesięcznego kalendarza, robię to teraz w kodzie i nie jestem taki pewien.
Następnie użyj ich w swoim kodzie w następujący sposób:
/**
* Get the month name of a Date. e.g. January for the Date 2011-01-01
*
* @param date
* @return e.g. "January"
*/publicstaticString getMonthName(Context context,Date date){/*
* Android 2.2 has a bug in SimpleDateFormat. Can't use "MMMM" for
* getting the Month name for the given Locale. Thus relying on own
* values from string resources
*/String result ="";Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);try{
result = context.getResources().getStringArray(R.array.month_names)[month];}catch(ArrayIndexOutOfBoundsException e){
result =Integer.toString(month);}return result;}
„Najwyraźniej w Androidzie 2.2 jest błąd” - Przydałoby się, gdybyś udostępnił link do miejsca śledzenia błędu.
Peter Hall
6
tl; dr
Month.of( yourMonthNumber )// Represent a month by its number, 1-12 for January-December. .getDisplayName(// Generate text of the name of the month automatically localized. TextStyle.SHORT_STANDALONE ,// Specify how long or abbreviated the name of month should be.newLocale("es","MX")// Locale determines (a) the human language used in translation, and (b) the cultural norms used in deciding issues of abbreviation, capitalization, punctuation, and so on.)// Returns a String.
java.time.Month
Dużo łatwiej jest teraz zrobić w klasach java.time, które zastępują te kłopotliwe, starsze klasy data-czas.
MonthEnum określa kilkanaście obiektów, po jednym dla każdego miesiąca.
Miesiące od stycznia do grudnia są ponumerowane od 1 do 12.
Dostosuj, TextStyleaby określić, jak długa lub skrócona ma być nazwa. Należy pamiętać, że w niektórych językach (nie w języku angielskim) nazwa miesiąca różni się, jeśli jest używana samodzielnie lub jako część pełnej daty. Dlatego każdy styl tekstu ma inny …_STANDALONEwariant.
Jakie normy kulturowe powinny decydować o kwestiach, takich jak skróty, interpunkcja i wielkie litery.
Przykład:
Locale l =newLocale("es","MX");String output =Month.FEBRUARY.getDisplayName(TextStyle.SHORT_STANDALONE , l );// Or Locale.US, Locale.CANADA_FRENCH.
Nazwa → Monthobiekt
FYI, pójście w innym kierunku (analiza ciągu z nazwą miesiąca w celu uzyskania Monthobiektu wyliczenia) nie jest wbudowane. Możesz w tym celu napisać własną klasę. Oto moja szybka próba takiej klasy. Używaj na własne ryzyko . Nie zastanawiałem się nad tym kodem ani nie poddawałem go poważnym testom.
Stosowanie.
Month m =MonthDelocalizer.of(Locale.CANADA_FRENCH ).parse("janvier");// Month.JANUARY
Kod.
package com.basilbourque.example;import org.jetbrains.annotations.NotNull;import org.jetbrains.annotations.Nullable;import java.time.Month;import java.time.format.TextStyle;import java.util.ArrayList;import java.util.List;import java.util.Locale;// For a given name of month in some language, determine the matching `java.time.Month` enum object.// This class is the opposite of `Month.getDisplayName` which generates a localized string for a given `Month` object.// Usage… MonthDelocalizer.of( Locale.CANADA_FRENCH ).parse( "janvier" ) → Month.JANUARY// Assumes `FormatStyle.FULL`, for names without abbreviation.// About `java.time.Month` enum: https://docs.oracle.com/javase/9/docs/api/java/time/Month.html// USE AT YOUR OWN RISK. Provided without guarantee or warranty. No serious testing or code review was performed.publicclassMonthDelocalizer{@NotNullprivateLocale locale;@NotNullprivateList<String> monthNames, monthNamesStandalone;// Some languages use an alternate spelling for a “standalone” month name used without the context of a date.// Constructor. Private, for static factory method.privateMonthDelocalizer(@NotNullLocale locale ){this.locale = locale;// Populate the pair of arrays, each having the translated month names.int countMonthsInYear =12;// Twelve months in the year.this.monthNames =newArrayList<>( countMonthsInYear );this.monthNamesStandalone =newArrayList<>( countMonthsInYear );for(int i =1; i <= countMonthsInYear ; i++){this.monthNames.add(Month.of( i ).getDisplayName(TextStyle.FULL ,this.locale ));this.monthNamesStandalone.add(Month.of( i ).getDisplayName(TextStyle.FULL_STANDALONE ,this.locale ));}// System.out.println( this.monthNames );// System.out.println( this.monthNamesStandalone );}// Constructor. Private, for static factory method.// Personally, I think it unwise to default implicitly to a `Locale`. But I included this in case you disagree with me, and to follow the lead of the *java.time* classes. --Basil BourqueprivateMonthDelocalizer(){this(Locale.getDefault());}// static factory method, instead of constructors.// See article by Dr. Joshua Bloch. http://www.informit.com/articles/article.aspx?p=1216151// The `Locale` argument determines the human language and cultural norms used in de-localizing input strings.synchronizedstaticpublicMonthDelocalizer of (@NotNullLocale localeArg ){MonthDelocalizer x =newMonthDelocalizer( localeArg );// This class could be optimized by caching this object.return x;}// Attempt to translate the name of a month to look-up a matching `Month` enum object.// Returns NULL if the passed String value is not found to be a valid name of month for the human language and cultural norms of the `Locale` specified when constructing this parent object, `MonthDelocalizer`.@NullablepublicMonth parse (@NotNullString input ){int index =this.monthNames.indexOf( input );if(-1== index ){// If no hit in the contextual names, try the standalone names.
index =this.monthNamesStandalone.indexOf( input );}int ordinal =( index +1);Month m =( ordinal >0)?Month.of( ordinal ):null;// If we have a hit, determine the `Month` enum object. Else return null.if(null== m ){thrownew java.lang.IllegalArgumentException("The passed month name: ‘"+ input +"’ is not valid for locale: "+this.locale.toString());}return m;}// `Object` class overrides.@Overridepublicboolean equals (Object o ){if(this== o )returntrue;if( o ==null|| getClass()!= o.getClass())returnfalse;MonthDelocalizer that =(MonthDelocalizer) o;return locale.equals( that.locale );}@Overridepublicint hashCode (){return locale.hashCode();}publicstaticvoid main (String[] args ){// Usage example:MonthDelocalizer monthDelocJapan =MonthDelocalizer.of(Locale.JAPAN );try{Month m = monthDelocJapan.parse("pink elephant");// Invalid input.}catch(IllegalArgumentException e ){// … handle errorSystem.out.println("ERROR: "+ e.getLocalizedMessage());}// Ignore exception. (not recommended)if(MonthDelocalizer.of(Locale.CANADA_FRENCH ).parse("janvier").equals(Month.JANUARY )){System.out.println("GOOD - In locale "+Locale.CANADA_FRENCH+", the input ‘janvier’ parses to Month.JANUARY.");}}}
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*klas.
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .
Występuje problem podczas używania klasy DateFormatSymbols dla metody getMonthName w celu pobrania miesiąca według nazwy, która pokazuje miesiąc według numeru na niektórych urządzeniach z systemem Android. Rozwiązałem ten problem w ten sposób:
Straszliwa Calendarklasa została wyparta laty przez java.time klas zdefiniowanych w JSR 310.
Basil Bourque
0
publicstaticvoid main(String[] args){SimpleDateFormat format =newSimpleDateFormat("MMMMM",newLocale("en","US"));System.out.println(format.format(newDate()));}
DateFormatSymbolsjest częścią okropnych klas daty i czasu, które są teraz starsze, od przyjęcia JSR 310 . Teraz zastąpione przez klasy java.time . Sugerowanie ich użycia w 2019 roku to kiepska rada.
java.timeMonth
wyliczenie jest oparte na jedynkach : 1-12 dla stycznia-grudnia. Podobnie jak w przypadku [java.time.DayOfWeek](https://docs.oracle.com/javase/9/docs/api/java/time/DayOfWeek.html): 1-7 for Monday-Sunday per ISO 8601 standard. Only the troublesome old legacy date-time classes such as
Kalendarza] istnieją szalone schematy numeracji. Jeden z wielu powodów, dla których należy unikać klas starszych, obecnie całkowicie wypieranych przez klasy java.time .Odpowiedzi:
źródło
month-1
. Każdy innyCalendar.get(Calendar.MONTH)
będzie potrzebowałmonth
Musisz używać LLLL dla samodzielnych nazw miesięcy. jest to udokumentowane w
SimpleDateFormat
dokumentacji, takiej jak:źródło
IllegalArgumentException : Illegal pattern character 'L'
tl; dr
java.time
Od Java 1.8 (lub 1.7 i 1.6 z ThreeTen-Backport ) możesz używać tego:
Zauważ, że
integerMonth
jest oparty na 1, czyli 1 oznacza styczeń. Zakres obejmuje zawsze od 1 do 12 w okresie styczeń-grudzień (tj. Tylko kalendarz gregoriański).źródło
MonthDelocalizer
w mojej odpowiedzi, aby pobraćMonth
obiekt z przekazanego zlokalizowanego ciągu nazwy miesiąca:mai
→ Month.MAY. Pamiętaj, że rozróżnianie wielkości liter ma znaczenie: w języku francuskimMai
jest nieważne i powinnomai
.Użyłbym SimpleDateFormat. Ktoś poprawi mnie, jeśli istnieje łatwiejszy sposób na zrobienie miesięcznego kalendarza, robię to teraz w kodzie i nie jestem taki pewien.
źródło
Oto jak bym to zrobił. Zostawię sprawdzanie zakresu od
int month
ciebie.źródło
Korzystanie z SimpleDateFormat.
Wynik: luty
źródło
Najwyraźniej w Androidzie 2.2 jest błąd w SimpleDateFormat.
Aby używać nazw miesięcy, musisz zdefiniować je samodzielnie w swoich zasobach:
Następnie użyj ich w swoim kodzie w następujący sposób:
źródło
tl; dr
java.time.Month
Dużo łatwiej jest teraz zrobić w klasach java.time, które zastępują te kłopotliwe, starsze klasy data-czas.
Month
Enum określa kilkanaście obiektów, po jednym dla każdego miesiąca.Miesiące od stycznia do grudnia są ponumerowane od 1 do 12.
Poproś obiekt o wygenerowanie ciągu z nazwą miesiąca, automatycznie zlokalizowanego .
Dostosuj,
TextStyle
aby określić, jak długa lub skrócona ma być nazwa. Należy pamiętać, że w niektórych językach (nie w języku angielskim) nazwa miesiąca różni się, jeśli jest używana samodzielnie lub jako część pełnej daty. Dlatego każdy styl tekstu ma inny…_STANDALONE
wariant.Określ a,
Locale
aby określić:Przykład:
Nazwa →
Month
obiektFYI, pójście w innym kierunku (analiza ciągu z nazwą miesiąca w celu uzyskania
Month
obiektu wyliczenia) nie jest wbudowane. Możesz w tym celu napisać własną klasę. Oto moja szybka próba takiej klasy. Używaj na własne ryzyko . Nie zastanawiałem się nad tym kodem ani nie poddawałem go poważnym testom.Stosowanie.
Kod.
Informacje o java.time
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak
java.util.Date
,Calendar
, iSimpleDateFormat
.Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani
java.sql.*
klas.Skąd wziąć klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak
Interval
,YearWeek
,YearQuarter
, i więcej .źródło
Występuje problem podczas używania klasy DateFormatSymbols dla metody getMonthName w celu pobrania miesiąca według nazwy, która pokazuje miesiąc według numeru na niektórych urządzeniach z systemem Android. Rozwiązałem ten problem w ten sposób:
W String_array.xml
W klasie Java po prostu wywołaj tę tablicę w następujący sposób:
Miłego kodowania :)
źródło
Rozszerzenie Kotlin
Stosowanie
źródło
Calendar
klasa została wyparta laty przez java.time klas zdefiniowanych w JSR 310.źródło
SimpleDateFormat
klasy.Po prostu wstawiam linię
da rade.
źródło
DateFormatSymbols
jest częścią okropnych klas daty i czasu, które są teraz starsze, od przyjęcia JSR 310 . Teraz zastąpione przez klasy java.time . Sugerowanie ich użycia w 2019 roku to kiepska rada.Spróbuj użyć tego w bardzo prosty sposób i nazwij to jak własną funkcją
źródło
Month::getDisplayName
.