Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8分区日期转换_Java_Date - Fatal编程技术网

Java 8分区日期转换

Java 8分区日期转换,java,date,Java,Date,我有一个关于java中区域的问题。 我有一个用户案例,用户可以设置时区和一些时间表。例如,在周一和周日晚上11点使用时区美国/洛杉矶运行任务。 如果我的服务器时区是UTC+0:00,我就无法正确检测一周中的某一天和新时间(大约是星期二和星期一早上6点)。所以我的问题是如何根据服务器时区和用户时区正确运行用户任务 更新 我有一个cron表达式,在这里我设置了一周中的小时、分钟和一天。 当用户创建新任务时,他可以设置自定义时区(例如,使用自定义时区UTC-7:00在周一晚上11点运行任务) 因此,如

我有一个关于java中区域的问题。 我有一个用户案例,用户可以设置时区和一些时间表。例如,在周一和周日晚上11点使用时区美国/洛杉矶运行任务。 如果我的服务器时区是UTC+0:00,我就无法正确检测一周中的某一天和新时间(大约是星期二和星期一早上6点)。所以我的问题是如何根据服务器时区和用户时区正确运行用户任务

更新

我有一个cron表达式,在这里我设置了一周中的小时、分钟和一天。 当用户创建新任务时,他可以设置自定义时区(例如,使用自定义时区UTC-7:00在周一晚上11点运行任务)
因此,如果我的理解是正确的,我需要将他的小时设置(晚上11点)转换为相应的服务器时间。因此,如果我的服务器时区是UTC+3:00,我需要将晚上11点转换为上午9点,并且在我的服务器上不是星期一(而是星期二)。然后,如果我将在周二上午9点运行cron,它将在周一晚上11点运行类似于用户的任务。我的方法正确吗?我希望你能理解我的问题。提前感谢。

简短的回答是:从纪元开始以毫秒为单位计数

答案很长:
首先,了解计算机时间是如何工作的是非常重要的。我建议,但要点是,一切都是从1970年1月1日开始计算的。其次,我想一个例子会告诉你超过1000个单词:

ZonedDateTime dateTime = ZonedDateTime.parse("2016-10-20T11:34:57+02:00[Europe/Zurich]"); // UTC + 2
long millisEurope = dateTime.toInstant().toEpochMilli();
System.out.println(millisEurope); // 1476956097000

dateTime = dateTime.withZoneSameLocal(ZoneId.of("America/Los_Angeles")); // UTC - 7
long millisAmerica = dateTime.toInstant().toEpochMilli();
System.out.println(millisAmerica); // 1476988497000

// The difference between UTC + 2 and UTC - 7  == -9
System.out.println((millisEurope - millisAmerica) / 1000 / 60 / 60);
始终使用UTC(+0)加上定义的时区

编辑(更新后):

是的,如果您获得用户设置的时间和时区,则必须将其转换为您自己的时区,以便在同一时间点上执行。

简短回答:从历元开始以毫秒为单位计数

答案很长:
首先,了解计算机时间是如何工作的是非常重要的。我建议,但要点是,一切都是从1970年1月1日开始计算的。其次,我想一个例子会告诉你超过1000个单词:

ZonedDateTime dateTime = ZonedDateTime.parse("2016-10-20T11:34:57+02:00[Europe/Zurich]"); // UTC + 2
long millisEurope = dateTime.toInstant().toEpochMilli();
System.out.println(millisEurope); // 1476956097000

dateTime = dateTime.withZoneSameLocal(ZoneId.of("America/Los_Angeles")); // UTC - 7
long millisAmerica = dateTime.toInstant().toEpochMilli();
System.out.println(millisAmerica); // 1476988497000

// The difference between UTC + 2 and UTC - 7  == -9
System.out.println((millisEurope - millisAmerica) / 1000 / 60 / 60);
始终使用UTC(+0)加上定义的时区

编辑(更新后):

是的,如果用户设置了时区,则必须将其转换为自己的时区,以便在同一时间点上执行。

服务器操作系统和JVM的时区设置应该与您的编程无关。两者都可以在运行时的任何时刻更改,所以不要依赖它始终在各种日期-时间方法的可选参数中指定所需/预期时区

请注意,您不能提前很长时间安排时区敏感时刻。政客们因经常更改时区定义而臭名昭著,有时几乎没有事先通知

如果要在用户时区的上下文中设置下周一上午11点的警报,首先需要用户的时区。您可能能够检测到默认时区,但最终唯一可靠的方法是询问用户所需/预期的时区

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

将报警的星期几保留为
DayOfWeek
enum对象

DayOfWeek alarmDow = DayOfWeek.MONDAY ;
将闹钟的时间保持为
LocalTime

LocalTime alarmTimeOfDay = LocalTime.parse( "11:00:00" );
ZonedDateTime zdtNow = instant.atZone( z );
此类没有日期,也没有与UTC或时区的任何偏移。所以,在你适应时区之前,它没有任何意义

将闹钟的时区保留为
ZoneId

ZoneId z = ZoneId.of( "America/Montreal" );
有了这些零件,你就可以安排闹钟了

瞬间
的形式获取当前时刻。该类表示时间线上的一个时刻,分辨率为(小数点的九(9)位)

应用所需时区以获取
ZonedDateTime

LocalTime alarmTimeOfDay = LocalTime.parse( "11:00:00" );
ZonedDateTime zdtNow = instant.atZone( z );
要确定报警的未来时刻,请使用界面操纵日期时间值。类(注意复数
s
)提供了实现。首先提取一个仅限日期的值,因为我们将把报警的
LocalTime
指定为一天中的时间

LocalDate today = zdtNow.toLocalDate();
LocalDate dateOfNextOrSameDow = today.with( TemporalAdjusters.withNextOrSame( alarmDow ) );
ZonedDateTime zdtAlarm = ZonedDateTime.of( dateOfNextOrSameDow , alarmTimeOfDay , z ) ;
应用一天中所需的时间

LocalDate today = zdtNow.toLocalDate();
LocalDate dateOfNextOrSameDow = today.with( TemporalAdjusters.withNextOrSame( alarmDow ) );
ZonedDateTime zdtAlarm = ZonedDateTime.of( dateOfNextOrSameDow , alarmTimeOfDay , z ) ;
这个特定的报警日期时间可能已经在今天早些时候过去了。所以,测试一下。如果是这样,请添加一周以获得所需的一周中的下一天

if( zdtAlarm.isBefore( zdtNow ) ) {  // If already passed…
    zdtAlarm = zdtAlarm.plusWeeks( 1 );  // …go to next day-of-week occurrence.
}

服务器操作系统和JVM的时区设置应该与编程无关。两者都可以在运行时的任何时刻更改,所以不要依赖它始终在各种日期-时间方法的可选参数中指定所需/预期时区

请注意,您不能提前很长时间安排时区敏感时刻。政客们因经常更改时区定义而臭名昭著,有时几乎没有事先通知

如果要在用户时区的上下文中设置下周一上午11点的警报,首先需要用户的时区。您可能能够检测到默认时区,但最终唯一可靠的方法是询问用户所需/预期的时区

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

将报警的星期几保留为
DayOfWeek
enum对象

DayOfWeek alarmDow = DayOfWeek.MONDAY ;
将闹钟的时间保持为
LocalTime

LocalTime alarmTimeOfDay = LocalTime.parse( "11:00:00" );
ZonedDateTime zdtNow = instant.atZone( z );
此类没有日期,也没有与UTC或时区的任何偏移。所以,在你适应时区之前,它没有任何意义

将闹钟的时区保留为
ZoneId

ZoneId z = ZoneId.of( "America/Montreal" );
有了这些零件,你就可以安排闹钟了

瞬间
的形式获取当前时刻。