Java 如何在特定时区设置日期?
我使用定时器在特定时间段执行特定任务。如果要使任务从该日期开始并在每个期间重复,则此方法需要日期类型 几个小时以来,我一直在努力寻找解决方案,但什么都想不出来。我创建日历并为其设置时区。然后,当我从日历中获取日期时,该日期包含我的本地时间。我尝试使用SimpleDataFormat从日期获取字符串,但它成功了,因为您分别为SimpleDataFormat设置了时区。然后甚至尝试将该字符串解析为日期,但仍然不起作用。我现在有点绝望。如果我不能使用日历,设置日历时区有什么意义。如果不是我的本地时间,而是UTC时间,我仍然可以做一些事情。但事实也并非如此。我不想让此应用程序基于计算机的本地时间运行。这太荒谬了,它应该能够得到当地时间,把它变成我想要的时区,然后像那样使用它 代码: 样本输出:Java 如何在特定时区设置日期?,java,date,timer,Java,Date,Timer,我使用定时器在特定时间段执行特定任务。如果要使任务从该日期开始并在每个期间重复,则此方法需要日期类型 几个小时以来,我一直在努力寻找解决方案,但什么都想不出来。我创建日历并为其设置时区。然后,当我从日历中获取日期时,该日期包含我的本地时间。我尝试使用SimpleDataFormat从日期获取字符串,但它成功了,因为您分别为SimpleDataFormat设置了时区。然后甚至尝试将该字符串解析为日期,但仍然不起作用。我现在有点绝望。如果我不能使用日历,设置日历时区有什么意义。如果不是我的本地时间,
Mon Nov 27 14:37:21 MSK 2017
Mon Nov 27 14:37:21 MSK 2017
27/11/2017 12:37:21
Mon Nov 27 14:37:21 MSK 2017
java.util.Date对象不包含时区信息。它们代表了时间连续体中的一个瞬间,对每个人来说都是同一个瞬间,不管他们当时是在巴黎还是在纽约 但是,当您尝试使用System.out.println()打印日期对象时,它需要尝试并描述它自己。所以它需要描述它所代表的日期和时间,但要做到这一点,它首先需要选择一个时区来代表这个日期和时间,因为它没有时区。为方便起见,它选择用户的系统时区
您不会通过调用System.out.println()来使用日期,因此您不应该关心System.out.println()如何处理日期。java.util.Date对象不包含时区信息。它们代表了时间连续体中的一个瞬间,对每个人来说都是同一个瞬间,不管他们当时是在巴黎还是在纽约 但是,当您尝试使用System.out.println()打印日期对象时,它需要尝试并描述它自己。所以它需要描述它所代表的日期和时间,但要做到这一点,它首先需要选择一个时区来代表这个日期和时间,因为它没有时区。为方便起见,它选择用户的系统时区
你不能通过调用System.out.println()来使用日期,所以你不应该关心System.out.println()如何使用它。我希望我能告诉你远离早已过时的
Date
类。今天我们的生活好多了。但是,java.util.Timer
确实需要一个Date
来在特定的日期和时间安排任务,这是正确的。尽管如此,由于现代API使用起来非常方便,我建议您使用它来初始化日期
:
ZoneOffset eu = ZoneOffset.ofHours(1);
ZoneOffset america = ZoneOffset.ofHours(-5);
ZoneOffset asia = ZoneOffset.ofHours(7);
OffsetDateTime euTime = OffsetDateTime.now(eu);
System.out.println(euTime);
Date dateEu = Date.from(euTime.toInstant());
// schedule to start at the specified date-time and repeat weekly
myJavaUtilTimer.scheduleAtFixedRate(myTask, dateEu, TimeUnit.DAYS.toMillis(7));
在我看来,你并不是真的在使用时区,只是在使用GMT(或UTC)的偏移量。所以我在代码中加入了一些ZoneOffset
s。刚才打印euTime
的结果是
2017-11-27T15:56:03.213+01:00
您可以看到偏移量是预期的+01:00。然后,正如kumesana在中所说的,不要打印结果的日期
,只要相信它是可以的
如果您确实喜欢实时时区,请使用例如:
ZoneId eu = ZoneId.of("Europe/Brussels");
ZoneId america = ZoneId.of("America/Jamaica");
ZoneId asia = ZoneId.of("Asia/Krasnoyarsk");
代码的其余部分是相同的。没错:OffsetDateTime.now()
接受ZoneOffset
或ZoneId
,因此您甚至可以混合使用这两种类型。在上述时区中,欧洲/布鲁塞尔使用夏季时间(DST),因此您将在一年中的7个月内得到+02:00的偏移量
避免使用三个字母的时区缩写,如EST。它们常常模棱两可。您更愿意像我在代码中那样,以地区/城市格式指定时区
编辑:以下是从我的电脑运行的示例:
2017-11-28T19:04:22.917+01:00
myTask running @ 2017-11-28T19:04:23.156+01:00[Europe/Oslo]
如您所见,
myTask
在为计划任务指定的firstTime
后运行239毫秒。这种延迟是可以预料的。在第二次运行中,差异降至130毫秒。我希望我能告诉您远离早已过时的日期
类。今天我们的生活好多了。但是,java.util.Timer
确实需要一个Date
来在特定的日期和时间安排任务,这是正确的。尽管如此,由于现代API使用起来非常方便,我建议您使用它来初始化日期
:
ZoneOffset eu = ZoneOffset.ofHours(1);
ZoneOffset america = ZoneOffset.ofHours(-5);
ZoneOffset asia = ZoneOffset.ofHours(7);
OffsetDateTime euTime = OffsetDateTime.now(eu);
System.out.println(euTime);
Date dateEu = Date.from(euTime.toInstant());
// schedule to start at the specified date-time and repeat weekly
myJavaUtilTimer.scheduleAtFixedRate(myTask, dateEu, TimeUnit.DAYS.toMillis(7));
在我看来,你并不是真的在使用时区,只是在使用GMT(或UTC)的偏移量。所以我在代码中加入了一些ZoneOffset
s。刚才打印euTime
的结果是
2017-11-27T15:56:03.213+01:00
您可以看到偏移量是预期的+01:00。然后,正如kumesana在中所说的,不要打印结果的日期
,只要相信它是可以的
如果您确实喜欢实时时区,请使用例如:
ZoneId eu = ZoneId.of("Europe/Brussels");
ZoneId america = ZoneId.of("America/Jamaica");
ZoneId asia = ZoneId.of("Asia/Krasnoyarsk");
代码的其余部分是相同的。没错:OffsetDateTime.now()
接受ZoneOffset
或ZoneId
,因此您甚至可以混合使用这两种类型。在上述时区中,欧洲/布鲁塞尔使用夏季时间(DST),因此您将在一年中的7个月内得到+02:00的偏移量
避免使用三个字母的时区缩写,如EST。它们常常模棱两可。您更愿意像我在代码中那样,以地区/城市格式指定时区
编辑:以下是从我的电脑运行的示例:
2017-11-28T19:04:22.917+01:00
myTask running @ 2017-11-28T19:04:23.156+01:00[Europe/Oslo]
如您所见,
myTask
在为计划任务指定的firstTime
后运行239毫秒。这种延迟是可以预料的。在第二次运行中,差异降至130毫秒。不,我不会在system.out.println()中使用它,而是在计时器中使用它。当我将这个日期发送到计时器中时,计时器也会根据我的本地时间获取日期。这就是问题所在。例如,我想要一个计时器,它将在22.00 UTC+1和