Java 如何从给定季度中获取月份

Java 如何从给定季度中获取月份,java,java-time,localdate,date,Java,Java Time,Localdate,Date,我想从某个季度中得到几个月。使用下面的代码,我成功地从LocalDate.now()实例获取了当前季度的月份名称 如何从一个季度字符串(例如“Q1”)中获取季度月份 int-monthhint=Month.from(LocalDate.now()).firstMonthOfQuarter().getValue(); 对于(int j=1;j对于quarty>firstmonth规则是 Q1 -> 1 Q2 -> 4 Q3 -> 7 Q4 -> 10 With math

我想从某个季度中得到几个月。使用下面的代码,我成功地从LocalDate.now()实例获取了当前季度的月份名称

如何从一个季度字符串(例如“Q1”)中获取季度月份

int-monthhint=Month.from(LocalDate.now()).firstMonthOfQuarter().getValue();

对于(int j=1;j对于
quarty>firstmonth
规则是

Q1 -> 1
Q2 -> 4
Q3 -> 7
Q4 -> 10

With math : quarterValue *3 -2
因此,在Java中应用这一点:

String quarter = "Q1";
int monthInt = Integer.parseInt(quarter.replaceAll("\\D", "")) * 3 - 2;
for (int j = 0; j < 3; j++) {
    System.out.println(Month.of(monthInt + j).name());
}
String quarter=“Q1”;
int-monthInt=Integer.parseInt(quarter.replaceAll(“\\D”,“”“))*3-2;
对于(int j=0;j<3;j++){
System.out.println(月份)(monthInt+j.name());
}

List quarters=Arrays.asList(“Q1”、“Q2”、“Q3”、“Q4”);
用于(字符串季度:季度){
系统输出打印(季度);
int-monthInt=Integer.parseInt(quarter.replaceAll(“\\D”,“”“))*3-2;
对于(int j=0;j<3;j++){
System.out.print(“+Month.of(monthhint+j.name());
}
System.out.println();
}
第一季度1月2月3月
第二季度4月5月6月
第三季度7月8月9月
第四季度10月11月12月

我们可以通过查看
IsoFields的
getFrom
声明来了解JDK是如何计算季度的

public long getFrom(TemporalAccessor temporal) {
    if (isSupportedBy(temporal) == false) {
        throw new UnsupportedTemporalTypeException("Unsupported field: QuarterOfYear");
    }
    long moy = temporal.getLong(MONTH_OF_YEAR);
    return ((moy + 2) / 3);
}
请注意它如何使用公式
quarty=(moy+2)/3
。因此,要找到一个季度的起始月份,我们只需要根据
moy
-
moy=quarty*3-2
对其进行重新排列

您可以编写如下方法:

private static List<String> monthNamesFromQuarter(int quarter) {
    // you can do the validation of quarter yourself
    int start = quarter * 3 - 2;
    return IntStream.range(start, start + 3)
            .mapToObj(Month::of)
            .map(Month::name)
            .collect(Collectors.toList());
}
    System.out.println(monthsPerQuarter.get("Q3"));
私有静态列表monthNamesFromQuarter(int quarter){
//您可以自己验证四分之一
int start=四分之一*3-2;
返回IntStream.range(开始,开始+3)
.mapToObj(年月日)
.map(月份::名称)
.collect(Collectors.toList());
}

我建议我们为每个季度包含的月份建立一个地图,并在需要某个季度字符串的月份时进行简单的地图查找。流管道和适当的
日期时间格式将在几行中建立这样一个地图:

static Map<String, List<Month>> monthsPerQuarter = Arrays.stream(Month.values())
        .collect(Collectors.groupingBy(
                DateTimeFormatter.ofPattern("QQQ", Locale.ENGLISH)::format));
输出为:

如果您需要单独的月份:

    monthsPerQuarter.get("Q4").forEach(System.out::println);
如果您的季度最初是1到4之间的数字,您可以使用此地图:

static Map<Integer, List<Month>> monthsPerQuarter = Arrays.stream(Month.values())
        .collect(Collectors.groupingBy(m -> m.get(IsoFields.QUARTER_OF_YEAR)));
这是11行代码,而不是4行,我看不到任何增益 将类与、、和一起使用

一月

YearQuarter
库中有一个类,您可能会发现它对这项工作很有用:

获取当前季度。我们需要一个时区来确定当前日期,从而确定当前季度。对于任何给定时刻,全球各地的日期因时区而异

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
YearQuarter currentYearQuarter = YearQuarter.now( z ) ;
但您希望通过解析字符串来确定季度

如果您的字符串样式类似于(标准实际上没有指定季度)
YYYY Qq
,则
YearQuarter
可以

如果只有季度部分而没有年份,请使用enum。如果输入字符串为
Q1
等,请使用来检索匹配的enum对象

String input = "Q1" ;
Quarter quarter = Quarter.valueOf( input ) ;
如果你有一个数字而不是字符串,也就是说,
1
2
3
4
,那么使用静态方法
Quarter.of
。顺便说一句,在你自己的代码中,你应该传递这些
Quarter
对象,而不仅仅是一个整数或字符串,以使你的代码更具自我文档化ovide类型安全,并确保有效值

int input = 1 ; // Domain: 1, 2, 3, 4. 
Quarter quarter = Quarter.of( input ) ;
将该
Quarter
实例应用于当前
YearQuarter
实例,以获得另一个
YearQuarter
实例。这些类使用该模式,因此我们不修改现有实例,而是生成新实例

YearQuarter yearQuarter = currentYearQuarter.with( quarter ) ;
年季度.toString():2019-Q1

从该年度季度获取第一个日期()、年度月份()和枚举对象

LocalDate firstDate = yearQuarter.atDay( 1 ) ;
YearMonth yearMonth1 = YearMonth.from( firstDate ) ;
YearMonth yearMonth2 = yearMonth1.plusMonths( 1 ) ;
YearMonth yearMonth3 = yearMonth1.plusMonths( 2 ) ;
生成包含月份名称的字符串

Locale locale = Locale.US ;  // Or Locale.CANADA_FRENCH and so on. 
String output1 = yearMonth1.getMonth().getDisplayName( TextStyle.FULL , locale ) ;
一月


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,如,&

要了解更多信息,请参阅.和搜索堆栈溢出以获取许多示例和解释。规范为

该项目现已启动,建议迁移到类

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
classes

从哪里获得java.time类

  • 、和更高版本-标准Java API的一部分,带有捆绑实现。
    • Java9添加了一些次要功能和修复
    • 大多数java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(如果我理解正确的话,从像
      Q1
      这样的季度字符串到月份名称的映射是恒定的,对吗?
      Q1
      总是表示一月到三月。我使用
      int quarty=LocalDate.now().get(IsoFields.quarter\u OF年)
      最初,IsoFields.QUARTER_OF_YEAR是常量,并将其设置为字符串。因此,您没有QUARTER字符串,而是QUARTER
      int
      ?我有一个QUARTER字符串,最初是int。非常感谢!我想知道是否有API解决方案,但这同样有效。有一个API可以找到季度的开始给你一个月的时间,但既然你说你有一个季度号,你需要在这里做一些数学运算。@XBLAZ3KX这是一个非常好而且干净的解决方案。谢谢!谢谢你的详细解释。仅供参考,
      季度上还有一个
      firstMonth()
      方法:
      YearQuarter                         // Represent an entire quarter of a specific year.
      .now( ZoneId.of( "Asia/Tokyo" ) )   // Determine the current quarter as seen via the wall-clock time used by the people of a particular region (a time zone). 
      .with(                              // Move to another quarter.
          Quarter.valueOf( "Q1" )         // Or, `Quarter.of( 1 )` if starting with an integer number rather than a `String` object.
      )                                   // Returns another `YearQuarter` object, rather than modifying the original.
      .atDay( 1 )                         // Returns a `LocalDate` object.
      .getMonth()                         // Returns a `Month` enum object.
      .getDisplayName(                    // Automatically localize the name of the month. 
          TextStyle.FULL ,                // How long or abbreviated do you want the translation.
          Locale.US                       // Or Locale.CANADA_FRENCH and so on. 
      )                                   // Returns a `String` object.
      
      ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
      YearQuarter currentYearQuarter = YearQuarter.now( z ) ;
      
      String input = "2020-Q1" ;
      YearQuarter yearQuarter = YearQuarter.parse( input ) ;
      
      String input = "Q1" ;
      Quarter quarter = Quarter.valueOf( input ) ;
      
      int input = 1 ; // Domain: 1, 2, 3, 4. 
      Quarter quarter = Quarter.of( input ) ;
      
      YearQuarter yearQuarter = currentYearQuarter.with( quarter ) ;
      
      LocalDate firstDate = yearQuarter.atDay( 1 ) ;
      YearMonth yearMonth1 = YearMonth.from( firstDate ) ;
      YearMonth yearMonth2 = yearMonth1.plusMonths( 1 ) ;
      YearMonth yearMonth3 = yearMonth1.plusMonths( 2 ) ;
      
      Locale locale = Locale.US ;  // Or Locale.CANADA_FRENCH and so on. 
      String output1 = yearMonth1.getMonth().getDisplayName( TextStyle.FULL , locale ) ;