问题描述
我正在尝试将 zoneddatetime (EST) 转换为 Date (UTC) 我认为 3 月 13 日和 14 日的日历日期有 1 小时的休息时间
系统默认 - UTC
zoneddatetime zoneddatetime1 = zoneddatetime.of(2021,3,13,19,ZoneId.of("America/New_York"));
Date date1 = Date.from(zoneddatetime1.withZonesameInstant(ZoneId.systemDefault()).toInstant();
System.out.println("EST -> ",zoneddatetime1);
System.out.println("UTC -> ",date1);
zoneddatetime zoneddatetime2 = zoneddatetime.of(2021,14,ZoneId.of("America/New_York"));
Date date2 = Date.from(zoneddatetime2.withZonesameInstant(ZoneId.systemDefault()).toInstant();
System.out.println("EST -> ",zoneddatetime2);
System.out.println("UTC -> ",date2);
实际结果:
EST -> 2021-03-13T19:00-05:00[美国/纽约]
UTC -> 2021 年 3 月 14 日星期日 00:00:00 UTC
EST -> 2021-03-14T19:00-04:00[美国/纽约]
UTC -> 2021 年 3 月 14 日星期日 23:00:00 UTC
预期结果:
EST -> 2021-03-13T19:00-05:00[美国/纽约]
UTC -> 2021 年 3 月 14 日星期日 00:00:00 UTC
EST -> 2021-03-14T19:00-04:00[美国/纽约]
UTC -> 2021 年 3 月 15 日星期一 00:00:00 UTC
这是商业用例
-> 客户特定假期 2021/1/14、2021/2/14、2021/3/14(这些是 UTC)
-> 用户选择一个特定的时间,例如:2021/2/14 19:00,2021/3/14 19:00 EST(这两天是实际工作日)
现在系统说用户选择的日期是假期或工作日 客户
为此,我将用户选择的日期 (EST) 转换为 UTC 并检查客户端特定的日历(它适用于 2 月,但无法用于 3 月)
解决方法
夏令时于 3 月 14 日星期日在 Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py",line 34,in inner
response = get_response(request)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py",line 145,in _get_response
response = self.process_exception_by_middleware(e,request)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py",line 143,in _get_response
response = response.render()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\response.py",line 106,in render
self.content = self.rendered_content
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\response.py",line 83,in rendered_content
content = template.render(context,self._request)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\backends\django.py",line 61,in render
return self.template.render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\base.py",line 171,in render
return self._render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\base.py",line 163,in _render
return self.nodelist.render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\base.py",line 937,in render
bit = node.render_annotated(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\base.py",line 904,in render_annotated
return self.render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\loader_tags.py",line 150,in render
return compiled_parent._render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\base.py",line 62,in render
result = block.nodelist.render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\base.py",in render_annotated
return self.render(context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\template\defaulttags.py",line 166,in render
len_values = len(values)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py",line 256,in __len__
self._fetch_all()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py",line 1242,in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py",line 55,in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch,chunk_size=self.chunk_size)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\compiler.py",line 1100,in execute_sql
cursor.execute(sql,params)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\utils.py",line 99,in execute
return super().execute(sql,line 67,in execute
return self._execute_with_wrappers(sql,params,many=False,executor=self._execute)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\utils.py",line 76,in _execute_with_wrappers
return executor(sql,many,context)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\utils.py",line 84,in _execute
return self.cursor.execute(sql,params)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\utils.py",line 89,in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\utils.py",params)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\sqlite3\base.py",line 383,in execute
return Database.Cursor.execute(self,query,params)
django.db.utils.OperationalError: no such column: core_item.brands_id
开始。我想这就是观察到的差异的原因。
America/New_York
的夏令时于 America/New_York
开始。在此之后的任何日期时间实例(直到冬季时间再次生效)时区 2021-03-14T02:00:00 EST
将是 EDT 而不是 EST。 EDT 的 UTC 偏移量为 -4 小时。
全年使用 EST
您的客户似乎坚持在夏季使用 EST(东部标准时间)报告时间,而不是 EDT(东部夏令时间)。有些时区可以做到这一点,因此解决方案是:不要使用 America/New_York 时区,而是使用使用东部时间而不使用夏令时/DST 的时区。例如:
ZoneId clientTimeZone = ZoneId.of("America/Atikokan");
ZonedDateTime zonedDateTime1 = ZonedDateTime.of(2021,3,13,19,clientTimeZone);
Date date1 = Date.from(zonedDateTime1.toInstant());
System.out.println("EST -> " + zonedDateTime1);
System.out.println("UTC -> " + date1);
ZonedDateTime zonedDateTime2 = ZonedDateTime.of(2021,14,clientTimeZone);
Date date2 = Date.from(zonedDateTime2.toInstant());
System.out.println("EST -> " + zonedDateTime2);
System.out.println("UTC -> " + date2);
输出是(在 UTC 时区运行时):
EST -> 2021-03-13T19:00-05:00[America/Atikokan]
UTC -> Sun Mar 14 00:00:00 UTC 2021
EST -> 2021-03-14T19:00-05:00[America/Atikokan]
UTC -> Mon Mar 15 00:00:00 UTC 2021
与您预期的相比,不同之处在于:
- 时区 ID 现在是 America/Atikokan。
-
2021-03-14T19:00
的 UTC 偏移量现在不是-04:00
,而是-05:00
。这就是导致时间转换为 00:00 的预期 UTC 时间的原因。
与您的代码相比,我进行了另一项更改:我已将 withZoneSameInstant()
的调用排除在外。他们在这里没有区别。由于您在执行 toInstant()
之后,正如方法名称所述,您在两种情况下都会获得相同的瞬间。
编辑:全年使用东部标准时间的北美和中美洲时区包括:
- 在加拿大:美国/Atikokan
- 在美国:我没有发现
- 在中美洲和加勒比地区:美洲/坎昆、美洲/牙买加、美洲/巴拿马