фактически getMonth () на Date устарела навсегда;)
Mateusz Dymczyk
6
@slhck: устарел. Начиная с версии 1.1 JDK, заменен на Calendar.get (Calendar.MONTH).
adarshr
3
@Zenzen Я не вижу проблемы в использовании устаревшего метода в основном в устаревшем классе.
Сераб
1
@Muhd, если вы работаете с датами, помогите себе и используйте joda или любую другую библиотеку.
Сераб
1
@Serabe: проблема в том, что есть лучшие решения (которые, по крайней мере, не устарели). И вот уже 14 лет getMonth устарела и по какой-то причине устарела.
Хороший ответ. Примечание для читателя: вы можете указать часовой пояс, а не полагаться на вызов по умолчанию, указанный в ответе. Например, в Париже новый день (и месяц) наступает раньше, чем в Монреале. Если вы заботитесь конкретно о Монреале, используйте ZoneId.of( "America/Montreal" ).
Кстати, еще одно замечание для читателя: вы также можете получить Monthобъект enum, а не просто целое число. Month m = localDate.gotMonth();Смотрите LocalDate::getMonthметод. Использование таких объектов делает ваш код самодокументируемым, обеспечивает безопасность типов и гарантирует допустимые значения. См. Учебник по Enum от Oracle.
Василий Бурк
1
если вы используете date.toInstant()и работаете с java.sql.Date(ребенком java.util.Date), вы получите UnsupportedOperationException. Попробуйтеnew java.sql.Date(src.getTime()).toLocalDate()
Адам
1
@ Adam Гораздо проще конвертировать в / из java.sql.Date, используя новые методы конвертации, добавленные в этот старый класс. java.sql.Date.valueOf( myLocalDate )а myJavaSqlDate.toLocalDate() также драйверы JDBC обновлены для JDBC 4.2 или более поздней версии больше не нужны java.sqlтипы, и могут непосредственно адреса java.timeтипов с помощью ResultSet::getObjectи PreparedStatement::setObjectметоды.
Василий Бурк
287
java.util.Date date=newDate();Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);
Обратите внимание, что Calendar.MONTHбез видимых причин основывается на нуле, то есть в январе == 0. Теперь это хорошо документировано в API, но это все еще чертовски запутанно для начинающих пользователей. Я еще не нашел никого, кто мог бы сказать мне, почему они пошли с этим - возможно, пришло время для нового SO вопроса (хотя я боюсь, что нет большого фона для этого: /)
Voo
5
Метод @Voo Date.getMonth () основывался на нуле, что, вероятно, является основной причиной Calendar.MONTH.
Muhd
1
@Muhd Конечно, в конце концов это была замена. Но это только сдвигает вопрос о том, почему Date.getMonth () был основан на нуле? Imo ужасный дизайн, особенно если учесть, что дни начинаются в один день (по крайней мере, они могут быть последовательными!). Я предполагаю, что для начала это был просто некоторый недосмотр в не очень хорошо разработанном API (как Date, так и Calendar). Но, может быть, есть какой-то прецедент - он просто кажется мне странным и вызвал проблемы у более чем одного новичка в моем опыте.
Во
2
На самом деле это уже было задано здесь, на SO (и не только). Суть в том, что это результат плохо разработанного API. Я имею в виду, как вы упомянули, весь класс Date - это шутка. Интересен тот факт, что не только Java страдает от этой проблемы - iirc JavaScript getMonth () также начинается с 0!
Матеуш Дымчик
1
@ Voo getYear()также, «без видимых причин», вычитается к 1900 году.
Hele
17
Если вы используете Java 8 date api, вы можете получить его в одну строку!
Еще проще, просто спросите у DateTimeобъекта месяц. int month = dateTime.getMonthOfYear();
Василий Бурк
Добрый звонок, Василий, я обновил код. Тем не менее, мне нравится, .toString("MM")как это показывает, что есть больше возможностей, чем просто «ММ».
ssoward
1
Этот ответ игнорирует критическую проблему часового пояса. Смотрите мои комментарии на вопрос и ответ родного брата. Я предлагаю пропускание DateTimeZoneобъекта к этому DateTime конструктору: DateTimeZone.forID( "America/Montreal" ).
Василий Бурк
6
ТЛ; др
myUtilDate.toInstant()// Convert from legacy class to modern. `Instant` is a point on the timeline in UTC..atZone(// Adjust from UTC to a particular time zone to determine date. Renders a `ZonedDateTime` object. ZoneId.of("America/Montreal")// Better to specify desired/expected zone explicitly than rely implicitly on the JVM’s current default time zone.)// Returns a `ZonedDateTime` object..getMonthValue()// Extract a month number. Returns a `int` number.
java.time подробности
Ответ Ортомалы Локни за использование java.time правильный. И вы должны использовать java.time, поскольку это гигантское улучшение по сравнению со старыми классами java.util.Date/.Calendar. Смотрите руководство по Oracle на java.time.
Я добавлю код, показывающий, как использовать java.time без учета java.util.Date, когда вы начинаете со свежим кодом.
Использование java.time в двух словах ... Это Instantмомент времени на UTC. Примените часовой пояс ( ZoneId), чтобы получить ZonedDateTime.
MonthКласс представляет собой сложное перечисление для представления в месяц в целом. Это перечисление имеет удобные методы, такие как получение локализованного имени. И будьте уверены, номер месяца в java.time является нормальным, 1-12, а не бессмысленной ерундой (0-11), найденной в java.util.Date/.Calendar.
Чтобы получить текущую дату и время, часовой пояс имеет решающее значение. В любой момент дата не одинакова во всем мире. Поэтому месяц не одинаков во всем мире, если он близок к концу / началу месяца.
ZoneId zoneId =ZoneId.of("America/Montreal");// Or 'ZoneOffset.UTC'.ZonedDateTime now =ZonedDateTime.now( zoneId );Month month = now.getMonth();int monthNumber = month.getValue();// Answer to the Question.String monthName = month.getDisplayName(TextStyle.FULL ,Locale.CANADA_FRENCH );
Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация 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, и более .
Если вы не можете использовать время Joda и все еще живете в темном мире :) (Java 5 или ниже), вы можете наслаждаться этим:
Примечание. Убедитесь, что дата уже указана в формате: дд / мм / гггг
/**
Make an int Month from a date
*/publicstaticint getMonthInt(Date date){SimpleDateFormat dateFormat =newSimpleDateFormat("MM");returnInteger.parseInt(dateFormat.format(date));}/**
Make an int Year from a date
*/publicstaticint getYearInt(Date date){SimpleDateFormat dateFormat =newSimpleDateFormat("yyyy");returnInteger.parseInt(dateFormat.format(date));}
2 проблемы с вашим ответом: во-первых, вы можете сделать дату с текущим временем, new Date()обходясь без System.currentTimeMillis. Другая причина в том, что getMonth устарела.
Мухд
@Muhd Так, что является лучшим решением?
twlkyao
@Muhd System.currentTimeMillis (), который я добавил здесь, должен был указать, что здесь длинный тип, и вы можете указать дату.
Ответы:
java.time (Java 8)
Вы также можете использовать пакет java.time в Java 8 и преобразовать ваш
java.util.Date
объект вjava.time.LocalDate
объект, а затем просто использоватьgetMonthValue()
метод.Обратите внимание, что значения месяца здесь даны от 1 до 12,
cal.get(Calendar.MONTH)
в отличие от ответа adarshr, который дает значения от 0 до 11.Но, как сказал в комментариях Василий Бурк, предпочтительным способом является получение
Month
объекта enum с помощьюLocalDate::getMonth
метода.источник
ZoneId.of( "America/Montreal" )
.Month
объект enum, а не просто целое число.Month m = localDate.gotMonth();
СмотритеLocalDate::getMonth
метод. Использование таких объектов делает ваш код самодокументируемым, обеспечивает безопасность типов и гарантирует допустимые значения. См. Учебник по Enum от Oracle.date.toInstant()
и работаете сjava.sql.Date
(ребенкомjava.util.Date
), вы получитеUnsupportedOperationException
. Попробуйтеnew java.sql.Date(src.getTime()).toLocalDate()
java.sql.Date
, используя новые методы конвертации, добавленные в этот старый класс.java.sql.Date.valueOf( myLocalDate )
аmyJavaSqlDate.toLocalDate()
также драйверы JDBC обновлены для JDBC 4.2 или более поздней версии больше не нужныjava.sql
типы, и могут непосредственно адресаjava.time
типов с помощьюResultSet::getObject
иPreparedStatement::setObject
методы.источник
Calendar.MONTH
без видимых причин основывается на нуле, то есть в январе == 0. Теперь это хорошо документировано в API, но это все еще чертовски запутанно для начинающих пользователей. Я еще не нашел никого, кто мог бы сказать мне, почему они пошли с этим - возможно, пришло время для нового SO вопроса (хотя я боюсь, что нет большого фона для этого: /)getYear()
также, «без видимых причин», вычитается к 1900 году.Если вы используете Java 8 date api, вы можете получить его в одну строку!
источник
Joda времени
Кроме того, с классом Joda-Time
DateTime
.…или…
источник
DateTime
объекта месяц.int month = dateTime.getMonthOfYear();
.toString("MM")
как это показывает, что есть больше возможностей, чем просто «ММ».DateTimeZone
объекта к этому DateTime конструктору:DateTimeZone.forID( "America/Montreal" )
.ТЛ; др
java.time
подробностиОтвет Ортомалы Локни за использование java.time правильный. И вы должны использовать java.time, поскольку это гигантское улучшение по сравнению со старыми классами java.util.Date/.Calendar. Смотрите руководство по Oracle на java.time.
Я добавлю код, показывающий, как использовать java.time без учета java.util.Date, когда вы начинаете со свежим кодом.
Использование java.time в двух словах ... Это
Instant
момент времени на UTC. Примените часовой пояс (ZoneId
), чтобы получитьZonedDateTime
.Month
Класс представляет собой сложное перечисление для представления в месяц в целом. Это перечисление имеет удобные методы, такие как получение локализованного имени. И будьте уверены, номер месяца в java.time является нормальным, 1-12, а не бессмысленной ерундой (0-11), найденной в java.util.Date/.Calendar.Чтобы получить текущую дату и время, часовой пояс имеет решающее значение. В любой момент дата не одинакова во всем мире. Поэтому месяц не одинаков во всем мире, если он близок к концу / началу месяца.
О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в
java.sql.*
классах.Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как
Interval
,YearWeek
,YearQuarter
, и более .источник
Если вы не можете использовать время Joda и все еще живете в темном мире :) (Java 5 или ниже), вы можете наслаждаться этим:
Примечание. Убедитесь, что дата уже указана в формате: дд / мм / гггг
источник
Возвращаемое значение начинается с 0, поэтому вы должны добавить его к результату.
источник
new Date()
обходясь безSystem.currentTimeMillis
. Другая причина в том, что getMonth устарела.