Мне только удачи от SO, так почему бы не попробовать еще раз?
У меня есть приложение, которое должно отображать другое изображение в зависимости от времени года (весна, лето, зима, осень). У меня очень конкретные даты начала и окончания для этих сезонов.
Я бы хотел, чтобы вы, гении, получили метод GetSeason, который принимает дату в качестве входных данных и возвращает строковое значение Spring, Summer, Winter или Fall. Вот диапазоны дат и связанные с ними сезоны:
Пружина: 3 / 1-4 / 30
Лето: 5 / 1-8 / 31
Осень: 9 / 1-10 / 31
Зима: 1-2-28 ноября
Может ли кто-нибудь предоставить рабочий метод, чтобы вернуть правильный сезон? Спасибо всем!
На земле нет ничего лучше жизни в высокой пустыне. 8 дней назад было 103 градуса, завтра будет 72 :)
Вы также забыли учесть там 2/29 ... но я понимаю, что вы имеете в виду.
А что насчет южного полушария? Вы знаете, что наши времена года перевернуты, не так ли?
Это имело бы значение, если бы он был в в южном полушарии. :) Он уже настраивает продолжительность сезонов для своего региона.
Для справки - это приложение было бы намеренно бесполезно никому, находящемуся на расстоянии более 20 миль от меня.
Ну и напоследок - это не домашнее задание. Проверьте мой профиль на наличие массивов массивов на Java, и вы увидите фактическое полное описание этого варианта использования. Спасибо всем!
Я, в основном, поэтому и ответил. Просто ТАК похоже, что кто-то задает домашнее задание, не так ли?
Не забывайте, что в южном полушарии времена года меняются местами.




Что ж, это может быть так просто, как
String getSeason(int month) {
switch(month) {
case 11:
case 12:
case 1:
case 2:
return "winter";
case 3:
case 4:
return "spring";
case 5:
case 6:
case 7:
case 8:
return "summer";
default:
return "autumn";
}
}
В комментариях меня упрекнули в лучшем решении: enums:
public static Enum Season {
WINTER(Arrays.asList(11,12,1,2)),
SPRING(Arrays.asList(3,4)),
SUMMER(Arrays.asList(5,6,7,8)),
AUTUMN(Arrays.asList(9,10));
Season(List<Integer> months) {
this.monthlist = months;
}
private List<Integer> monthlist;
public boolean inSeason(int month) {
return this.monthlist.contains(month); // if months are 0 based, then insert +1 before the )
}
public static Season seasonForMonth(int month) {
for(Season s: Season.values()) {
if (s.inSeason(month))
return s;
}
throw new IllegalArgumentException("Unknown month");
}
}
Не мой любимый, поскольку я ненавижу использовать значение по умолчанию для реальных известных ответов, а многократные возвраты - это плохой тон, но это полезно.
Что ж, сложный ответ - использовать перечисление. Буду редактировать.
month = числовое значение-1, поэтому jan = 0, feb = 1 .. dec = 11. at leat, в соответствии с константами Calendar. *.
Да, Андреас прав ... как ни странно, у тебя было это прямо раньше. Кроме того, вы действительно пытались сделать это медленнее? :) В общем, это в целом глупый вопрос, но вау, ты тут не сработал.
Подожди, только что видел ответ Контагиозного. Вы прощены. Этот ответ НЕ ТАК ДЕТСКИЙ, как этот.
Что ж, я устал редактировать этот ответ. Преимущество этой системы состоит в том, что список месяцев для сезона разделен запятой в той же строке кода, что и название сезона. Это делает его более удобным в обслуживании, чем коммутатор.
поскольку в этом диапазоне все сезоны - это полные месяцы, вы можете переключить месяц с вашей даты:
switch (date.getMonth()) {
case Calendar.JANUARY:
case Calendar.FEBRUARY:
return "winter";
case Calendar.MARCH:
return "spring";
//etc
}
Я рекомендую завершить переключение целиком, используя все 12 констант календаря вместо значений по умолчанию для последних. Затем вы можете убедиться, что ваш ввод был правильным, например, с помощью
default:
throw new IllegalArgumentException();
в конце.
Вы также можете использовать Enum для сезона вместо простой строки, в зависимости от ваших вариантов использования.
Обратите внимание, что метод Date.getMonth () устарел, вместо него следует использовать java.util.Calendar.get (Calendar.MONTH). (просто преобразуйте дату в календарь с помощью calendar.setDate (yourDate))
Похоже, достаточно проверить месяц:
private static final String seasons[] = {
"Winter", "Winter", "Spring", "Spring", "Summer", "Summer",
"Summer", "Summer", "Fall", "Fall", "Winter", "Winter"
};
public String getSeason( Date date ) {
return seasons[ date.getMonth() ];
}
// As stated above, getMonth() is deprecated, but if you start with a Date,
// you'd have to convert to Calendar before continuing with new Java,
// and that's not fast.
Здесь я не делаю никаких домашних заданий. Мои студенческие дни остались далеко позади. Проверьте мой профиль на другие мои вопросы по Java, чтобы увидеть вариант использования.
k, избавился от ссылки. Большинство людей не читают это, но это не имело в виду обиду.
Кто-то отредактировал мой ответ, изменив его на 3 месяца за сезон, что не было запрошенным решением ... Я отменил изменение. Надеюсь, он прочитает это, прежде чем повторить это снова.
Я чувствую себя покровительственным, но польщенным. так что я сделаю это.
Это проверяет не только месяц, но и день месяца.
import java.util.*
public String getSeason(Date today, int year){
// the months are one less because GC is 0-based for the months, but not days.
// i.e. 0 = January.
String returnMe = "";
GregorianCalender dateToday = new GregorianCalender(year, today.get(Calender.MONTH_OF_YEAR), today.get(Calender.DAY_OF_MONTH);
GregorianCalender springstart = new GregorianCalender(year, 2, 1);
GregorianCalender springend = new GregorianCalender(year, 3, 30);
GregorianCalender summerstart = new GregorianCalender(year, 4, 1);
GregorianCalender summerend = new GregorianCalender(year, 7, 31);
GregorianCalender fallstart = new GregorianCalender(year, 8, 1);
GregorianCalender fallend = new GregorianCalender(year, 9, 31);
GregorianCalender winterstart = new GregorianCalender(year, 10, 1);
GregorianCalender winterend = new GregorianCalender(year, 1, 28);
if ((dateToday.after(springstart) && dateToday.before(springend)) || dateToday.equals(springstart) || dateToday.equals(springend)){
returnMe = "Spring";
else if ((dateToday.after(summerstart) && dateToday.before(summerend)) || dateToday.equals(summerstart) || dateToday.equals(summerend)){
returnMe = "Summer";
else if ((dateToday.after(fallstart) && dateToday.before(fallend)) || dateToday.equals(fallstart) || dateToday.equals(fallend)){
returnMe = "Fall";
else if ((dateToday.after(winterstart) && dateToday.before(winterend)) || dateToday.equals(winterstart) || dateToday.equals(winterend)){
returnMe = "Winter";
else {
returnMe = "Invalid";
}
return returnMe;
}
Я уверен, что это ужасно, и это можно исправить. Дай мне знать в комментариях.
Хорошо, сначала хорошие комментарии: вы хорошо справляетесь с делом дня месяца, поэтому, если он решит выделить 2 дня с осени на лето, у вас есть самое простое решение. Кроме того, вы правильно используете Календарь.
Теперь о плохом: вы создаете 8 объектов календаря КАЖДЫЙ РАЗ, когда вызывается функция, когда необходимо только 4 (разберитесь), и их можно создать один раз и использовать повторно. Кроме того, зачем возвращать «Invalid»? Сделайте исключение, если каким-то образом сегодняшняя дата не входит в один из 4 сезонов, k?
Мне любопытно, почему текущий год каким-то образом не сохраняется в аргументе Date. Вроде бы так и было.
public class lab6project1 {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("This program reports the season for a given day and month");
System.out.println("Please enter the month and day as integers with a space between the month and day");
int month = keyboard.nextInt();
int day = keyboard.nextInt();
if ((month == 1) || (month == 2)) {
System.out.println("The season is Winter");
} else if ((month == 4) || (month == 5)) {
System.out.println("The season is Spring");
} else if ((month == 7) || (month == 8)) {
System.out.println("The season is Summer");
} else if ((month == 10) || (month == 11)) {
System.out.println("The season is Fall");
} else if ((month == 3) && (day <= 19)) {
System.out.println("The season is Winter");
} else if (month == 3) {
System.out.println("The season is Spring");
} else if ((month == 6) && (day <= 20)) {
System.out.println("The season is Spring");
} else if (month == 6) {
System.out.println("The season is Summer");
} else if ((month == 9) && (day <= 20)) {
System.out.println("The season is Summer");
} else if (month == 9) {
System.out.println("The season is Autumn");
} else if ((month == 12) && (day <= 21)) {
System.out.println("The season is Autumn");
} else if (month == 12) {
System.out.println("The season is Winter");
}
}
}
Попробуйте использовать хеш-таблицы или перечисления. Вы можете преобразовать дату в какое-то значение (1 января - 1, ...), а затем создать ячейки для определенного поля. или вы можете сделать перечисление с месяцем. {январь: зима, февраль: зима, ... июль: лето и т. д.}
Здесь есть несколько хороших ответов, но они устарели. Классы java.time значительно упрощают эту работу.
Мешающие старые классы, связанные с самыми ранними версиями Java, были вытеснены классами java.time, встроенными в Java 8 и более поздних версий. См. Учебник Oracle. Большая часть функциональности была перенесена на Java 6 и 7 в ThreeTen-Backport и в дальнейшем адаптирована для Android в ThreeTenABP.
MonthУчитывая, что сезоны здесь определены с использованием целых месяцев, мы можем использовать удобный Monthперечислить. Такие значения перечисления лучше, чем простые целочисленные значения (1–12), потому что они безопасны по типу и вам гарантированы допустимые значения.
EnumSetEnumSet - это быстрый способ с компактной памятью для отслеживания подмножества значений перечисления.
EnumSet<Month> spring = EnumSet.of( Month.MARCH , Month.APRIL );
EnumSet<Month> summer = EnumSet.of( Month.MAY , Month.JUNE , Month.JULY , Month.AUGUST );
EnumSet<Month> fall = EnumSet.of( Month.SEPTEMBER , Month.OCTOBER );
EnumSet<Month> winter = EnumSet.of( Month.NOVEMBER , Month.DECEMBER , Month.JANUARY , Month.FEBRUARY );
В качестве примера мы получаем текущий момент для определенного часового пояса.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( zoneId );
Спросите это значение даты и времени для его Month.
Month month = Month.from( zdt );
Посмотрите, какой сезон EnumSet имеет это конкретное значение месяца, вызвав contains.
if ( spring.contains( month ) ) {
…
} else if ( summer.contains( month ) ) {
…
} else if ( fall.contains( month ) ) {
…
} else if ( winter.contains( month ) ) {
…
} else {
// FIXME: Handle reaching impossible point as error condition.
}
Если вы используете эту идею сезона в своей базе кода, я предлагаю определить собственное перечисление «Season».
Базовое перечисление простое: public enum Season { SPRING, SUMMER, FALL, WINTER; }. Но мы также добавляем статический метод of для поиска того, какой месяц соответствует сезону.
package work.basil.example;
import java.time.Month;
public enum Season {
SPRING, SUMMER, FALL, WINTER;
static public Season of ( final Month month ) {
switch ( month ) {
// Spring.
case MARCH: // Java quirk: An enum switch case label must be the unqualified name of an enum. So cannot use `Month.MARCH` here, only `MARCH`.
return Season.SPRING;
case APRIL:
return Season.SPRING;
// Summer.
case MAY:
return Season.SUMMER;
case JUNE:
return Season.SUMMER;
case JULY:
return Season.SUMMER;
case AUGUST:
return Season.SUMMER;
// Fall.
case SEPTEMBER:
return Season.FALL;
case OCTOBER:
return Season.FALL;
// Winter.
case NOVEMBER:
return Season.WINTER;
case DECEMBER:
return Season.WINTER;
case JANUARY:
return Season.WINTER;
case FEBRUARY:
return Season.WINTER;
default:
System.out.println ( "ERROR." ); // FIXME: Handle reaching impossible point as error condition.
return null;
}
}
}
Или используйте функцию выражений переключения (JEP 361) Java 14.
package work.basil.example;
import java.time.Month;
import java.util.Objects;
public enum Season
{
SPRING, SUMMER, FALL, WINTER;
static public Season of ( final Month month )
{
Objects.requireNonNull( month , "ERROR - Received null where a `Month` is expected. Message # 0ac03df9-1c5a-4c2d-a22d-14c40e25c58b." );
return
switch ( Objects.requireNonNull( month ) )
{
// Spring.
case MARCH , APRIL -> Season.SPRING;
// Summer.
case MAY , JUNE , JULY , AUGUST -> Season.SUMMER;
// Fall.
case SEPTEMBER , OCTOBER -> Season.FALL;
// Winter.
case NOVEMBER , DECEMBER , JANUARY , FEBRUARY -> Season.WINTER;
}
;
}
}
Вот как использовать это перечисление.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now ( zoneId );
Month month = Month.from ( zdt );
Season season = Season.of ( month );
Выгрузить в консоль.
System.out.println ( "zdt: " + zdt + " | month: " + month + " | season: " + season );
zdt: 2016-06-25T18:23:14.695-04:00[America/Montreal] | month: JUNE | season: SUMMER
Простое решение
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeInMills);
int month = calendar.get(Calendar.MONTH);
CurrentSeason = month == 11 ? 0 : (month + 1) / 3;
Название вашего вопроса очень общее, поэтому большинство пользователей сначала думают об астрономических сезонах. Несмотря на то, что подробное содержание вашего вопроса ограничено настраиваемыми диапазонами дат, это ограничение может быть вызвано просто невозможностью вычислить астрономический случай, поэтому я осмеливаюсь опубликовать ответ на этот старый вопрос также для астрономического сценария.
И большинство ответов здесь основаны только на полных месяцах. Я даю здесь два примера для рассмотрения как астрономических сезонов, так и сезонов на основе произвольных диапазонов дат.
Здесь нам обязательно нужна дополнительная информация, конкретный часовой пояс или смещение, иначе мы не можем преобразовать мгновение (например, старомодный экземпляр java.util.Date вашего ввода) в локальное представление, используя комбинацию месяца и дня. Для простоты я предполагаю часовой пояс системы.
// your input
java.util.Date d = new java.util.Date();
ZoneId tz = ZoneId.systemDefault();
// extract the relevant month-day
ZonedDateTime zdt = d.toInstant().atZone(tz);
MonthDay md = MonthDay.of(zdt.getMonth(), zdt.getDayOfMonth());
// a definition with day-of-month other than first is possible here
MonthDay beginOfSpring = MonthDay.of(3, 1);
MonthDay beginOfSummer = MonthDay.of(5, 1);
MonthDay beginOfAutumn = MonthDay.of(9, 1);
MonthDay beginOfWinter = MonthDay.of(11, 1);
// determine the season
Season result;
if (md.isBefore(beginOfSpring)) {
result = Season.WINTER;
} else if (md.isBefore(beginOfSummer)) {
result = Season.SPRING;
} else if (md.isBefore(beginOfAutumn)) {
result = Season.SUMMER;
} else if (md.isBefore(beginOfWinter)) {
result = Season.FALL;
} else {
result = Season.WINTER;
}
System.out.println(result);
Я использовал простое вспомогательное перечисление вроде public enum Season { SPRING, SUMMER, FALL, WINTER; }.
Здесь нам также понадобится одна дополнительная информация, а именно, в северном или южном полушарии сейчас сезон. Моя библиотека Time4J предлагает следующее решение на основе предопределенного перечисления Астрономический сезон с использованием версии v5.2:
// your input
java.util.Date d = new java.util.Date();
boolean isSouthern = false;
Moment m = TemporalType.JAVA_UTIL_DATE.translate(d);
AstronomicalSeason result = AstronomicalSeason.of(m);
if (isSouthern) { // switch to southern equivalent if necessary
result = result.onSouthernHemisphere();
}
System.out.println(result);
Если нужен только номер сезона для северного полушария:
/**
* @return 1 - winter, 2 - spring, 3 - summer, 4 - autumn
*/
private static int getDateSeason(LocalDate date) {
return date.plus(1, MONTHS).get(IsoFields.QUARTER_OF_YEAR);
}
Через Как узнать квартал заданной даты?.
А вот как рассчитать сезонные границы для заданной даты:
private static LocalDate atStartOfSeason(LocalDate date) {
return date.plus(1, MONTHS).with(IsoFields.DAY_OF_QUARTER, 1).minus(1, MONTHS);
}
private static LocalDate afterEndOfSeason(LocalDate date) {
return atStartOfSeason(date).plus(3, MONTHS);
}
Через Как получить первую дату и последнюю дату текущего квартала в java.util.Date.
Просто проверяю, но вы понимаете, что у вас есть 2-месячные Spring и Осень и 4 месяца Лето и Зима?