将java.util.date与java.sql.Time合并

时间:2011-05-10 13:28:13

标签: java sql date time merge

我有一个广泛的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

有什么想法吗?

7 个答案:

答案 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>

Java 8和更高版本

    // 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 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);

再次输出与以前相同。

链接