Java 使用hh:mm:ss每天在特定时间运行的计划
我试图在每天的特定时间运行代码,但是使用hh:mm:ss。我特别想在美国东部时间每天下午5点运行它,所以需要考虑时区 以下是我在科特林的尝试:Java 使用hh:mm:ss每天在特定时间运行的计划,java,date,kotlin,Java,Date,Kotlin,我试图在每天的特定时间运行代码,但是使用hh:mm:ss。我特别想在美国东部时间每天下午5点运行它,所以需要考虑时区 以下是我在科特林的尝试: val timer = Timer() val format = SimpleDateFormat("hh:mm:ss") val date = format.parse("11:07:09") timer.schedule(object : TimerTask() { override fun run() { // code h
val timer = Timer()
val format = SimpleDateFormat("hh:mm:ss")
val date = format.parse("11:07:09")
timer.schedule(object : TimerTask() {
override fun run() {
// code here
}
}, date)
我无法让它工作,即使我这样做了,我也不知道如何将时区添加到它中
我怎样才能做到这一点?tl;博士
细节
java.util.Date
表示一个日期,其时间以UTC为单位
您忽略了日期和分区/偏移
您的结果显然默认为1970年1月1日上午11点
java.time
此外,可怕的Date
和SimpleDateFormat
类在几年前被java.time类取代
java.util.Date d = java.util.Date.from( instant ) ;
表示一天中的目标时间
LocalTime lt = LocalTime.parse( "11:07:09" ) ;
获取当前日期,即今天的日期。需要时区。在任何一个特定的时刻,世界各地的日期都因地区而异
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
把这些放在一起决定一个时刻
ZonedDateTime zdt = ZonedDateTime.of( today , lt , z ) ; // Time-of-day will be adjusted if not valid on that date in that zone.
调整到UTC。同一时刻,时间线上的同一点,不同的挂钟时间
Instant instant = zdt.toInstant() ; // Adjust from zone to UTC.
避免遗留日期时间类。但如果必须具有互操作性,则可以通过调用添加到旧类中的新方法来来回转换
java.util.Date d = java.util.Date.from( instant ) ;
您可能希望改进此代码,以查看所需的时刻是否已经过去。要进行比较,请使用isAfter
和isBefore
方法
遗嘱执行人
Timer
类已被executor框架取代。搜索Oracle Java教程和堆栈溢出以了解更多信息
有了执行器,您可以安排任务在某一时刻运行。但您可以通过指定等待时间而不是一天中的某个时间来间接地执行此操作。调度执行器接受初始延迟的参数。您可以将该延迟计算为当前时刻和所需时刻之间的时间跨度
要计算时间跨度,请使用Duration
类
Duration d = Duration.between( Instant.now() , instant ) ;
请记住,您不能期望在瞬间完美地完成任务。主机操作系统上的JVM调度和JVM中的Java线程调度可能会涉及延迟
当然,您还需要记录任务完成时的历史记录。当你的应用程序关闭,然后重新启动时,它需要研究历史,找出如何设置新的时间表。这个问题超出了这个答案的范围。读写文件、使用数据库或依赖其他方案
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- 、和更高版本-标准Java API的一部分,带有捆绑实现。
- Java9添加了一些次要功能和修复
- 及
- 大多数java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(tl;dr
细节
表示一个日期,其时间以UTC为单位 您忽略了日期和分区/偏移 您的结果显然默认为1970年1月1日上午11点 java.time 此外,可怕的java.util.Date
和Date
类在几年前被java.time类取代SimpleDateFormat
表示一天中的目标时间java.util.Date d = java.util.Date.from( instant ) ;
获取当前日期,即今天的日期。需要一个时区。对于任何给定的时刻,全球各地的日期因区域而异LocalTime lt = LocalTime.parse( "11:07:09" ) ;
把这些放在一起决定一个时刻ZoneId z = ZoneId.of( "Africa/Tunis" ) ; LocalDate today = LocalDate.now( z ) ;
调整到UTC。同一时刻,时间线上的同一点,不同的挂钟时间ZonedDateTime zdt = ZonedDateTime.of( today , lt , z ) ; // Time-of-day will be adjusted if not valid on that date in that zone.
避免使用旧的日期时间类。但如果必须具有互操作性,则可以通过调用添加到旧类中的新方法来来回转换Instant instant = zdt.toInstant() ; // Adjust from zone to UTC.
您可能需要改进此代码,以查看所需的时刻是否已经过去。要进行比较,请使用java.util.Date d = java.util.Date.from( instant ) ;
和isAfter
方法 遗嘱执行人 executor框架已取代isBefore
类。有关详细信息,请搜索Oracle Java教程和堆栈溢出 使用执行器,您可以安排任务在某个时刻运行。但您可以通过指定等待时间而不是一天中的某个时间来间接执行。计划执行器会为初始延迟提供参数。您可以将该延迟计算为当前时刻和所需时刻之间的时间跨度 要计算时间跨度,请使用Timer
类Duration
请记住,您不能期望任务在瞬间完美执行。主机操作系统上的JVM调度和JVM中的Java线程调度可能会涉及延迟 当然,您还需要在任务完成后记录任务的历史记录。当您的应用程序关闭后重新启动时,它需要研究历史记录,以确定如何设置新的计划。此问题超出了此答案的范围。请阅读编写文件、使用数据库或依赖其他方案Duration d = Duration.between( Instant.now() , instant ) ;
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅.和搜索堆栈溢出以获取许多示例和解释。规范为 您可以直接与数据库交换java.time对象