在JAVA中两个时间的相加

huangapple go评论74阅读模式
英文:

Addition of two times in JAVA

问题

我想实现两个时间的相加(java.sql.Time),而不使用任何其他库(java.date,LocalTime...),我始终得到1小时以下的时间。


java.sql.Time

Time heureDebut = "09:00:00";
Time heureFin = "00:15:00";
long heureDebuts = heureDebut.getTime() + heureFin.getTime();
Time tt = new Time(heureDebuts);
//我得到的结果是08:15:00
英文:

I want to make the addition of two times (java.sql.Time) without using any other library (java.date, LocalTime..), I get always the time under 1 hour.

java.sql.Time

Time heureDebut="09:00:00";
Time heureFin="00:15:00";
long heureDebuts = heureDebut.getTime()+heureFin.getTime();
Time tt = new Time(heureDebuts);
//I get 08:15:00 as a result

答案1

得分: 1

## java.time

你说你不想使用除了 `java.sql.Time` 以外的库类但是对于你和其他阅读这篇内容的人我建议你 *不要* 使用 `Time`首先这个类已经过时很长时间了其次这个类的设计非常糟糕第三它并不适合你的目的第四我并不确信它能否用于这个目的你可能从 Amine ABBAOUI 的回答中得到了这种印象认为这是可能的但这个回答有两种欺骗性它使用的方法已经被弃用了23年半我建议没人应该这样做它把所有工作都做在了 `Time` 类的外面

java.time 处理起来要舒服得多它从Java 8开始就已经内置在Java中还被后移植到了Java 6和7中

虽然不是完全清楚但我假设 `09:00:00` 是起始时间,`00:15:00` 是持续时间你想通过将持续时间添加到起始时间来计算结束时间

    LocalTime heureDebut = LocalTime.of(9, 0);
    Duration heureFin = Duration.ofMinutes(15);
    
    LocalTime resultat = heureDebut.plus(heureFin);
    
    System.out.println(resultat);

输出是

> 09:15

## 如果你从数据库获取 `Time` 对象

如果你从存储起始时间和持续时间为 `time` 数据类型这是错误的的SQL数据库获取 `java.sql.Time` 对象并且你无法控制数据库设计从数据库获取 `LocalTime` 对象将持续时间转换为 `Duration` 对象然后按照之前的方法继续处理例如

    PreparedStatement stmt = yourDatabaseConnection.prepareStatement(
        "select heure_debut, heure_fin from votre_table where id = 4;");
    ResultSet rs = stmt.executeQuery();
    if (rs.next()) {
        LocalTime heureDebut = rs.getObject("heure_debut", LocalTime.class);
        LocalTime heureFin = rs.getObject("heure_fin", LocalTime.class);
        Duration dur = Duration.ofNanos(heureFin.getLong(ChronoField.NANO_OF_DAY));
        
        LocalTime resultat = heureDebut.plus(dur);
        
        System.out.println(resultat);
    }

由于 `LocalTime``Time` 相对于时区没有连接上面的转换将给你预期的结果

## 如果你不想使用 java.time

如果你不想使用 java.time尽管我不太理解),我最好的建议是你全部手动完成不要使用任何库类这不是我推荐的解决方案也不是一个好的解决方案但这并不像试图让已经过时且设计不良的 `Time` 类以一种它从未设计过的方式工作那样糟糕

## 你的代码出了什么问题

除了你不能将字符串赋给 `Time` 对象之外你还遇到了时区偏移的问题看起来你的时区在1970年1月1日时的UTC偏移量为+01:00。`Time` 在1970年1月1日时是 `java.util.Date`。虽然没有很好地记录下来这个时间在JVM的默认时区中因此你的时区中的 `09:00:00` 与UTC的08:00:00相同`00:15:00` 是在之前一天晚上的23:15:001969年12月31日)。你使用的 `getTime` 方法获取的是自00:00:00 *UTC* 以来的毫秒数因此在第一种情况下你得到了8小时的毫秒数而在第二种情况下你得到了一个负数相当于*减去*三刻钟你将这些相加得到了足够表示7小时15分钟的毫秒数然后你将这些毫秒数传递给了一个 `Time` 对象得到了07:15:00 UTC而这会在你的时区中打印为08:15:00

## 链接

[Oracle 教程日期时间](https://docs.oracle.com/javase/tutorial/datetime/) 解释了如何使用 java.time。
英文:

java.time

You said you wanted to use no library class but java.sql.Time. Still for you and for everyone else reading this I am suggesting that you don’t use the Time class. One, the class is long outdated, two, the class is horribly designed, three, it’s the wrong class for your purpose, and four, I am not convinced that it can be used for this at all. You may get the impression from the answer by Amine ABBAOUI that it is possible, but that answer is cheating in two ways: It is using methods that have been deprecated for 23 and a half years, which I suggest that no one should want to do either; and it’s doing all of the work outside the Time class.

java.time is so much nicer to work with. It has been built into Java since Java 8 and has also been backported to Java 6 and 7.

It’s not perfectly clear to me, but I am assuming that 09:00:00 is a start time and 00:15:00 is a duration, and you want to calculate an end time by adding the duration to the start time.

	LocalTime heureDebut = LocalTime.of(9, 0);
Duration heureFin = Duration.ofMinutes(15);
LocalTime resultat = heureDebut.plus(heureFin);
System.out.println(resultat);

Output is:

> 09:15

If you were getting Time objects from your database

If you were getting java.sql.Time objects from an SQL database that stores both start time and duration as time datatype (which is incorrect) and you cannot control the database design: Get LocalTime objects from the database. Convert the duration to a Duration object and then proceed as I did before. For example:

	PreparedStatement stmt = yourDatabaseConnection.prepareStatement(
"select heure_debut, heure_fin from votre_table where id = 4;");
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
LocalTime heureDebut = rs.getObject("heure_debut", LocalTime.class);
LocalTime heureFin = rs.getObject("heure_fin", LocalTime.class);
Duration dur = Duration.ofNanos(heureFin.getLong(ChronoField.NANO_OF_DAY));
LocalTime resultat = heureDebut.plus(dur);
System.out.println(resultat);
}

Since a LoalTime opposite a Time isn’t connected to any time zone, the conversion above will give you the expected result.

If you don’t want to use java.time

If you don’t want to use java.time (not that I’d understand), my best suggestion is that you do everything by hand and don’t use any library class at all. It’s no solution that I recommend, it’s no good solution, but it’s not as bad as trying to make the outdated and poorly designed Time class behave in a way that it was never designed to.

What went wrong in your code?

Apart from the fact that you cannot assign a string to a Time object, you have got a time zone offset problem. It seems your time zone was at UTC offset +01:00 on January 1, 1970. A Time is a java.util.Date on January 1, 1970. While not well documented, the time is in the default time zone of the JVM. So your 09:00:00 in your time zone is the same as 08:00:00 UTC. And 00:15:00 is 23:15:00 on the night before (December 31, 1969). The getTime method that you use gets the number of milliseconds since 00:00:00 UTC. So in the first case you get 8 hours worth of milliseconds, and in the second case you get a negative amount equal to minus three quarters of an hour. You added those and got milliseconds enough for 7 hours 15 minutes. You fed those back into a Time object and got 07:15:00 UTC, which prints as 08:15:00 in your time zone.

Oracle tutorial: Date Time explaining how to use java.time.

答案2

得分: 0

以下是翻译好的部分:

您可以按如下方式使用这段伪代码:
时间 heureDebut = Time.valueOf("01:00:00");
时间 heureFin = Time.valueOf("00:15:00");
int hours = heureDebut.getHours() + heureFin.getHours();
int minutes = heureDebut.getMinutes() + heureFin.getMinutes();
int seconds = heureDebut.getSeconds() + heureFin.getSeconds();
if (seconds >= 60) {
minutes = minutes + 1;
seconds = seconds % 60;
}
if (minutes >= 60) {
hours = hours + 1;
minutes = minutes % 60;
}
时间 result = new Time(hours, minutes, seconds);
System.out.println(result.toString());
英文:

You can use this pseudo code as follows:

    Time heureDebut= Time.valueOf("01:00:00");
Time heureFin=Time.valueOf("00:15:00");
int hours = heureDebut.getHours() + heureFin.getHours();
int minutes = heureDebut.getMinutes() +heureFin.getMinutes();
int seconds = heureDebut.getSeconds()+heureFin.getSeconds();
if (seconds >= 60) {
minutes =minutes+1;
seconds = seconds % 60;
}
if (minutes >= 60) {
hours =hours+1;
minutes = minutes % 60;
}
Time result=new Time(hours,minutes,seconds);
System.out.println(result.toString());

答案3

得分: 0

似乎是“夏令时”问题。

Time base = Time.valueOf("09:00:00");
Time additional = Time.valueOf("00:15:00");
long additionalTime = additional.getTime() - additional.getTimezoneOffset() * 60 * 1000;
System.out.println(new Time(base.getTime() + additionalTime));
英文:

It seems to be Daylight Saving Time issue.

Time base = Time.valueOf("09:00:00");
Time additional = Time.valueOf("00:15:00");
long additionalTime  = additional.getTime() - additional.getTimezoneOffset()*60*1000;
System.out.println(new Time(base.getTime() + additionalTime));

huangapple
  • 本文由 发表于 2020年8月18日 17:58:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63466249.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定