英文:
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:00(1969年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.
Link
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));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论