How to set a date in certain timezone?
我正在使用计时器在某段时间内执行某些任务。如果要使任务从该日期开始并在每个时间段内重复,则此方法需要日期类型。
我一直试图找到解决方案几个小时,但无法想出任何东西。我创建日历并为其设置时区。然后,当我从该日历获取日期时,此日期包含我的本地时间。我尝试使用SimpleDataFormat从Date获取字符串并且它起作用,因为您分别为SimpleDataFormat设置时区。然后甚至尝试将该字符串解析为日期,但它仍然无效。这一刻我有点无望。如果我无法使用日历,那么为日历设置时区有什么意义呢。如果没有得到我当地的时间,我仍然可以做一些事情,而是获得UTC。但事实并非如此。我不想根据计算机的本地时间运行此应用程序。这是荒谬的,它应该能够获得当地时间并将其转换为我想要的时区并使用它。
码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | TimeZone eu = TimeZone.getTimeZone("GMT+1"); TimeZone america = TimeZone.getTimeZone("EST"); TimeZone asia = TimeZone.getTimeZone("GMT+7"); SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); df.setTimeZone(eu); Calendar euCal = Calendar.getInstance(eu); Date dateEu = euCal.getTime(); System.out.println(dateEu); //Prints local time date euCal.setTimeZone(eu); System.out.println(dateEu); //Still prints local time date String formattedDateEu = df.format(dateEu); System.out.println(formattedDateEu); //This one works fine but it is string try { dateEu = df.parse(formattedDateEu); } catch (Exception e) { e.printStackTrace(); } System.out.println(dateEu); //Fun part. Although I don't get exception dateEu is still not in the time zone I want. |
样本输出:
1 2 3 4 | 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()打印Date对象时,它需要尝试描述自己。所以它需要描述它所代表的日期和时间,但要做到这一点,首先需要选择一个时区来表示这个日期和时间,因为它没有。为方便起见,它选择用户的系统时区。
你不会通过调用System.out.println()来使用你的日期,所以你不应该关心System.out.println()对它做什么。
我希望我能告诉你远离过时的
1 2 3 4 5 6 7 8 9 10 | 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)。所以我在代码中添加了一些
1 | 2017-11-27T15:56:03.213+01:00 |
您可以看到偏移量是+01:00。然后,正如kumesana在另一个答案中已经说过的那样,不要打印出结果
如果您确实喜欢实时区域,请使用例如:
1 2 3 | ZoneId eu = ZoneId.of("Europe/Brussels"); ZoneId america = ZoneId.of("America/Jamaica"); ZoneId asia = ZoneId.of("Asia/Krasnoyarsk"); |
其余的代码是一样的。这是真的:
避免像EST一样使用三个字母的时区缩写。他们往往含糊不清。我喜欢像我在代码中那样以区域/城市格式指定您的时区。
编辑:这是从我的电脑运行的示例:
1 2 | 2017-11-28T19:04:22.917+01:00 myTask running @ 2017-11-28T19:04:23.156+01:00[Europe/Oslo] |
如您所见,