- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有适用于 3 个地区(蒙古、土库曼尼亚等)的网络应用。并且都部署在tomcat的虚拟主机上。现在我需要为每个应用程序设置时区。我怎样才能做到这一点?我为每个应用程序实现了 ServerContextListener 接口(interface)来设置 TimeZone:
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
TimeZone timeZone=TimeZone.getTimeZone("Asia/Ulan_Bator");
// TimeZone timeZone=TimeZone.getTimeZone("Asia/Ashgabat");
timeZone.setDefault(timeZone);
}
但在部署后每个应用程序都有相同的时区。
P.S:对不起我的英语:)
最佳答案
ZoneId
,不是TimeZone
多年前,随着 JSR 310 的采用,现代 java.time 类取代了糟糕的遗留日期时间类。
TimeZone
替换为 ZoneId
& ZoneOffset
.
ZoneId z = ZoneId.of( "Asia/Ulan_Bator" ) ;
避免依赖 JVM 当前的默认时区。
JVM 只有一个默认时区。调用 TimeZone.setDefault
会立即影响该 JVM 内所有应用程序的所有线程中的所有代码。
But after deploy each apps has same TimeZone.
因此您不能为每个网络应用设置不同的默认时区。如果所有 Web 应用程序都在同一个 Servlet 容器中运行,那么所有 Web 应用程序共享相同的默认时区。
更好的方法是将所需/预期时区作为可选参数显式传递给各种 java.time 方法。例如,如果您想捕捉在特定时区看到的当前时刻,请将所需的 ZoneId
对象传递给 now
方法。
ZoneId z = ZoneId.of( "Asia/Ashgabat" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
与其依赖于 JVM 当前的默认时区,不如为您的每个 Web 应用程序设置一个时区。
ServletContextListener::contextInitialized
您已接近解决方案。当每个 Web 应用程序启动时,您需要指定其默认值。这样做的地方是在 contextInitialized
在你的类中实现 ServletContextListener
的方法如您的问题所示。
在该方法中,指定所需的时区。
ZoneId z = ZoneId.of( "Asia/Ashgabat" ) ;
但是该变量超出范围并在 contextInitialized
方法结束时消失。所以我们需要在某处存储对该 ZoneId
对象的引用。但是哪里? Servlet 规范为您在应用程序中跨代码所需的此类“全局”变量或常量定义了一个位置。
您的 contextInitialized
方法被传递了一个 ServletContextEvent
.该对象持有对 ServletContext
的引用表示正在启动的 Web 应用程序的当前实例的对象。
ServletContext myWebAppContext = servletContextEvent.getContext() ;
ServletContext
方便地维护了一个简单的“属性”键值存储。键是一个 String
,值是一个 Object
。我们可以为每个 Web 应用程序的默认时区创建一个字符串名称,并将 ZoneId
作为 Object
值传递。将这些传递给 ServletContext::setAttribute
.
String key = "com.example.acme_webapp.zoneid" ;
Object value = ZoneId.of( "Asia/Ashgabat" ) ;
myWebAppContext.setAttribute( key , value ) ;
在您的应用代码中,look up the context并在需要时随时归因。询问正在服务的 Servlet 请求的上下文。
ServletContext context = request.getServletContext() ;
从存储的属性中请求值。
Object value = context.getAttribute( "com.example.acme_webapp.zoneid.mongolia" ) ;
将 Object
转换回 ZoneId
。我们知道这应该可行,但对于防御性编程,您可能需要检查 instanceof
。
ZoneId z = ( ZoneId ) value ;
然后继续你的工作。正如我们上面所讨论的,也许您想捕捉那个区域中看到的时间。
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
提示:您可能想要定义一个枚举来处理属性名称的多个区域字符串。复制粘贴字符串值是有风险的。参见 tutorial .
请注意,虽然每个网络应用程序实例都有自己的 ZoneId
对象,该对象正在跨线程共享。根据定义,Servlet 环境是高度线程化的,每个请求都在一个线程上得到服务。这样 ZoneId
就可以在任意数量的线程之间共享。但没关系。幸运的是,java.time 类是 thread-safe通过设计,使用 immutable objects图案。
强制性 Servlet 线程并发技巧:任何进行 Servlet 编码的人都应该阅读并重读这本书:Java Concurrency in Practice作者:Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes、Doug Lea。
关于java - tomcat中如何为每个虚拟主机设置TimeZone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31934995/
我需要以 [+/-]hh:mm 格式保存手机的时区 我正在使用 TimeZone 类来处理这个问题,但我能得到的唯一格式如下: PST -05:00 GMT +02:00 我宁愿不对结果进行子串化,是
我正在尝试在 Node js 中使用 moment-timezone 来获取所有可用时区的列表,如下所示 - var moment = require('moment-timezone'); var
我正在使用以下代码将时区 (GMT-3) 转换为设备本地时区。 int hour=17,minute=0,day=12,month=6,year=2014; Calendar cal = new Gr
System.setProperty("user.timezone", "America/Chicago"); TimeZone.setDefault(TimeZone.getTimeZone("美国
我想从字符串初始化DateFormatter().timeZone,但是当我做类似的事情时 let dateFormatter = DateFormatter() dateFormatter.time
我通过存储日期组件字典在我的后端存储用户出生日期。它看起来像这样: { "day": 1, "month": 1, "year": 1970, "timeZone":
我一直在开发一个应用程序,它以下面给出的特定格式从服务器获取日期。 "2015-02-03 00:00:00" 我想使用 NSDateFormatter 以不同的 UI 格式显示它们但是当我更改时区时
我有什么 我有一个来自服务器的日期字符串,它的格式是 w3c 日期格式 2016-02-13T09:53:49.871Z 我的问题 当我将消息发布到服务器时,它显示的是 5 小时前而不是现在 我想要什
我正在将我的项目从 Django 1.8.2 升级到 1.9.7,我收到了这个警告: WARNINGS: my_app.my_model.date_available: (fields.W161) F
在下面的代码中: from datetime import datetime import pytz EDT = pytz.timezone('US/Eastern') d1 = datetime.n
我通过以下方式将服务器(Ubuntu 12.04)的时区更改为UTC: echo 'UTC' > /etc/timezone dpkg-reconfigure --frontend nonintera
我想获取洛杉矶的时区信息,现在10/10/2017是夏令时,但是我通过两种方式获取洛杉矶的时区得到了不同的结果。 public class TimeZoneDemo2 { public stati
我把它放在应用程序 Controller 中: before_filter :set_timezone def set_timezone Time.zone = current_user.time_
是否可以转换java.util.TimeZone字符串 sun.util.calendar.ZoneInfo[id=\"America/Los_Angeles\",offset=-28800000,d
当我写这段代码时: Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("EST"));
我正在使用 Java 8, 在我们的代码的前面,我们使用 sdf.setTimeZone(TimeZone.getTimeZone("PDT")); 转换为失败的美国太平洋地区(没有抛出任何错误,但转
我不断收到此警告:timezone of object (UTC) is different than current timezone ().我当前的时区是“EET”,如 Sys.timezone(
我正在我的网站上使用时刻时区转换器进行时区日期转换。默认情况下,我在 IST 中显示日期和时间。我有一个按钮可以转换用户时区中的给定时间。此按钮操作调用 moment js 并进行转换。到这里我没有问
我从服务响应中获得时区偏移量为“-5.00”,我需要在 UI 中将其格式化为 CST。我如何在 JavaScript 中转换它?我搜索了一下,不确定JavaScript中有没有直接的方法。 最佳答案
这个问题在这里已经有了答案: Converting string to datetime object (2 个答案) 关闭 6 年前。 我的主机有 UTC 时区,我正在尝试将 PDT 时间字符串转
我是一名优秀的程序员,十分优秀!