Осторожно, месяцы Java отсчитываются от нуля, поэтому 0 = январь, 1 = февраль и т. Д.
Ник Холт,
Вы правы, поэтому, если нужно сменить язык, просто нужно сменить локаль. Спасибо
atomfat
2
@NickHolt ОБНОВЛЕНИЕ Современное java.timeMonthперечисление основано на единице: 1-12 для января-декабря. То же самое для [ 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 Calendar` имеет сумасшедшие схемы нумерации. Одна из многих причин избегать устаревших классов, которые теперь полностью вытеснены классами java.time .
ОН нуждается month-1. Кто-нибудь еще, использующий, Calendar.get(Calendar.MONTH)будет просто нуждатьсяmonth
Рон
1
Реализация DateFormatSymbols была изменена в JDK 8, поэтому метод getMonths больше не возвращает правильные значения для всех Locale: oracle.com/technetwork/java/javase/…
ahaaman
33
Вам необходимо использовать LLLL для автономных названий месяцев. это задокументировано в SimpleDateFormatдокументации, например:
SimpleDateFormat dateFormat =newSimpleDateFormat("LLLL",Locale.getDefault());
dateFormat.format( date );
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
Начиная с Java 1.8 (или 1.7 и 1.6 с ThreeTen-Backport ) вы можете использовать это:
Обратите внимание, что integerMonthотсчитывается от 1, т.е. 1 соответствует январю. Диапазон всегда от 1 до 12 для января-декабря (т. Е. Только по григорианскому календарю).
скажем, у вас есть строковый месяц май на французском языке, используя метод, который вы опубликовали (май на французском языке - это май), как я могу получить число 5 из этой строки?
usertest 03
@usertest я написал черновой проект класса MonthDelocalizerв моем ответе , чтобы получить Monthобъект из прошедшей локализованного имени месяца строки: mai→ Month.MAY. Обратите внимание, что чувствительность к регистру имеет значение: во французском языке Maiэто недопустимо и должно быть mai.
Basil Bourque
Это 2019 год. Почему это не главный ответ?
anothernode
16
Я бы использовал SimpleDateFormat. Кто-то поправит меня, если есть более простой способ сделать ежемесячный календарь, я делаю это сейчас в коде, и я в этом не уверен.
А затем используйте их в своем коде следующим образом:
/**
* 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;}
«По-видимому, в Android 2.2 есть ошибка» - было бы полезно, если бы вы могли указать, где отслеживается ошибка.
Питер Холл
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
Теперь гораздо проще сделать это в классах java.time, которые вытесняют эти утомительные старые устаревшие классы даты и времени.
MonthПеречисление определяет дюжину объектов, по одному на каждый месяц.
С января по декабрь месяцы пронумерованы с 1 по 12.
Настроить TextStyle чтобы указать, как долго или сокращенно вы хотите имя. Обратите внимание, что на некоторых языках (не на английском) название месяца меняется, если оно используется отдельно или как часть полной даты. Таким образом, у каждого стиля текста есть свой …_STANDALONEвариант.
Какой человеческий язык следует использовать при переводе.
Какие культурные нормы должны определять такие вопросы, как аббревиатуры, пунктуация и использование заглавных букв.
Пример:
Locale l =newLocale("es","MX");String output =Month.FEBRUARY.getDisplayName(TextStyle.SHORT_STANDALONE , l );// Or Locale.US, Locale.CANADA_FRENCH.
Имя → Month объект
FYI, пойти в другом направлении (разбор строки имени месяца для получения Monthобъекта перечисления) не встроен. Вы можете написать свой собственный класс для этого. Вот моя быстрая попытка пройти такой урок.Используйте на свой риск . Я не задумывался над этим кодом и не тестировал его.
Использование.
Month m =MonthDelocalizer.of(Locale.CANADA_FRENCH ).parse("janvier");// Month.JANUARY
Код.
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.");}}}
Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*занятиях.
Более поздние версии Android связывают реализации классов java.time.
Для более ранней версии Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP… .
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .
Возникает проблема, когда вы используете класс DateFormatSymbols для его метода getMonthName, чтобы получить месяц по имени, он показывает месяц по номеру на некоторых устройствах Android. Я решил эту проблему следующим образом:
Ужасный Calendarкласс был вытеснен много лет назад классами java.time, определенными в JSR 310.
Бэзил Бурк
0
publicstaticvoid main(String[] args){SimpleDateFormat format =newSimpleDateFormat("MMMMM",newLocale("en","US"));System.out.println(format.format(newDate()));}
DateFormatSymbolsявляется частью ужасных классов даты и времени, которые теперь унаследованы с момента принятия JSR 310 . Теперь на смену классам java.time . Предлагать их использование в 2019 году - плохой совет.
java.timeMonth
перечисление основано на единице: 1-12 для января-декабря. То же самое для [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
Calendar` имеет сумасшедшие схемы нумерации. Одна из многих причин избегать устаревших классов, которые теперь полностью вытеснены классами java.time .Ответы:
источник
month-1
. Кто-нибудь еще, использующий,Calendar.get(Calendar.MONTH)
будет просто нуждатьсяmonth
Вам необходимо использовать LLLL для автономных названий месяцев. это задокументировано в
SimpleDateFormat
документации, например:источник
IllegalArgumentException : Illegal pattern character 'L'
tl; dr
java.time
Начиная с Java 1.8 (или 1.7 и 1.6 с ThreeTen-Backport ) вы можете использовать это:
Обратите внимание, что
integerMonth
отсчитывается от 1, т.е. 1 соответствует январю. Диапазон всегда от 1 до 12 для января-декабря (т. Е. Только по григорианскому календарю).источник
MonthDelocalizer
в моем ответе , чтобы получитьMonth
объект из прошедшей локализованного имени месяца строки:mai
→ Month.MAY. Обратите внимание, что чувствительность к регистру имеет значение: во французском языкеMai
это недопустимо и должно бытьmai
.Я бы использовал SimpleDateFormat. Кто-то поправит меня, если есть более простой способ сделать ежемесячный календарь, я делаю это сейчас в коде, и я в этом не уверен.
источник
Вот как бы я это сделал. Я оставлю проверку дальности
int month
до тебя.источник
Использование SimpleDateFormat.
Результат: февраль
источник
Видимо в Android 2.2 есть ошибка SimpleDateFormat.
Чтобы использовать названия месяцев, вы должны сами определить их в своих ресурсах:
А затем используйте их в своем коде следующим образом:
источник
tl; dr
java.time.Month
Теперь гораздо проще сделать это в классах java.time, которые вытесняют эти утомительные старые устаревшие классы даты и времени.
Month
Перечисление определяет дюжину объектов, по одному на каждый месяц.С января по декабрь месяцы пронумерованы с 1 по 12.
Попросите объект сгенерировать строку автоматически локализованную названия месяца .
Настроить
TextStyle
чтобы указать, как долго или сокращенно вы хотите имя. Обратите внимание, что на некоторых языках (не на английском) название месяца меняется, если оно используется отдельно или как часть полной даты. Таким образом, у каждого стиля текста есть свой…_STANDALONE
вариант.Укажите
Locale
чтобы определить:Пример:
Имя →
Month
объектFYI, пойти в другом направлении (разбор строки имени месяца для получения
Month
объекта перечисления) не встроен. Вы можете написать свой собственный класс для этого. Вот моя быстрая попытка пройти такой урок.Используйте на свой риск . Я не задумывался над этим кодом и не тестировал его.Использование.
Код.
Около java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в
java.sql.*
занятиях.Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как
Interval
,YearWeek
,YearQuarter
, и более .источник
Возникает проблема, когда вы используете класс DateFormatSymbols для его метода getMonthName, чтобы получить месяц по имени, он показывает месяц по номеру на некоторых устройствах Android. Я решил эту проблему следующим образом:
В String_array.xml
В классе Java просто вызовите этот массив следующим образом:
Удачного кодирования :)
источник
Расширение Kotlin
использование
источник
Calendar
класс был вытеснен много лет назад классами java.time, определенными в JSR 310.источник
SimpleDateFormat
Тем не менее, он использует заведомо проблемный и давно устаревший класс.Просто вставив строку
сделает свое дело.
источник
DateFormatSymbols
является частью ужасных классов даты и времени, которые теперь унаследованы с момента принятия JSR 310 . Теперь на смену классам java.time . Предлагать их использование в 2019 году - плохой совет.Попробуйте использовать это очень простым способом и назовите его как свою собственную функцию
источник
Month::getDisplayName
.