Java 如何从给定季度中获取月份
我想从某个季度中得到几个月。使用下面的代码,我成功地从LocalDate.now()实例获取了当前季度的月份名称 如何从一个季度字符串(例如“Q1”)中获取季度月份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
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字符串,而是QUARTERint
?我有一个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 ) ;