有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java日期在同一天或同一个月

我需要编写一个方法,以YYYY-MM-DD格式将Date作为输入参数,并返回列表中所有在同一天的日期

列表中的日期如下所示:2020-06-09T07:10:28.1985307Z

我是否需要使用“-”split解析参数,并将字符串的MM部分与列表日期的MM部分进行比较?这似乎太复杂了,你能给我一些建议如何更好地解决这个问题吗


共 (4) 个答案

  1. # 1 楼答案

    您说“格式为YYYY-MM-DD”,这表明您实际得到的是字符串对象,而不是日期对象。日期、本地日期、实例等,它们没有格式。它们代表的是它们所命名的事物(除了日期,它被严重错误地命名了,实际上代表的是一个基于Epochmilis的无时区瞬间,与人类的日期概念完全没有任何关系)

    要处理日期,您需要。。有日期对象。或者更确切地说,是来自java.time包的正确类型。如果只是一个约会,那么您正在寻找LocalDate。这些都是无时区的。它们只是代表了,比如说,“1985年4月4日”的概念,而不涉及地点。您的输入不是日期。它们实际上是时间上的瞬间,因为这是一个精确指定的时间(6位数字代表秒分数),并且包括一个时区,这是一个人类甚至不用于正常目的的时区。这表明你真正想要的是Instant

    然后你想做一些非常奇怪的事情:检查日期。你把时间的概念和日期的概念混为一谈,日期根本不是时间的一刻。毕竟,如果荷兰是4月4日,纽约很可能是4月3日。如果说莫斯科是1917年10月25日,阿姆斯特丹是11月7日。如果不先本地化,试图将“日期”等同起来是毫无意义的。你在问谁?他们住在哪里

    有很多方法可以将java.time包中的各种类型从instant转换为dates,再转换回dates。这里有一种方法:

    public static Instant read(String in) {
        return Instant.parse(in);
    }
    
    public static LocalDate localize(Instant i, ZoneId zone) {
        return i.atZone(zone).toLocalDate();
    }
    
    public static void main(String[] args) throws Exception {
        Instant a = Instant.parse("2020-06-09T07:10:28.1985307Z");
        Instant b = Instant.parse("2020-04-09T07:10:28.1985307Z");
        Instant c = Instant.parse("2020-06-09T23:10:28.1985307Z");
    
        ZoneId ams = ZoneId.of("Europe/Amsterdam");
    
        LocalDate aDate = localize(a, ams);
        LocalDate bDate = localize(b, ams);
        LocalDate cDate = localize(c, ams);
    
        System.out.println(aDate.isEqual(cDate));
    }
    

    上述内容最终将打印为“假”。2020-06-09T07:10:28.1985307Z描述的时间瞬间被阿姆斯特丹的某个人描述为2020年6月9日。瞬间2020-06-09T23:10:28.1985307Z将被描述为第10个(正如阿姆斯特丹在当时的+0200)。把这个区域换到纽约,答案会是正确的

    “这两个瞬间是同一个日期吗”这个问题不是一个理智的问题,除非在这个问题中还包括哪个区域在问。请注意,UTC本身就是一个区域,您可以使用它:ZoneId utc = ZoneOffset.UTC;将使您到达该区域

  2. # 2 楼答案

    如果不确定时区,这是不可能的。地球上的任何地方都不是同一个日期,所以你的列表中的某个时间点是在这个日期,那个日期,甚至是另一个日期,都取决于时区。这也意味着新的一个月在不同时区的不同时间开始。如果我还记得的话,有一个国家甚至在大约20年前改变了时区,以便成为第一个进入新千年的国家

    我随机选择了一个时区。您只需选择您喜欢的时区,并将其替换到我下面的代码中即可。我依次回答你的两个问题:

    1. 找出同一天的时刻
    2. 找出同一个月的时刻

    同一天发生的时刻

        ZoneId zone = ZoneId.of("Africa/Kinshasa");
    
        List<Instant> theList = List.of(
                Instant.ofEpochSecond(1_590_965_000),
                Instant.ofEpochSecond(1_590_966_000),
                Instant.ofEpochSecond(1_592_002_800),
                Instant.ofEpochSecond(1_592_089_100),
                Instant.ofEpochSecond(1_593_557_000),
                Instant.ofEpochSecond(1_593_558_000));
        System.out.println("The gross list");
        theList.forEach(System.out::println);
    
        LocalDate userInput = LocalDate.parse("2020-06-13");
    
        List<Instant> sameDay = theList.stream()
                .filter(i -> i.atZone(zone).toLocalDate().equals(userInput))
                .collect(Collectors.toList());
        System.out.println("Same day: " + sameDay);
    

    输出为:

    The gross list
    2020-05-31T22:43:20Z
    2020-05-31T23:00:00Z
    2020-06-12T23:00:00Z
    2020-06-13T22:58:20Z
    2020-06-30T22:43:20Z
    2020-06-30T23:00:00Z
    Same day: [2020-06-12T23:00:00Z, 2020-06-13T22:58:20Z]
    

    如果您的时刻还不是Instant对象,请在使用它们执行任何其他操作之前,使用Instant.parse将它们转换为Instant。刚果与UTC(全年)的偏移量为+01:00,因此2020-06-12T23:00:00Z等于2020-06-13T00:00:00+01:00[非洲/金沙萨],因此在6月13日也一样

    在同一个月发生的时刻

    代码非常相似

        YearMonth userMonth = YearMonth.from(userInput);
        List<Instant> sameMonth = theList.stream()
                .filter(i -> YearMonth.from(i.atZone(zone)).equals(userMonth))
                .collect(Collectors.toList());
        System.out.println(sameMonth);
    

    [2020-05-31T23:00:00Z, 2020-06-12T23:00:00Z, 2020-06-13T22:58:20Z, 2020-06-30T22:43:20Z]

    AYearMonth是类名所说的,一年一个月。我认为这是一门正确的课程,可以代表你的同月

    链接

    Oracle tutorial: Date Time解释如何使用java。时间

  3. # 3 楼答案

    日期类已过时。对解决方案使用LocalDate和ZoneDateTime

    public class Test {
    
        public static void main(String[] args){
            Test t = new Test();
            List<LocalDate> result = t.fetchDates(LocalDate.parse("2020-06-09"));
            System.out.println(result);
        }
    
        private List<ZonedDateTime> datesList = List.of(
                ZonedDateTime.parse("2020-06-09T07:10:28.1985307Z"),
                ZonedDateTime.parse("2020-06-01T01:10:28.1985307Z"),
                ZonedDateTime.parse("2020-06-09T01:10:28.1985307Z"),
                ZonedDateTime.parse("2020-06-08T01:10:28.1985307Z"),
                ZonedDateTime.parse("2020-06-09T01:10:28.1985307Z")
                );
    
    
        public List<LocalDate> fetchDates(LocalDate date)
        {
            return datesList.stream()
                    .filter(zdt -> zdt.toLocalDate().equals(date))
                    .map(zdt -> zdt.toLocalDate())
                    .collect(Collectors.toList());
        }
    }
    

    印刷品[2020-06-092020-06-092020-06-09]

  4. # 4 楼答案

    1-将输入字符串转换为LocalDate

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    
    
    LocalDate date = LocalDate.parse(str, formatter);
    

    2-使用LocalDate,您可以执行许多操作,例如检索当前日期、月份、年份等。解析所有日期并实现您的逻辑,以下是一些相关方法:

        date.getDayOfYear();
        date.minusMonths();
        date.isBefore();