Определение сезона по дате с использованием Java - PullRequest
1 голос
/ 10 октября 2008

У меня не было ничего, кроме удачи от SO, так почему бы не попробовать еще раз?

У меня есть приложение, которое должно показывать другое изображение в зависимости от времени года (весна, лето, зима, осень). У меня есть очень конкретные даты начала и окончания этих сезонов.

Что бы я хотел от ваших гениев, так это метод GetSeason, который принимает в качестве даты дату и возвращает строковое значение Spring, Summer, Winter или Fall. Вот диапазоны дат и связанные с ними сезоны:

Пружина: 3 / 1-4 / 30
Лето: 5 / 1-8 / 31
Падение: 9 / 1-10 / 31
Зима: 11 / 1-2 / 28

Может ли кто-нибудь предоставить метод работы, чтобы вернуть соответствующий сезон? Спасибо всем!

Ответы [ 9 ]

6 голосов
/ 10 октября 2008

Похоже, что просто проверка месяца сделает:

private static final String seasons[] = {
    "Winter", "Winter",
    "Spring", "Spring", "Spring",
    "Summer", "Summer", "Summer",
    "Fall", "Fall", "Fall",
    "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.
3 голосов
/ 26 июня 2016

Некоторые хорошие ответы здесь, но они устарели. Классы java.time значительно облегчают эту работу.

java.time

Мучительные старые классы, включенные в ранние версии Java, были вытеснены классами java.time , встроенными в Java 8 и более поздние версии. См. Oracle Tutorial . Большая часть функциональности была перенесена в Java 6 & 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP .

Month

Учитывая, что времена года здесь определяются с использованием целых месяцев, мы можем использовать удобный Month enum . Такие перечисляемые значения лучше, чем простые целочисленные значения (1-12), потому что они являются типобезопасными и вам гарантированы допустимые значения.

EnumSet

EnumSet - это быстродействующий и компактный способ отслеживания подмножества значений перечисления.

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.
}

Определите свой собственный список "Сезон"

Если вы используете идею этого сезона в своей базе кода, я предлагаю определить ваше собственное перечисление «Сезон».

Базовое перечисление простое: public enum Season { SPRING, SUMMER, FALL, WINTER; }. Но мы также добавляем статический метод of, чтобы выполнить поиск того, какой месяц соответствует какому сезону.

package com.example.javatimestuff;

import java.time.Month;

public enum Season {
    SPRING, SUMMER, FALL, WINTER;

    static public Season of ( 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;
        }
    }

}

Вот как использовать это перечисление.

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 );

дата: 2016-06-25T18: 23: 14.695-04: 00 [Америка / Монреаль] | месяц: июнь | сезон: лето

1 голос
/ 24 июля 2014

Попробуйте использовать хеш-таблицы или перечисления. Вы можете преобразовать дату в некоторое значение (jan 1 равно 1, ...), а затем создать ячейки для определенного поля. или вы можете сделать перечисление с месяцем. {январь: зима, февраль: зима, ... июль: лето и т. д.}

1 голос
/ 27 ноября 2010
import java.util.Scanner;

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) && (day >= 20 ))
   System.out.println("The season is Spring");

  else if ( (month == 6) && (day <= 20 ))
   System.out.println("The season is Spring");

  else if ( (month == 6) && (day >= 21 ))
   System.out.println("The season is Summer");

  else if ( (month == 9) && (day <= 20 ))
   System.out.println("The season is Summer");

  else if ( (month == 9) && (day >= 21 ))
   System.out.println("The season is Autumn");

  else if ( (month == 12) && (day <= 21 ))
   System.out.println("The season is Autumn");

  else if ( (month == 12) && (day >= 22 ))
   System.out.println("The season is Winter");


 }

}
1 голос
/ 10 октября 2008

Я чувствую покровительство, но польщен. так что я сделаю это.

Это проверяет не только месяц, но и день месяца.

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;
}

Я уверен, что это отвратительно и может быть улучшено. дайте мне знать в комментариях.

1 голос
/ 10 октября 2008

Ну, это может быть так же просто, как

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");
    }
}
0 голосов
/ 07 декабря 2018

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

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

а) отображение произвольных диапазонов дат на времена года

Здесь нам определенно нужна дополнительная информация, конкретный часовой пояс или смещение, иначе мы не сможем перевести момент (например, старомодный 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 предлагает следующее решение на основе предопределенного enum AstronomicalSeason с использованием версии 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);
0 голосов
/ 01 сентября 2016

Простое решение

 Calendar calendar = Calendar.getInstance();
 calendar.setTimeInMillis(timeInMills);
 int month = calendar.get(Calendar.MONTH);
 CurrentSeason = month == 11 ? 0 : (month + 1) / 3;
0 голосов
/ 10 октября 2008

, так как в этом диапазоне все сезоны являются полными месяцами, вы можете переключаться на месяц с даты:

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))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...