我有一个广泛的DATE-TIME转换类,但我遇到了一个我无法解决的场景:
我有一个java.util.date:Tue May 10 00:00:00 BST 2011
我有一个java.sql.time:03:58:44
我需要创建一个java.util.date:Tue May 10 03:58:44 BST 2011
我想出的唯一方法是:
public static Date getDate(Date date, Time time) {
Calendar calendar=Calendar.getInstance();
calendar.set(date.getYear(), date.getMonth(), date.getDay(), time.getHours(), time.getMinutes(), time.getSeconds());
return calendar.getTime();
}
完全弃用的代码,但不起作用: java.sql.Time.getYear(未知来源)的java.lang.IllegalArgumentException
有什么想法吗?
答案 0 :(得分:10)
java.sql.Time只是java.util.Date的包装器。您可以像使用两个java.util.Date对象一样使用它。
例如,将Calendar设置为java.sql.Time:
calendar.setTime(time);
现在提取小时/分钟/秒字段,即:
calendar.get(Calendar.HOUR);
接下来,将Calendar设置为java.util.Date对象,并将这三个字段添加到它的时间,即:
calendar.add(Calendar.HOUR, hour);
获取日期:
calendar.getTime();
答案 1 :(得分:4)
最简单的方法是将毫秒加在一起创建一个新日期,ala
public static Date getDate(Date date, Time time) {
return new Date(date.getTime() + time.getTime())
}
答案 2 :(得分:4)
vickirk的解决方案并不是那么糟糕,但有时区问题,导致你观察的时间少了一个小时。
我想,BST表示British Summer Time,即GMT +0100。现在,java.util.Date及其后代内部使用自1970年1月1日午夜 GMT 以来的毫秒数。在您使用toString()
对日期/时间进行格式化之前,不会考虑时区。他们使用你当地的时区,显然是BST。这意味着,真正存储在这些对象中的是
java.util.date:Mon May 09 23 :00:00 GMT 2011年 java.sql.time: 02 :58:44 GMT
当您添加内部值(由getTime()
检索)时,如vickirk建议,您获得的日期包含
5月10日星期二 01 :58:44 GMT 2011,然后结果为
5月10日星期二 02 :58:44 BST 2011年字符串化。
因此,减少一小时的解释是,当您单独对字符串进行字符串化时,时区偏移量应用两次,而在添加后仅应用一次,因为您现在只进行一次。或者,从另一个角度来看,添加时间点的内部值 03:58:44 BST相当于添加2小时58分44秒的时间范围。 / p>
因此,要获得在java.sql.Time中编码的3h 58m 44s的时间 span ,您必须手动补偿时区偏移。你可以通过使用java.sql.Time解析时间字符串“00:00:00”,这将导致内部值-3600000
,相当于1969年12月31日23:00:00 GMT,即在纪元前一小时。这是时区偏移的负数。
public static Date mergeDate(Date date, Time time) {
long tzoffset = -(Time.valueOf("00:00:00").getTime());
return new Date(date.getTime() + time.getTime() + tzoffset);
}
当然,所有这些都是一个肮脏的黑客,这是必要的,因为你坚持将时间的价值解释为时间跨度,而它确实是一个时间点。
答案 3 :(得分:2)
相反,你可以使用它。
public static Date getDate(Date date, Time time) {
Calendar calendar=Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(date);
calendar.add(Calendar.MILLISECOND, (int) time.getTime());
return calendar.getTime();
}
答案 4 :(得分:1)
你能做到吗
java.util.Date newDate = new java.util.Date(sqlDate.getTime());
答案 5 :(得分:1)
试试这些
public static Date getDate(Date date, Time time) {
Calendar calendar=Calendar.getInstance();
calendar.setTime(date);
Calendar calendar1=Calendar.getInstance();
calendar1.setTime(time);
calendar.set(Calendar.MINUTE, calendar1.get(Calendar.MINUTE));
calendar.set(Calendar.SECOND, calendar1.get(Calendar.SECOND));
calendar.set(Calendar.HOUR_OF_DAY, calendar1.get(Calendar.HOUR_OF_DAY));
return calendar.getTime();
}
答案 6 :(得分:1)
我建议您使用java.time(现代的Java日期和时间API)进行日期和时间工作。如果您无法避免将日期设为java.util.Date
(不表示日期的类),而将一天中的时间设为java.sql.Time
,则将两者都转换为现代类型,然后从那里进行组合。 / p>
// Time zone to use throughout
ZoneId zone = ZoneId.systemDefault();
// Initialize values to be used for demonstration
Instant startOfDay = LocalDate.of(2011, Month.MAY, 10)
.atStartOfDay(zone)
.toInstant();
Date date = Date.from(startOfDay);
Time time = Time.valueOf(LocalTime.of(3, 58, 44));
// Do work
LocalTime localTime = time.toLocalTime();
LocalDateTime combination = date.toInstant()
.atZone(zone)
.toLocalDate()
.atTime(localTime);
// Print result
System.out.println(combination);
输出:
2011-05-10T03:58:44
仅当您必不可少的需要Date
(通常是对于您暂时无法升级到java.time的旧版API)时,请转换回去:
Instant inZone = combination.atZone(zone).toInstant();
Date oldfashionedDate = Date.from(inZone);
System.out.println(oldfashionedDate);
在我的时区中,输出为:
2011年5月10日星期二03:58:44 CEST
对于Java 6和7,请使用java.time的backport,ThreeTen Backport(在底部的链接)。对于backport,我们需要使用DateTimeUtils
转换为现代类型:
LocalTime localTime = DateTimeUtils.toLocalTime(time);
LocalDateTime combination = DateTimeUtils.toInstant(date)
.atZone(zone)
.toLocalDate()
.atTime(localTime);
输出与以前相同。另外,如果您需要转换回Date
,请使用DateTimeUtils
:
Instant inZone = combination.atZone(zone).toInstant();
Date oldfashionedDate = DateTimeUtils.toDate(inZone);
再次输出与以前相同。
java.time
。java.time
向Java 6和7(JSR-310的ThreeTen)的反向端口。