【问题标题】:Add hours and minutes to a Date object [duplicate]将小时和分钟添加到日期对象 [重复]
【发布时间】:2018-12-10 21:02:18
【问题描述】:

我有一个小 gui,它有一个日期选择器和一个文本框,我可以在其中输入时间 (HH:mm)。

我想创建一个方法,从 datepicker 中获取 Date,并将时间 (HH:mm) 添加到 datepicker-date,然后返回 Date,以便我可以将其保存在数据库中。

我希望最终日期采用这种格式“yyyy-MM-dd HH:mm”

这是我尝试过的:

public Date getCalibrationDate(){
        String time = getTime();
        int hours = Integer.parseInt(time.substring(0,2));
        int minutes = Integer.parseInt(time.substring(2,4));
        Date date = java.sql.Date.valueOf(kalibreringsdatum.getValue());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        calendar.set(Calendar.HOUR_OF_DAY, hours);
        calendar.set(Calendar.MINUTE,minutes);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String dateAsString = sdf.format(calendar.getTime());
        Date dateTime = null;

        try {
            dateTime = sdf.parse(dateAsString);
        } catch (ParseException e) {
            System.out.println("Could not parse date");
            e.printStackTrace();
        }
        return dateTime;
    }

但它以这种方式返回日期:Tue Dec 11 11:22:00 CET 2018。 我做错了什么,如何简化方法?

【问题讨论】:

  • 你使用的是 java 8 吗?
  • 使用java.time API - 更简单的解决方案
  • 不确定为什么要使用String dateAsString = sdf.format(calendar.getTime()); 后跟dateTime = sdf.parse(dateAsString);Calendar#getTime 返回java.util.Date 的实例
  • 除非有一些非常特殊的原因,否则避免使用java.sql.Date,更喜欢java.util.Date - 更好的是,使用java.time.LocalDateTime
  • 仅供参考,非常麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle

标签: java date javafx datepicker


【解决方案1】:

tl;博士

对于TIMESTAMP WITHOUT TIME ZONE类型的数据库列。

myPreparedStatement                        // As of JDBC 4.2, send/receive java.time objects to/from your database.
.setObject(                                // Call `PreparedStatement::setObject` and `ResultSet::getObject` for java.time objects.
    … ,                                    // Fill-in to indicate which placeholder in SQL statement.
    LocalDateTime.of(                      // Represent a date with time-of-day, but lacking in zone/offset so NOT a moment, NOT a point on the timeline.
        LocalDate.parse( "2018-01-23" ) ,  // Parse the date-only value.
        LocalTime.parse( "21:54" )         // Parse the time-of-day.
    )                                      // Returns a `LocalDateTime` object.
)

对于TIMESTAMP WITH TIME ZONE类型的数据库列。

myPreparedStatement                        // As of JDBC 4.2, send/receive java.time objects to/from your database.
.setObject(                                // Call `PreparedStatement::setObject` and `ResultSet::getObject` for java.time objects.
    … ,                                    // Fill-in to indicate which placeholder in SQL statement.
    LocalDateTime.of(                      // Represent a date with time-of-day, but lacking in zone/offset so NOT a moment, NOT a point on the timeline.
        LocalDate.parse( "2018-01-23" ) ,  // Parse the date-only value.
        LocalTime.parse( "21:54" )         // Parse the time-of-day.
    )                                      // Returns a `LocalDateTime` object.
    .atZone(                               // Assign a time zone to make a moment.
        ZoneId.of( "Pacific/Auckland" )    // Real time zones have a proper name in `Continent/Region` format. Never use 2-4 letter pseudo-zones such as `PDT`, `IST`, `CST`, etc. 
    )                                      // Returns a `ZonedDateTime` object.
    .toOffsetDateTime()                    // Strip out the time zone, leaving only a mere offset-from-UTC (a number of hours-minutes-seconds). Returns a `OffsetDateTime` object.
    .withOffsetSameInstant(                // Adjust the offset-from-UTC to UTC itself (an offset of zero). Same moment, different wall-clock time.
        ZoneOffset.UTC 
    )                                      // Returns another `OffsetDateTime` object.
)

java.time

现代方法使用 java.time 类,多年前取代了可怕的旧遗留类(CalendarDateSimpleDateFormat 等)。

LocalDate

LocalDate 类表示仅日期值,没有时间,也没有 time zoneoffset-from-UTC

文本中仅日期值的常见 SQL 格式是 YYYY-MM-DD。这也是 ISO 8601 标准定义的格式。 java.time 类在解析/生成字符串时默认使用 ISO 8601 格式。所以不需要指定格式模式。

LocalDate ld = LocalDate.parse( "2018-01-23" ) ;

类似于 HH:MM 格式的字符串,表示一天中的小时和分钟。

LocalTime lt = LocalTime.parse( "21:54" ) ;

结合日期和时间。

LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;

ldt.toString(): 2018-01-23T21:54

请注意,LocalDateTime,故意缺少任何时区概念或与 UTC 的偏移,不是片刻,不是在时间线。因此,只适合在类似于 SQL 标准 TIMESTAMP WITHOUT TIME ZONE 的数据类型的列中保存到数据库。

JDBC 4.2

从 JDBC 4.2 开始,我们可以通过 setObjectgetObject 直接与数据库交换 java.time 对象。

myPreparedStatement.setObject( … , ldt ) ;

检索。

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

ZonedDateTime

如果您想处理时间轴上的时刻、实际点,请使用适当的 Java 类(InstantOffsetDateTimeZonedDateTime)。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

OffsetDateTime

现在我们有时间了。通常在移动日期(例如传输到数据库)时最好关注 UTC。

OffsetDateTime odtUtc = zdt.toOffsetDateTime().withOffset( ZoneOffset.UTC ) ;

发送到数据库。

myPreparedStatement.setObject( … , odtUtc ) ;

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    你可以使用 SimpleDateFormat 得到你想要的:

    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateAndTime {
    
    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        System.out.println(sdf.format(new Date()))
    }
    }
    

    【讨论】:

    • 仅供参考,非常麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
    • 你可以,但正如其他人所说,你不应该在 2018 年。而且你的代码不会总是给出预期的结果。
    • Basil Bourque,谢谢,非常有用的信息。会记住的。
    猜你喜欢
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    相关资源
    最近更新 更多