Как узнать квартал заданной даты?

Учитывая объект java.util.Date, как мне найти, в каком квартале он находится?

Предположим, что Q1 = январь, февраль, март, Q2 = апр, май, июнь и т. д.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
41
0
83 561
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Ответ принят как подходящий

Начиная с Java 8, квартал доступен как поле с использованием классов в пакете java.time.

import java.time.LocalDate;
import java.time.temporal.IsoFields;

LocalDate myLocal = LocalDate.now();
quarter = myLocal.get(IsoFields.QUARTER_OF_YEAR);

В более старых версиях Java вы могли использовать:

import java.util.Date;

Date myDate = new Date();
int quarter = (myDate.getMonth() / 3) + 1;

Имейте в виду, что getMonth был объявлен устаревшим раньше:

As of JDK version 1.1, replaced by Calendar.get(Calendar.MONTH).

Вместо этого вы можете использовать объект Calendar следующим образом:

import java.util.Calendar;
import java.util.GregorianCalendar;

Calendar myCal = new GregorianCalendar();
int quarter = (myCal.get(Calendar.MONTH) / 3) + 1;

как вы это делаете, когда у вас месяц с 1 по 12? Я пробовал то же самое, но с x / 4 + 1, но с проблемами округления.

Gambo 03.09.2012 17:47

@Gambo Я, к сожалению, не думаю, что в этом случае есть хорошая изящная формула. Я бы использовал переключатель (см. Ответ программиста-преступника ниже).

Bill the Lizard 03.09.2012 17:53

@BobAvallone Месяцы 0-11 в Java.

Bill the Lizard 06.12.2013 19:58

@Gambo Joda Time возвращает monthOfYear через 1–12, поэтому вы можете использовать это, например: dimTimeByDay.setQuarter( ((curDate.getMonthOfYear() - 1) / 3) + 1 );

Hendy Irawan 22.04.2014 19:07

Вам придется написать свой собственный код, потому что термин «квартал» отличается для каждой компании. Разве ты не можешь просто сделать что-нибудь вроде:

Calendar c = /* get from somewhere */
int month = c.get(Calendar.MONTH);

return (month >= Calendar.JANUARY && month <= Calendar.MARCH)     ? "Q1" :
       (month >= Calendar.APRIL && month <= Calendar.JUNE)        ? "Q2" :
       (month >= Calendar.JULY && month <= Calendar.SEPTEMBER)    ? "Q3" :
                                                                    "Q4";

Поскольку кварталы - это локализованная (западная) концепция, укажите Locale, а не используйте платформу по умолчанию:

Calendar cal = Calendar.getInstance(Locale.US);
/* Consider whether you need to set the calendar's timezone. */
cal.setTime(date);
int month = cal.get(Calendar.MONTH); /* 0 through 11 */
int quarter = (month / 3) + 1;

Это позволит избежать появления тринадцатого месяца (Calendar.UNDECIMBER) в незападных календарях и любого перекоса, вызванного их более короткими месяцами.

Так что я думаю, это зависит от того, как ваша библиотека относится к месяцам. В Jodatime я думаю, что март равен 3, тогда как в другом случае это поле может быть 2. Все зависит от того, начинается ли январь с 0 или 1.

obesechicken13 23.09.2015 17:59

@ obesechicken13 Это было ядро ​​Java, java.util.Calendar, и нет никаких изменений, первый месяц всегда 0. Calendar (и Joda) устарели с Java 8.

erickson 23.09.2015 19:32

Я не уверен, что Календарь устарел. Ни один из его методов не устарел. И что вы имеете в виду, когда Joda устаревает с Java 8? Вы имеете в виду, что LocalDateTime лучше, и если да, то каковы преимущества LocalDateTime перед Joda?

obesechicken13 24.09.2015 22:24

@ obesechicken13 Нет, классы не аннотированы с помощью @Deprecated, но рекомендация из домашняя страница Joda-Time: "Стандартные классы даты и времени до Java SE 8 плохие. ... Обратите внимание, что начиная с Java SE 8 и далее пользователям предлагается перейти на java.time (JSR-310)." Кроме того, "Обратите внимание, что Joda-Time считается быть в значительной степени «законченным» проектом. Никаких серьезных улучшений не планируется. Если вы используете Java SE 8, перейдите на java.time (JSR-310). "

erickson 25.09.2015 00:21

JFreeChart имеет класс Quarter. Если вам интересно, посмотрите javadoc. Источник также доступен на SourceForge, если вы хотите проверить реализацию.

Здесь хорошие решения, но помните, что кварталы могут быть изменены в зависимости от компании / отрасли. Иногда квартал может составлять разные 3 месяца.

Вероятно, вы захотите расширить или инкапсулировать класс календаря, чтобы настроить его для своих задач, а не писать какую-то служебную функцию, которая его преобразует. Ваше приложение, вероятно, будет достаточно сложным в этой области, чтобы вы могли найти другие применения для вашего нового класса календаря - я обещаю, вы будете рады, что вы расширили или инкапсулировали его, даже если сейчас это кажется глупым.

Если у тебя есть

private static final int[] quarters = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};

Тогда текущий quarter

private static final int thisQuarter = quarters[thisMonth];

Где thisMonth

private static final int thisMonth = cal.get(Calendar.MONTH);
int month = Calendar.getInstance().get( Calendar.MONTH ) + 1;

int quarter = month % 3 == 0?  (month / 3): ( month / 3)+1;

@ stackoverflow.com/users/430688/graham-savage Это "работает", потому что это всего лишь принятый ответ, но сделанный глупо. Добавление 1 к месяцу в первой строке нарушает целочисленное деление, поэтому вместо того, чтобы просто не делать этого, он имеет сложное условное выражение. Проще int month = Calendar.getInstance (). Get (Calendar.MONTH) и int квартал = (месяц / 3) +1; Ой, подождите, это принятый ответ.

Dirk Bester 04.03.2015 04:58

Убедитесь, что thisMonth является хотя бы числом с плавающей запятой или двойным, а не целым:

String quarter = thisMonth/3 <= 1 ? "Q1" : thisMonth/3 <= 2 ? "Q2" : thisMonth/3 <= 3 ? "Q3" : "Q4";

С уважением, РС

Для себя я использовал этот метод для строкового представления:

int quarter = (Calendar.getInstance().get(Calendar.MONTH) / 3); // 0 to 3
String[] mQuarterKey = {"qt1", "qt2", "qt3", "qt4"};
String strQuarter = mQuarterKey[quarter];

В Java 8 и более поздних версиях классы java.time имеют более простую версию. Используйте LocalDate и IsoFields

LocalDate.now().get(IsoFields.QUARTER_OF_YEAR)

Наш финансовый год начинается в октябре, поэтому, используя этот ответ, я только что использовал: new LocalDate (). PlusMonths (3) .get (IsoFields.QUARTER_OF_YEAR);

dannrob 03.11.2017 22:38

@dannrob Это LocalDate.now (). plusMonths (3) .get (IsoFields.QUARTER_OF_YEAR) ‌;

Usama 24.08.2020 19:29

Для этого требуется API O в Android :(

Pratik Butani 10.09.2020 08:55

При использовании времени Joda используйте функцию Math.ceil ():

double quarter = Math.ceil(new Double(jodaDate.getMonthOfYear()) / 3.0);

tl; dr

YearQuarter
.from(
    LocalDate.of( 2018 , 1 , 23 ) 
)

ThreeTen-Extra

Ответ от abdmob правильный: использование java.time - разумный путь.

Кроме того, проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time.

Его полезные классы включают:

  • Quarter
  • YearQuarter

Текущий квартал

Чтобы получить текущий квартал, укажите часовой пояс. Определение квартала означает определение даты. А определение даты означает указание часового пояса. В любой момент дата меняется в зависимости от зоны земного шара. Укажите, используя правильное название часового пояса в форме continent/region. Никогда не используйте сокращения из 3-4 букв, такие как EST или IST.

ZoneId z = ZoneId.of( "America/Montreal" );
YearQuarter yq = YearQuarter.now( z );

Учитывая java.util.Date

Если указан java.util.Date, сначала преобразуйте его в тип java.time. Класс Instant представляет момент на временной шкале в универсальное глобальное время с разрешением наносекунды.

Instant instant = myUtilDate.toInstant();

Назначьте часовой пояс, чтобы получить ZoneDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

Создайте YearQuarter из этого ZonedDateTime.

YearQuarter yq = YearQuarter.from( zdt );

Используйте в своем коде

Вы должны передавать экземпляры YearQuarter, а не просто числа или строки. Использование объектов обеспечивает безопасность типов, гарантирует допустимые значения и делает ваш код более самодокументированным.


О java.time

Фреймворк java.time встроен в Java 8 и новее. Эти классы заменяют неудобные старые классы даты и времени наследие, такие как java.util.Date, Calendar, & SimpleDateFormat.

Чтобы узнать больше, см. Учебник Oracle. И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310.

Проект Джода-Тайм, теперь в Режим обслуживания, советует перейти на классы java.time.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте Драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в классах java.sql.*.

Где взять классы java.time?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с объединенной реализацией.
    • В Java 9 добавлены некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP….

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и более.

с java8 вы можете использовать форматировщик:

import java.time.format.DateTimeFormatter
import java.time.LocalDate

println("withQuarter: " + LocalDate.of("2016".toInt,"07".toInt,1).format(DateTimeFormatter.ofPattern("yyyyQMM")))

withQuarter: 2016307

Пользуюсь этим методом.

 public static Integer getQuarter(Date d){
    Calendar c = Calendar.getInstance();
    c.setTime(d);
    int month = c.get(Calendar.MONTH);
    return (month /3)+1;
}

Другие вопросы по теме