0

基本上我想将格式为'hh:mm'的DateTimeFormatter应用于我从'zonedDateTime.toLocalTime()'对象获得的值并将其存储为LocalTime对象,以便我得到像'08:00'这样的值,如下代码显示了我如何获取特定时区的当前时间,并在格式化时尝试将其转换为名为“currentTime”的 LocalTime:

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm");

        ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of(appTheme.getTimezone()));
        LocalTime currentTime = LocalTime.parse(zonedDateTime.toLocalTime().toString(),formatter);

现在由于某种未知原因,我从上面的最后一行代码中得到以下错误:


java.time.format.DateTimeParseException: Text '15:32:03.824' could not be parsed, unparsed text found at index 5
    java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1952)
    java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    java.time.LocalTime.parse(LocalTime.java:441)
    io.apptizer.cafe.controller.CategoryController.getBusinessCategoryDetails(CategoryController.java:789)
    io.apptizer.cafe.controller.CategoryController.backwardCompatibilityCategories(CategoryController.java:387)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    io.apptizer.cafe.filter.SessionHandleFilter.doFilter(SessionHandleFilter.java:39)

我希望我能很好地解释我的问题,我的主要目标是获取 'hh:mm' 或 'HH:mm' 格式的 'zonedDateTime.toLocalTime()' 值并将其存储为 LocalTime 对象,我只是可以实现它,因为是否出现错误,

如果有人能帮忙就好了,干杯!

4

2 回答 2

2

tl;博士

ZonedDateTime
.now(
    ZoneId.of( "Asia/Tokyo" )
)
.toLocalTime()

要不就:

LocalTime.now( ZoneId.of( "Asia/Tokyo" ) )

细节

您的问题包括:

  • 您的格式化模式hh:mm与您的输入不匹配15:32:03.824
  • hh:mm正在使用错误的代码。这hh意味着 12 小时制,但您的输入显然是 24 小时制。

ISO 8601

您的输入格式符合一天中某个时间的ISO 8601标准。

LocalTime

java.time类在解析/生成文本时默认使用标准 ISO 8601 格式。所以不需要指定格式模式。只需解析为一个LocalTime对象。

LocalTime lt = LocalTime.parse( "15:32:03.824" ) ;

您的更大目标尚不清楚,但我怀疑您想要在特定时区看到的当前时间。如果是这样,只需LocalTime.now在经过时区时使用。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalTime lt = LocalTime.now( z ) ;

如果您将时刻表示为ZonedDateTime,只需调用toLocalTime即可提取LocalTime对象。

LocalTime lt = myZonedDateTime.toLocalTime() ;

提示:您似乎只考虑字符串操作。思考而不是学习和使用内置于 Java 8 及更高版本的行业领先的java.time框架中的类的智能对象。请参阅Oracle 提供的免费Java 教程。注意上面的代码如何不使用字符串来完成它的工作。

截断

你说:

所以我得到像'08:00'这样的值,

如果您的意思是要将分钟和秒清除为零,请truncate

LocalTime lt = LocalTime.now( ZoneId.of( "America/Edmonton" ) ).truncatedTo( ChronoUnit.HOURS ) ;

数据库

你评论说:

我需要将我从 'zonedDateTime.toLocalTime()' 获得的值存储为 'HH:mm' 或 'hh:mm' 格式的 LocalTime 对象

如果您的意思是存储在数据库中,那么您的数据库表应该定义为类似于 SQL 标准类型的类型TIME,而不是文本类型。然后LocalTime通过 JDBC 4.2 或更高版本传递您的对象。

myPreparedStatement.setObject( … , lt ) ;

恢复。

LocalTime lt = myResultSet.getObject( … , LocalTime.class ) ;

你评论说:

我将使用多个 LocalTime 值进行时间范围比较

LocalTime使用带有 JDBC的一对对象来查询类型为 的列TIME。例如,让我们查找标记为午餐时间的行。

LocalTime start = LocalTime.NOON ;
LocalTime end = LocalTime.of( 13 , 0 ) ;

SQL 看起来像这样,其中?是一个值的占位符,作为准备好的语句的一部分被替换。

SELECT * 
FROM some_table_
WHERE time_of_day_ !< ? 
AND time_of_day_ < ? 
; 

请注意!<,意思是“不小于”,是询问“等于或大于”的更短方式。

Java代码将是:

myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , end ) ;
于 2021-05-24T20:31:00.337 回答
1

您不能创建格式化的日期时间对象

如上面链接中所述,您需要使用您选择的模式将时间格式化为字符串。请注意,它hh对应于 12 小时制时间(即 AM/PM 时间),因此您应该使用a它。查看文档以获取更多详细信息。

import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter24Hour = DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);
        DateTimeFormatter formatterAmPm = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);

        ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.systemDefault());
        LocalTime localTime = zonedDateTime.toLocalTime();
        
        String currentTime24HourFormat = formatter24Hour.format(localTime);
        String currentTime12HourFormat = formatterAmPm.format(localTime);

        System.out.println(currentTime24HourFormat);
        System.out.println(currentTime12HourFormat);
    }
}

输出:

21:40
09:40 PM
于 2021-05-24T20:41:39.147 回答