Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
每15分钟的Java日期时间比较_Java_Date_Datetime - Fatal编程技术网

每15分钟的Java日期时间比较

每15分钟的Java日期时间比较,java,date,datetime,Java,Date,Datetime,我有一个csv记录,时间戳为或每5分钟一次: - 2015/05/19 16:15:00 - 2015/05/19 16:20:00 - 2015/05/19 16:35:00 - 2015/05/19 16:10:00 - 2015/05/19 16:55:00 ArrayList<String> per15Min = new ArrayList<String>() {{ add("00,15"); add("15,30"); add("30,

我有一个csv记录,时间戳为或每5分钟一次:

- 2015/05/19 16:15:00
- 2015/05/19 16:20:00
- 2015/05/19 16:35:00
- 2015/05/19 16:10:00
- 2015/05/19 16:55:00
ArrayList<String> per15Min = new ArrayList<String>() {{
    add("00,15");
    add("15,30");
    add("30,45");
    add("45,00");
}};
我使用数组来比较每条记录的日期是否在15分钟内:

- 2015/05/19 16:15:00
- 2015/05/19 16:20:00
- 2015/05/19 16:35:00
- 2015/05/19 16:10:00
- 2015/05/19 16:55:00
ArrayList<String> per15Min = new ArrayList<String>() {{
    add("00,15");
    add("15,30");
    add("30,45");
    add("45,00");
}};
我需要的是,如果时间戳(每5分钟)在15分钟数组内,它将进入以下条件:

00-10 minutes must enter at 00,15
15-25 minutes must enter at 15,30
30-40 minutes must enter at 30,45
45-55 minutes must enter at 45,00

有人知道if条件有什么问题吗?

任何时候你需要处理日期/时间信息,你都应该使用合适的API,在你的情况下你可以避开日期和日历,但是如果可以的话最好使用Java 8的时间API或者Joda time,因为交互比日历更简单

字符串
日期值转换为
日期
s或(更好的是)
LocalDateTime
值,并使用它们的比较方法

  • 日期#在
    之前,
    日期#在
    之后,
    日期#等于
  • LocalDateTime#在
    之前,
    LocalDateTime#在
    之后,
    LocalDateTime#等于
例如

List<String> listOfDateValues = new ArrayList<>(25);
listOfDateValues.addAll(Arrays.asList(
                new String[]{"2015/05/19 16:10:00",
                    "2015/05/19 16:00:00",
                    "2015/05/19 16:05:00",
                    "2015/05/19 16:10:00",
                    "2015/05/19 16:15:00",
                    "2015/05/19 16:20:00",
                    "2015/05/19 16:25:00",
                    "2015/05/19 16:30:00",
                    "2015/05/19 16:35:00",
                    "2015/05/19 16:40:00",
                    "2015/05/19 16:45:00",
                    "2015/05/19 16:50:00",
                    "2015/05/19 16:55:00",
                    "2015/05/19 16:25:00"}));

List<String> per15Min = new ArrayList<>(
                Arrays.asList(
                                new String[]{
                                    "00,15",
                                    "16,30",
                                    "31,45",
                                    "46,59" //??
                                }
                )
);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
Map<String, List<String>> mapGroups = new HashMap<>();
for (String dateValue : listOfDateValues) {

    LocalDateTime ldt = LocalDateTime.parse(dateValue, formatter);
    for (String range : per15Min) {
        String[] split = range.split(",");
        LocalDateTime startRange = ldt.withMinute(Integer.parseInt(split[0])).withSecond(0).withNano(0);
        LocalDateTime endRange = ldt.withMinute(Integer.parseInt(split[1])).withSecond(59).withNano(999999999);
        if ((ldt.equals(startRange) || ldt.isAfter(startRange))
                        && (ldt.equals(endRange) || ldt.isBefore(endRange))) {
            List<String> group = mapGroups.get(range);
            if (group == null) {
                group = new ArrayList<String>(25);
                mapGroups.put(range, group);
            }
            group.add(dateValue);
        }
    }

}

for (String range : per15Min) {
    List<String> group = mapGroups.get(range);
    System.out.println(range);
    for (String dateValue : group) {
        System.out.println(" -> " + dateValue);
    }
}

注意,我已经修改了你的游骑兵,范围为
00-15
15-30
…时间
xx:15.00
到哪里去了?在这两个集合中?

任何时候需要处理日期/时间信息时,您都应该使用适当的API,在您的情况下,您可以使用
date
Calendar
,但如果可以,最好使用Java8的时间API或Joda time,因为交互比
Calendar
更简单

字符串
日期值转换为
日期
s或(更好的是)
LocalDateTime
值,并使用它们的比较方法

  • 日期#在
    之前,
    日期#在
    之后,
    日期#等于
  • LocalDateTime#在
    之前,
    LocalDateTime#在
    之后,
    LocalDateTime#等于
例如

List<String> listOfDateValues = new ArrayList<>(25);
listOfDateValues.addAll(Arrays.asList(
                new String[]{"2015/05/19 16:10:00",
                    "2015/05/19 16:00:00",
                    "2015/05/19 16:05:00",
                    "2015/05/19 16:10:00",
                    "2015/05/19 16:15:00",
                    "2015/05/19 16:20:00",
                    "2015/05/19 16:25:00",
                    "2015/05/19 16:30:00",
                    "2015/05/19 16:35:00",
                    "2015/05/19 16:40:00",
                    "2015/05/19 16:45:00",
                    "2015/05/19 16:50:00",
                    "2015/05/19 16:55:00",
                    "2015/05/19 16:25:00"}));

List<String> per15Min = new ArrayList<>(
                Arrays.asList(
                                new String[]{
                                    "00,15",
                                    "16,30",
                                    "31,45",
                                    "46,59" //??
                                }
                )
);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
Map<String, List<String>> mapGroups = new HashMap<>();
for (String dateValue : listOfDateValues) {

    LocalDateTime ldt = LocalDateTime.parse(dateValue, formatter);
    for (String range : per15Min) {
        String[] split = range.split(",");
        LocalDateTime startRange = ldt.withMinute(Integer.parseInt(split[0])).withSecond(0).withNano(0);
        LocalDateTime endRange = ldt.withMinute(Integer.parseInt(split[1])).withSecond(59).withNano(999999999);
        if ((ldt.equals(startRange) || ldt.isAfter(startRange))
                        && (ldt.equals(endRange) || ldt.isBefore(endRange))) {
            List<String> group = mapGroups.get(range);
            if (group == null) {
                group = new ArrayList<String>(25);
                mapGroups.put(range, group);
            }
            group.add(dateValue);
        }
    }

}

for (String range : per15Min) {
    List<String> group = mapGroups.get(range);
    System.out.println(range);
    for (String dateValue : group) {
        System.out.println(" -> " + dateValue);
    }
}

注意,我已经修改了你的游骑兵,范围为
00-15
15-30
…时间
xx:15.00
到哪里去了?在这两组代码中?

您提供的代码显示了许多不良气味(或反模式):计算机科学家通过经验发现的模式会导致许多问题

最大的问题是您依赖于字符串格式和解析

只对文本使用字符串,而不是作为元组、日期等各种数据的中间表示形式

特别是对于文化相关的概念,如Date的,这可能会导致完全混乱。例如,某些文化可能不使用阿拉伯数字(如
12
)书写日期,但例如使用罗马数字(如
XII
)。或者,在某个时间点,年份将不再可以用四位数字表示,或者一位使用时区
12:15:57 UTC+01
解析日期,但在格式化和解析过程中,时区会丢失。一般来说,使用字符串处理进行数据处理是一个坏主意,只有当数据是text/names/strings/…时才这样做

接下来,您似乎存储了
15
的倍数,这有点没用了。这将减缓这一进程

不要显式地存储倍数等,只使用蛮力方法(如果绝对必要,可以枚举元素)

在这个回答中,我提出了两种方法:
dateFloor(dated,int m)
datecel(Date d,int m)
。您可以将分钟数传递给您,在本例中,
15
作为设置粒度的额外参数

public static Date dateFloor (Date d, int m) {
    Date d2 = (Date) d.clone();
    d2.setMinutes((d2.getMinutes()/m)*m);
    return d2;
}

public static Date dateCeil (Date d, int m) {
    Date d2 = (Date) d.clone();
    d2.setMinutes(((d2.getMinutes()+m)/m)*m);
    //alternatively: d2.setMinutes((d2.getMinutes()/m)*m+m);
    return d2;
}
DateFloor
可以计算
日期之前的
,并模拟
dateceli
计算
日期之后的

使用这些方法,方法非常简单:

Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
    String line = sc.nextLine();
    Date date = csvDateFormat.parse(line);
    Date before = dateFloor(date,15);
    Date after = dateCeil(date,15);
    System.out.print(before);
    System.out.print(" <= ");
    System.out.print(date);
    System.out.print(" < ");
    System.out.println(after);
 }
其他错误 您犯的一个概念性错误是,当您将日期格式化为字符串,并尝试生成最后的
15
minutes部分时,它会将
00
附加到该部分,导致时间低于实际时间,因为您的方法不会先增加小时数

附加建议
您可以将I/O与计算某些内容的方法混合使用。控制器模式要求您必须拆分这些关注点。此外,您最好使用csv解析器。如果您使用像
“foo,bar”这样的字符串,baz
.csv
文件中,您将在
foo
bar
之间进行分割。这不符合标准。

您提供的代码显示了许多不良气味(或反模式):计算机科学家通过经验发现的模式会导致许多问题

最大的问题是您依赖于字符串格式和解析

只对文本使用字符串,而不是作为元组、日期等各种数据的中间表示形式

特别是对于依赖于文化的概念,如日期,这可能会导致完全混乱。例如,某些文化可能不使用阿拉伯数字(如
12
),但例如使用罗马数字(如
XII
)。或者,在某个时间点,年份将不再可以用四位数字表示,或者一位使用时区
12:15:57 UTC+01
解析日期,但在格式化和解析过程中时区丢失。通常,使用字符串处理进行数据处理是一个坏主意,只有在数据为文本/名称时才这样做/字符串/

接下来,您似乎要存储多个
15
,这有点没用。这会减慢进程

不要显式地存储倍数等,只使用蛮力方法(如果绝对必要,可以枚举元素)

在这个回答中,我提出了两种方法:
dateFloor(dated,int m)
dateceli(Date d,int m)
。您可以将分钟数作为一个额外的pa传递
Tue May 19 16:15:00 GMT 2015 <= Tue May 19 16:15:00 GMT 2015 < Tue May 19 16:30:00 GMT 2015
Tue May 19 16:15:00 GMT 2015 <= Tue May 19 16:20:00 GMT 2015 < Tue May 19 16:30:00 GMT 2015
Tue May 19 16:30:00 GMT 2015 <= Tue May 19 16:35:00 GMT 2015 < Tue May 19 16:45:00 GMT 2015
Tue May 19 16:00:00 GMT 2015 <= Tue May 19 16:10:00 GMT 2015 < Tue May 19 16:15:00 GMT 2015
Tue May 19 16:45:00 GMT 2015 <= Tue May 19 16:55:00 GMT 2015 < Tue May 19 17:00:00 GMT 2015
while ((perLine = br.readLine()) != null) {

    // Split row per column
    String[] perColumn = perLine.split(",", -1);

    // Convert unix date to yyyyMMddHHmm
    java.util.Date time = new java.util.Date(Long.parseLong(perColumn[0]) * 1000);

    String csvDateNoDay = fileDateFormat.format(time).substring(0,10);
    long csvDateYsDay = fileDateFormat.parse(fileDateFormat.format(time)).getTime();

    // Date of the file to be created/used
    String fileDate = "";
    String fileUnixDate = "";

    for (int j = 0 ; j < per15Min.size() ; j++) {
        String[] s = per15Min.get(j).split(",", -1);
        long isBeforeDate = fileDateFormat.parse(csvDateNoDay + s[0]).getTime();
        long isAfterDate = fileDateFormat.parse(csvDateNoDay + s[1]).getTime();

        /* Compare the Date for each record versus the list of array:
         * Record (Minutes) Array  Filename Date
         *     00 - 14       00    yyyyMMddHH00
         *     15 - 29       15    yyyyMMddHH15
         *     30 - 44       30    yyyyMMddHH30
         *     45 - 59       45    yyyyMMddHH45
         */     
        if ((csvDateYsDay>isBeforeDate && csvDateYsDay<isAfterDate) || csvDateYsDay==isBeforeDate) { 
            fileDate = csvDateNoDay + s[0];
            fileUnixDate = String.valueOf(isBeforeDate);
        }    
    }
}