使用Java从Date中识别季节

时间:2008-10-09 22:37:41

标签: java date

我从来没有什么好运,所以为什么不再试一次?

我的应用程序需要根据一年中的季节(春季,夏季,冬季,秋季)显示不同的图像。这些季节我有非常具体的开始和结束日期。

我想要的天才是一种名为GetSeason的方法,它以日期作为输入并返回Spring,Summer,W​​inter或Fall的String值。以下是日期范围及其相关季节:

春季:3 / 1-4 / 30
夏季:5 / 1-8 / 31
掉落:9/1〜10/31
冬季:11 / 1-2 / 28

有人能提供一种工作方法来恢复正常的季节吗? 谢谢大家!

11 个答案:

答案 0 :(得分:6)

似乎只是检查月份会这样做:

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.

答案 1 :(得分:3)

这里有一些好的答案,但它们已经过时了。 java.time类使这项工作变得更加容易。

java.time

与最早版本的Java捆绑在一起的麻烦的旧类已被Java 8及更高版本中内置的java.time类所取代。见Oracle Tutorial。许多功能已经被后端移植到Java 6& ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。

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

通过调用contains来查找哪个季节EnumSet具有该特定月份值。

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

zdt:2016-06-25T18:23:14.695-04:00 [美国/蒙特利尔] |月:6月|季节:夏天

答案 2 :(得分:1)

嗯,它可以像

一样简单
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";
      }
}

我在评论中被谴责为更好的解决方案:枚举:

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

答案 3 :(得分:1)

我感到光顾,但受宠若惊。所以我会这样做。

这不仅检查月份,还检查月份。

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

我确信这很可怕,可以改进。请在评论中告诉我。

答案 4 :(得分:1)

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


 }

}

答案 5 :(得分:1)

尝试使用哈希表或枚举。您可以将日期转换为某个值(jan 1为1,...),然后为某个字段创建bin。或者你可以用月份做一个枚举。 {1月:冬天,2月:冬天,... 7月:夏天等}}

答案 6 :(得分:0)

因为在这个范围内,所有季节都是整整几个月,您可以使用您日期的月份进行切换:

switch (date.getMonth()) {
    case Calendar.JANUARY:
    case Calendar.FEBRUARY:
         return "winter";
    case Calendar.MARCH:
         return "spring";
    //etc
}

我建议使用所有12个日历常量完成整个开关,而不是最后一个的默认值。然后,您可以确保输入正确,例如

default:
 throw new IllegalArgumentException();

最后。

根据您的使用情况,您可能还想在本季使用枚举,而不是简单的字符串。

请注意,不推荐使用Date.getMonth()方法,而应使用java.util.Calendar.get(Calendar.MONTH)。 (只需使用calendar.setDate(yourDate)将日期转换为日历)

答案 7 :(得分:0)

简单的解决方案

 Calendar calendar = Calendar.getInstance();
 calendar.setTimeInMillis(timeInMills);
 int month = calendar.get(Calendar.MONTH);
 CurrentSeason = month == 11 ? 0 : (month + 1) / 3;

答案 8 :(得分:0)

您的问题的标题非常笼统,因此大多数用户会首先想到天文季节。即使您问题的详细内容仅限于自定义日期范围,但这种限制可能仅是由于无法计算天文个案引起的,因此我也敢针对天文场景针对这一老问题发布答案。

这里的大多数答案仅基于完整的月份。我在这里举两个例子来说明天文季节和基于任意日期范围的季节。

a)将任意日期范围映射到季节

在这里我们肯定需要其他信息,具体的时区或偏移量,否则我们将无法使用以下信息将即时信息(例如输入的老式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; }

b)天文季节

在这里,我们还需要一个额外的信息,即季节是在北半球还是在南半球。我的库Time4J使用预定义的枚举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);

答案 9 :(得分:0)

如果只需要北半球的季节编号:

/**
 * @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);
}

通过How do I discover the Quarter of a given Date?


这是如何计算给定日期的季节范围:

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

通过How to get the first date and last date of current quarter in java.util.Date

答案 10 :(得分:0)

import java.util.Scanner;

public class Season {

public static void main (String[] args) {

    Scanner sc = new Scanner(System.in);

    System.out.println("Enter the month:");

        int mon=sc.nextInt();

        if(mon>12||mon<1)
        {
            System.out.println("Invalid month");
        }

        else if(mon>=3&&mon<=5)
        {
            System.out.println("Season:Spring");
        }

        else if(mon>=6&&mon<=8)
        {
            System.out.println("Season:Summer");
        }

        else if(mon>=9&&mon<=11)
        {
            System.out.println("Season:Autumn");
        }

        else if(mon==12||mon==1||mon==2)
        {
            System.out.println("Season:Winter");
        }
}
}