使用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

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

似乎只是检查月份会做:

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. 

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

java.time

与最早版本的Java捆绑在一起的麻烦的旧类已被Java 8及更高版本中内置的java.time类所取代。 请参阅Oracle教程 。 许多function已经在ThreeTen-Backport中移植到Java 6和7中,并在ThreeTenABP中进一步适应Android。

Month

鉴于这里使用整月来定义季节,我们可以使用方便的Month 枚举 。 这样的枚举值优于纯整数值(1-12),因为它们是类型安全的并且保证有效值。

EnumSet

EnumSet是一种快速执行且紧凑的内存方式,用于跟踪枚举值的子集。

 EnumSet spring = EnumSet.of( Month.MARCH , Month.APRIL ); EnumSet summer = EnumSet.of( Month.MAY , Month.JUNE , Month.JULY , Month.AUGUST ); EnumSet fall = EnumSet.of( Month.SEPTEMBER , Month.OCTOBER ); EnumSet 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. } 

定义自己的“季节”枚举

如果您在代码库中使用本季创意,我建议您定义自己的枚举“Season”。

基本的枚举很简单: public enum Season { SPRING, SUMMER, FALL, WINTER; } public enum Season { SPRING, SUMMER, FALL, WINTER; } 。 但我们还添加了一种静态方法来查找哪个月映射到哪个季节。

 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月| 季节:夏天

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

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

 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. // ie 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; } 

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

好吧,它可以很简单

 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 months) { this.monthlist = months; } private List 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"); } } 
 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"); } } 

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

因为在这个范围内所有季节都是整整几个月,你可以用你的约会月份来切换:

 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)将日期转换为日历)

简单解决方案

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