Java 像普通整数一样减去数字字符

Java 像普通整数一样减去数字字符,java,string,subtraction,Java,String,Subtraction,我有两个字符串,可以看作时间戳: String min="2017-04-15 13:27:31"; String max="2017-04-15 13:40:01"; 假设我们想找出从第一个时间戳到第二个时间戳所经过的时间。如果只包含时间而不包含日期,我可以使用以下代码获取: String[] partsMin=min.split(":"); String[] partMax=max.split(":");

我有两个字符串,可以看作时间戳:

String min="2017-04-15 13:27:31";
String max="2017-04-15 13:40:01";
假设我们想找出从第一个时间戳到第二个时间戳所经过的时间。如果只包含时间而不包含日期,我可以使用以下代码获取:

                String[] partsMin=min.split(":");
                String[] partMax=max.split(":");
                int diffZero=Integer.parseInt(partMax[0])-Integer.parseInt(partsMin[0]);                
                int diffOne=Integer.parseInt(partMax[1])-Integer.parseInt(partsMin[1]);
                int diffOTwo=Integer.parseInt(partMax[2])-Integer.parseInt(partsMin[2]);
                diffInSec=diffZero*3600+diffOne*60+diffOTwo;

这就是问题所在。如何在时间戳内有日期的情况下完成作业?

在代码中执行此操作:

int diffZero=Integer.parseInt(partMax[0])
与执行以下操作相同:

int diffZero=Integer.parseInt("2017-04-15")
正在生成异常(NumberFormatException)

您最好尝试将那些字符串min和max解析为日期

编辑: 您可以检查代码/变量:并看到拆分为“:”不会返回正确的数组,因为索引0处的元素包含的信息比您需要的多

但正如我之前所说的,你走错了路,不要重新发明轮子,看看使用java为我们提供的API会有多实际:

String min = "2017-04-15 13:27:31";
String max = "2017-04-15 13:40:01";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTimeMin = LocalDateTime.parse(min, formatter);
LocalDateTime dateTimeMax = LocalDateTime.parse(max, formatter);
long days = ChronoUnit.DAYS.between(dateTimeMin, dateTimeMax);
long minutes = ChronoUnit.MINUTES.between(dateTimeMin, dateTimeMax);

System.out.println(days);
System.out.println(minutes);

我将从中构造LocalDateTime实例。 然后我将从中获取毫秒数,并从EndTime中减去startTime。 剩下的是两者之间经过的毫秒数。DateTimeFormatter对此也很有帮助

String strMin = "2017-04-15 13:27:31";
DateTimeFormatter formatterTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTimeMin = LocalDateTime.parse(strMin, formatter);

String strMax = "2017-04-15 13:40:01";
LocalDateTime dateTimeMax = LocalDateTime.parse(strMax, formatter);

long minutes = ChronoUnit.MINUTES.between(dateMin, dateMaxto);
long hours = ChronoUnit.HOURS.between(dateMin, dateMax);
如果要获取毫秒数,请执行以下操作:


长毫秒间隔=dateMax.toEpochMilli()-dateMax.toEpochMilli()

使用java日期时间库(即使是旧的
date
类也可以)将字符串解析为适当的对象

根据您选择的日期时间库,您可以查看它们之间的差异。最简单的方法是:

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
 Date date1 = sdf.parse(str1);
 Date date2 = sdf.parse(str2);
 long differenceInSeconds = (date2.getTime()-date1.getTime())/1000;

新的Java8时间类也可以让您做到这一点,并且最好继续学习。但是,我记不起它的语法了。

您是否尝试过像这样替换字符串的所有其他部分:

String[] partsMin = min.replaceAll("\\d+-\\d+-\\d+", "").trim().split(":");
String[] partMax = max.replaceAll("\\d+-\\d+-\\d+", "").trim().split(":");

使用SimpleDataFormat解析日期字符串,并对日期结果进行操作,您将得到正确的值。这对于“2017-02-28 23:59:59”和“2017-03-01 00:00:01”之间的日期很有效

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = format.parse("2017-02-28 23:59:59");
Date date2 = format.parse("2017-03-01 00:00:01");

long time1 = date1.getTime();
long time2 = date2.getTime();

long diff = time2 - time2; // should be 2000

您可以使用regex
(\d{2}):(\d{2}):(\d{2})
并提取
$1
$1
$3
您熟悉Java8
DateTimeFormatter
类吗?这就是它的目的。@DawoodibnKareem不,我不是。@backslax不起作用。对了,对不起,我在回答别人的问题时分心了。正确使用的类是
DateTimeFormatter
,它取代了(现在已经过时的)
SimpleDateFormat
。你可以查一下地图,看看如何使用它。或者,您可以通过@StimpsonCat和@ΦXocę查看答案웃 Пepeúpaツ, 这两种方法都给出了这个问题的正确解决方案。OP知道:他在询问如何仅提取小时/分钟/秒部分,即使提供了完整的日期,但给出了错误。因为它不是一个正确的整数。@反斜杠不起作用,因为它不是一个正确的整数。如果它能工作,那么一开始就不会有这样的问题。只是一个小问题。为什么要将它除以1000?我必须补充一点,
DateFormat
是需要花费大量时间初始化的对象,如果一个对象要使用多次,最好将它存储在某个地方。但是,由于该格式在使用时往往会更改其区域设置,并且不是线程安全的,因此安全使用有点繁琐。
SimpleDataFormat
javadoc解释了这一点。java 8
DateFormatter
试图解决这个问题(通过线程安全),但还附带了其他恼人的东西…@lonesome get
getTime()
以毫秒为单位给出时间,因此差异也将以千秒为单位。将其除以1000得到的差值以秒为单位。@JeremyGrand你是在告诉我,如果有大约10K个时间戳,使用上述代码将给出错误的答案吗?@lonesome否。如果使用上述代码,每次都会得到正确的答案。他在谈论SimpleDataFormat的局限性(这就是为什么我每次都创建一个新的)。您不能创建一个SimpleDataFormat,然后从多个线程安全地使用它。只要它只在一根线上使用,你就可以了。完美~这里是+1。