java—如何在scala中获得上一年的相应季度

dldeef67  于 2021-05-19  发布在  Spark
关注(0)|答案(4)|浏览(631)

我有一个日期字符串,格式为“20202”[“yyyyq”]。有没有办法得到上一年的相应季度?
例如,20202年应该是20192年

vs91vp4v

vs91vp4v1#

我想用一些日期时间格式化程序来解决这个问题…
去吧!我会立即喜欢由阿文德库马尔阿维纳什使用解决方案 YearQuarter 三个额外的图书馆。如果你觉得在你的项目中添加一个外部库(或者你的团队或老板这么认为)太过分了,我们也可以不用它,只是不那么优雅。下面是一个java解决方案,我认为您可以手动转换为scala:

DateTimeFormatter quarterFormatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.YEAR, 4)
            .appendValue(IsoFields.QUARTER_OF_YEAR, 1)
            .parseDefaulting(IsoFields.DAY_OF_QUARTER, 1)
            .toFormatter();

    String quarterString = "20202";

    YearMonth firstMonthOfQuarter
            = YearMonth.parse(quarterString, quarterFormatter);
    YearMonth firstMonthOfQuarterLastYear = firstMonthOfQuarter.minusYears(1);
    String quarterPreviousYearString
            = firstMonthOfQuarterLastYear.format(quarterFormatter);

    System.out.println(quarterPreviousYearString);

输出是所需的:
20192

正确数据类型的优点

您能解释一下在这种情况下使用datetime比简单的字符串操作和转换为int有什么好处吗?
编辑:当你需要从输入中读取一些数字,例如一个身份证号码,并在输出时再次打印时,你是否将其读入 int 或者 String ? 大部分使用 int (或 long 或者 BigInteger ). 为什么?你的问题也差不多。
使用的优点 YearQuarter 或者 YearMonth 包括(可能不限于):
自解释代码: val d = "20202" 对这段数据的意义一无所知。类型的变量 YearQuarter 非常清楚地告诉读者,这个变量占一年的四分之一。 YearMonth 是标准java库中的最佳近似值,并且对于我们在这里使用它的原因已经不太清楚了,但是仍然有相当大的优势 String .
免费验证:通过使用格式化程序解析字符串,如果字符串不表示一年中的有效季度,我们一定会通过异常得到通知。
进一步验证便宜:如果您想要进一步验证,例如,季度必须在2019年第二季度之后,但不是在将来,这对于java.time来说是简单而直接的(它也可以用字符串来完成,但是代码将很难阅读,除非您通过几行注解来解释您要做的事情)。
为将来的需求做好准备:如果有一天你需要对这个季度做更多的事情,比如找到这个季度的第一天和最后一天,或者之前的那个季度,这将是一个在公园里散步的过程,因为这个课程提供了非常丰富的操作。

链接

oracle教程:date time解释如何使用java.time。

mwyxok5s

mwyxok5s2#

下面是一个简短的例子,展示了一种方法。

val d = "20202"
(d.substring(0,4).toInt - 1).toString + d.substring(4)  // 20192: String
qnyhuwrf

qnyhuwrf3#

更新(感谢ole v.v.)

下面给出的是纯的 DateTimeFormatter 解决方案:

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;

import org.threeten.extra.YearQuarter;

public class Main {
    public static void main(String[] args) {
        // Given string
        String str = "20202";

        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .appendValue(ChronoField.YEAR, 4)
                                .appendValue(IsoFields.QUARTER_OF_YEAR, 1)
                                .toFormatter();

        // Parse the converted string
        YearQuarter yearQuarter = YearQuarter.parse(str, dtf);
        System.out.println(yearQuarter.format(dtf));

        // A year ago
        System.out.println(yearQuarter.minusYears(1).format(dtf));
    }
}

输出:

20202
20192

原始答案:

我建议您使用threetenextra库。唯一需要解决的问题是将给定的字符串转换为 yyyy-Q 使用正则表达式可以轻松执行的格式,如下所示:

import java.time.format.DateTimeFormatter;

import org.threeten.extra.YearQuarter;

public class Main {
    public static void main(String[] args) {
        // Given string
        String str = "20202";

        // Convert the given string into yyyy-Q format
        str = str.replaceAll("(\\d{4})(\\d{1,2})", "$1-$2");

        // Parse the converted string
        YearQuarter yearQuarter = YearQuarter.parse(str, DateTimeFormatter.ofPattern("yyyy-Q"));

        // Define output format
        DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("uuuuQ");
        System.out.println(yearQuarter.format(outputFormat));

        // A year ago
        System.out.println(yearQuarter.minusYears(1).format(outputFormat));
    }
}

输出:

20202
20192

正则表达式的解释: (\\d{4})(\\d{1,2}) 指定两个组:第一个组有4个数字,第二个组有一个或两个数字
替换字符串 $1-$2 指定 group(1)-group(2)

plupiseo

plupiseo4#

其他答案的替代方法是使用我的lib time4j和它的类日历。例子:

String input = "20202";

    ChronoFormatter<CalendarQuarter> f =
        ChronoFormatter.ofPattern(
            "yyyyQ", 
            PatternType.CLDR, 
            Locale.ENGLISH, 
            CalendarQuarter.chronology());
    CalendarQuarter cq = f.parse(input);
    CalendarQuarter quarterInPreviousYear = cq.minus(Years.ONE);
    System.out.println(quarterInPreviousYear); // 2019-Q2

此解决方案的两个主要优点是:
日历季度也是间隔,所以很容易每天重复它们。
国际化支持90多种语言,甚至基于样式。
间隔示例:

for (PlainDate date : quarterInPreviousYear) {
        System.out.println(date);
    }

输出:

> 2019-04-01 
> 2019-04-02 
> 2019-04-03
> ...

丹麦语打印示例:

ChronoFormatter<CalendarQuarter> printer =
        ChronoFormatter.ofPattern(
            "QQQQ y", 
            PatternType.CLDR, 
            new Locale("da"), 
            CalendarQuarter.chronology());
    System.out.println(printer.print(quarterInPreviousYear)); // 2. kvartal 2019

相关问题