java - 如何在不同时区的某个时间执行作业
问题描述
假设我在 BST 即英国夏令时,并且我想按照美国/东部时区在 19.30 执行工作,那么我怎么能实现它。
我试过的示例代码,
Instant now = Instant.now();
LocalDateTime localTimeNow = LocalDateTime.ofInstant(now, ZoneOffset.systemDefault());
//if BST then use "Europe/London"
//if US/Eastern then use "America/New_York"
// For EST also use "America/New_York"
// If GB-Eire then use "Europe/London"
ZonedDateTime bsTime = now.atZone(ZoneId.of("Europe/London"));
ZonedDateTime nyAmerica = now.atZone(ZoneId.of("America/New_York"));
// Lets calculate the difference between 2 timezones
// Between London and EST
long timeDiff = ChronoUnit.MILLIS.between(bsTime, nyAmerica);
System.out.println("timeDiff - " + timeDiff);
int minutes = (int) ((timeDiff / 1000) / 60);
System.out.println("Time diff bet London and EST - " + minutes + " minutes");
long diff = Duration.between(bsTime, nyAmerica).getSeconds();
int mins = (int) (diff / 60);
System.out.println("Time diff bet London and EST - " + mins + " minutes");
在这两种情况下它都给我零。
我想要的是我必须使用这个延迟将它传递给执行器服务,如下所示,
executor.schedule(myRunnable, delay, TimeUnit.SECONDS);
因此,即使我在英国,根据美国/东部时间,这项工作应该在 19.30 执行。
此外,EST、BST 等一些缩写也不是有效的 ZoneId。那么,当我有 EST 或 BST 等缩写格式的时区时,我该如何处理这些情况?
解决方案
更新:下面的原始答案显示了如何计算本地时间以启动必须在不同时区的特定时间运行的作业。
如果您只是想计算要等到那个时间,它可以更容易地完成,而不涉及本地时区。
LocalTime jobStartTime = LocalTime.of(19, 30);
ZoneId jobZone = ZoneId.of("America/New_York");
ZonedDateTime now = ZonedDateTime.now(jobZone);
ZonedDateTime jobDateTime = now.with(jobStartTime);
if (jobDateTime.isBefore(now))
jobDateTime.plusDays(1);
long delay = ChronoUnit.MILLIS.between(now, jobDateTime);
System.out.println("now = " + now);
System.out.println("jobDateTime = " + jobDateTime);
System.out.println("delay = " + delay + " = " + Duration.ofMillis(delay));
输出
now = 2020-07-17T08:18:45.482028800-04:00[America/New_York]
jobDateTime = 2020-07-17T19:30-04:00[America/New_York]
delay = 40274517 = PT11H11M14.517S
原始答案
now
是2020-07-17 07:57:45 Z
在伦敦那是2020-07-17 08:57:45 +01:00
在纽约那是2020-07-17 03:57:45 -04:00
。
伦敦和纽约的时差是多少?
0秒,因为它们是同一时间。
问题中的代码没有计算时间是 19:30。相反,它会尝试计算现在的时区差异,但由于夏令时,晚上 7:30 的时区差异可能会有所不同,因此该方法是错误的。
如果您在伦敦,并且需要知道下一次纽约的时间是 19:30,请执行以下操作:
Instant now = Instant.now();
ZoneId localZone = ZoneId.of("Europe/London");
ZoneId remoteZone = ZoneId.of("America/New_York");
System.out.println("now = " + now);
ZonedDateTime remoteNow = now.atZone(remoteZone);
LocalDate remoteDate = remoteNow.toLocalDate();
LocalTime remoteTime = LocalTime.of(19, 30);
if (remoteNow.toLocalTime().isAfter(remoteTime))
remoteDate = remoteDate.plusDays(1);
ZonedDateTime remoteStartTime = ZonedDateTime.of(remoteDate, remoteTime, remoteZone);
System.out.println("remoteNow = " + remoteNow);
System.out.println("remoteStartTime = " + remoteStartTime);
ZonedDateTime localStartTime = remoteStartTime.withZoneSameInstant(localZone);
System.out.println("localNow = " + now.atZone(localZone));
System.out.println("localStartTime = " + localStartTime);
输出
now = 2020-07-17T07:57:45.206007800Z
remoteNow = 2020-07-17T03:57:45.206007800-04:00[America/New_York]
remoteStartTime = 2020-07-17T19:30-04:00[America/New_York]
localNow = 2020-07-17T08:57:45.206007800+01:00[Europe/London]
localStartTime = 2020-07-18T00:30+01:00[Europe/London]
因此,在运行英国时区的计算机上,美国东部的下一个晚上 7:30 时间是今晚午夜半点。
推荐阅读
- amazon-web-services - 我的应用程序如何发现 AWS App Mesh(具有动态端口的 ECS/Fargate)上的 *local* envoy sidecar 代理的地址/端口?
- jenkins - 将密码参数传递给 Jenkinsfile 中的下游作业时,“脚本不允许使用字段 hudson.util.Secret 值”
- python - Tkinter、Multiprocessing 和 cx_Freeze 的组合创建了一个不需要的窗口
- python - 在 Python 2.7 中使用 PyInstaller - 包括模块
- python - sklearn 中的 load_digits() 有什么作用?
- google-sheets - Google 表格日期查询不适用于特定列
- java - java中数组的简单交换给出了奇怪的结果
- c# - XamarinForms 中标签的 TextColor 属性在 Android 上不起作用
- android - 在使用 FTP 上传之前即时压缩图像
- sql - 解析sql中的不规则分隔符