Java 8分区日期转换

时间:2016-10-20 11:27:32

标签: java date

我在java中有一个关于区域的问题。 我有一个用户案例,用户可以设置时区和一些时间表。例如,周一和周日晚上11点运行任务,时区为America / Los_Angeles。 如果我的服务器时区是UTC + 0:00我有一个问题如何正确检测星期几和新时间(它将在周二和周一​​早上6点)。所以我的问题是如何根据服务器时区和用户时区正确运行用户任务。

更新

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

2 个答案:

答案 0 :(得分:0)

简答:自纪元以来以毫秒为单位计算。

答案很长:
首先,了解计算机时间如何工作非常重要。我会建议this article。,但要点是,所有事情都是在自1990年1月1日的时代以来计算出来的。其次,我想一个例子会告诉你超过1000个单词:

var sendSearch = true;
var isTiming = false;
var timeout = 300;

$("#s_search").on("keyup", function(){

if (!isTiming){
    isTiming = true;
    setInterval(function(){sendSearch = true;}, timeout);
}

if (sendSearch){

    sendSearch = false;     
    // do your ajax post here   
}

});

ZonedDateTime将始终使用UTC(+ 0)加上定义的时区。

编辑(更新后):
是的,如果您获得了用户设置的时间和时区,则必须将其转换为您自己的时区,以便在同一时间点执行。

答案 1 :(得分:0)

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

请注意,您无法提前安排时区敏感时刻。政治家因经常改变时区定义而臭名昭着,有时很少提前通知。

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

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

将闹钟的星期几保持为DayOfWeek枚举对象。

DayOfWeek alarmDow = DayOfWeek.MONDAY ;

将闹钟的时间保持为LocalTime

LocalTime alarmTimeOfDay = LocalTime.parse( "11:00:00" );

此课程缺少日期,缺少任何来自UTC或时区的偏移。所以在你调整到一个时区之前没有任何意义。

将闹钟的时区保持为ZoneId

ZoneId z = ZoneId.of( "America/Montreal" );

掌握这些部件后,您可以安排闹钟。

Instant获取当前时刻。 Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant now = Instant.now();

应用所需的时区以获得ZonedDateTime

ZonedDateTime zdtNow = instant.atZone( z );

要确定警报的未来时刻,请使用TemporalAdjuster界面操作日期时间值。类TemporalAdjusters(注意复数s)提供了实现。首先提取一个仅限日期的值,因为我们将报警的LocalTime指定为时间。

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.
}