好吧,伙计们,我已经解决这个问题大约两周了,现在我已经尝试了我能想到的一切,并在这里看到了大量的答案,感觉他们会回答这个问题,但我只是不知道我该如何做我想做的事情,这让我发疯了!任何地方似乎都没有人有答案,到处都是半个答案,但似乎没有人真正做我需要做的事情,肯定有人以前解决过这个问题!请原谅这个很长的问题,但重要的是问题问对了,这样答案才能真正满足需要!:D
此外,如果你可能提供的任何答案都没有考虑到我的数据存储/服务器是谷歌应用引擎(GAE),我的客户端是用谷歌网络工具包(GWT)编写的,所有东西都是用Java编写的,请不要再阅读了,我对Python、MySQL或PHP或类似的东西一无所知
最后,如果有人知道有更好的地方来解决这样的问题,请告诉我,因为我一直在遇到这样的问题。除了在这里,我不知道如何找到解决方案,或者花几个小时在谷歌上搜索其他已经解决问题的人。我也不明白如何从JavaDocs中找出任何东西——对不起,但在有人向我解释之前,我只是不会得到
我在服务器上存储了一个日期时间(显然是UTC),我也在服务器上为每个企业主存储了时区,存储为字符串(例如"America/New_York"
)。这个字符串是通过在服务器上使用java.util.TimeZone.getAvailableIDs()
并让企业所有者为他们的业务选择相关时区来获得的(如果他们什么都不选择,默认为"Europe/London"
-不需要挂断)我需要在未来的某个时候将任何日期时间传回客户端PC,忽略他们PC上的本地时区,因为需要根据企业所有者的时区来显示日期时间。
例如,企业主是伦敦的一位理发师,他们有一个在线预约时间表,任何潜在客户都可以查看。其中一位客户(也在伦敦)想预约,在9月3日星期一英国夏令时上午9点看到一个空位并预订。
然后,它作为UTC时间存储在数据存储中(实际上是0800,因为BST是UTC+1),当然,企业所有者已经选择"Europe/London"
作为他们的时区。到目前为止一切都很好。
现在,在未来的某个时候,客户正在纽约参加一个商务会议,并意识到他们有一个下周在伦敦理发的预约,他们想推迟一周,所以他们试图查看预约(在理发师预约簿中),但他们不想看到纽约时间凌晨4点,他们想看到英国时间上午9点。
所以我的问题是,当客户在9月3日点击查看预约时,服务器可以发回UTC日期时间0800和java.util.TimeZone
ID字符串"Europe/London"
但因为在客户端上我只能使用
com.google.gwt.i18n.client.TimeZone
它不允许我使用功能
TimeZone bizTimeZone=TimeZone.getTimeZone("Europe/London")
(which works for `java.util.TimeZone`)
因为它导致错误
"The method getTimeZone(String) is undefined for the type TimeZone"
它建议将其更改为
com.google.gwt.i18n.client.TimeZone.createTimeZone("Europe/London")
但在这个版本中,期望的是GWTcom.google.gwt.i18n.client.TimeZoneConstants
"对象"(此消息末尾显示的示例),而不是java.util.TimeZone.createTimeZone()
将接受的简单字符串。
我可以使用创建这个
final TimeZoneConstants constTz = GWT.create(TimeZoneConstants.class);
final TimeZone timeZoneCali = TimeZone.createTimeZone(constTz.europeLondon());
但当我从"Europe/London"
开始时,我不知道如何做到这一点,和/或我不知道怎样将这个对象存储到应用程序引擎数据库中,然后再检索它。
顺便说一句,在评论文本中,我也尝试过使用以下行:
//Calendar tmad = new GregorianCalendar(TimeZone.getTimeZone("Europe/London"));
//Calendar cal = Calendar.getInstance(someTimeZone);
//DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//df1.setTimeZone(TimeZone.getTimeZone("Europe/London"));
//final TimeZone timeZoneClient = TimeZone.createTimeZone("Europe/London");
//dtf.format(date,timeZoneClient)
必须有一个标准的方法来做这件事,我真的不能成为第一个必须解决这个问题的人!
constTz.europeLundon()={"转换":[1939460224770,028130,633506、36866、642242、45602、6050978、54506、60,59714、0、63242、60、68450、0、71978、60、77354、0、80714、60、86090,0,89450,60,94826,0,98521,60,20561,0,107257,60,112297,0,115993、60121033、0、124729、60、129937、0、133633、60和138673、0,142369、601147409、151105、60156145、159841、60164881、0,168577、601173785、177313、60182221、186217、60191257、0,194953、60199993、203689、60208729、0211425、60217465、0,221161、602226201、230065、60/235105、0238801、60/2243841、0,247537、60252577、256273、60261481、265009、60270217、0,273745、60/278953、0828649、60/287689、0291385、60/296425、0,300121、60305229、308857、60314065、0317593、60322001、0,326329、603331537、335233、60340273、343969、60349009、0,352705、60357913、0361441、603366649、370177、603375385、0,379081、60384121、387817、60392857、396553、60401593、0,405289、60410497、414025、60419233、0422761、60427969、0,431665、60436705、440401、6045441、449137、604454345、0,457873、60、463081、0、466609、60、471817、0和475513、60、480553、0,484249、60489289、492985、60498025、501721、60506929、0,510457、60515665、0519193、60524001、528097、60533137、0,536833、60541873、545569、60550777、554305、60555113、0,563041、568249、571777、576985、580681、585721、0,589417,60594457,0],"名称":["GMT","格林尼治标准时间","BST","英国夏令时"],"id":"欧洲/伦敦","std_offset":0}
v2.4也有类似的问题。
我认为莱利·拉克是对的。
TimeZone.createTimeZone("亚洲/东京")在GWT2.4中不起作用
然而,我发现我可以通过使用浏览器的默认设置来获得东京区域
Date d = new Date();
TimeZone timezone = TimeZone.createTimeZone(d.getTimezoneOffset());
这正是Riley Lark为您建议的,因为europeLundon有"std_offset":0…
TimeZone时区=时区.createTimeZone(0);
您尝试过TimeZone.createTimeZone("Europe/London");
吗?至少在较新版本的GWT中,这种方法接受一大堆名称,显然是"从CLDR和Olson时区数据库中准备的"。文档特别引用了您的用例:通过json传输时区。
查看属性文件-它似乎具有时区的所有标准名称。
如果这不适合你,你可以用分钟来传输时区的偏移量,然后用TimeZone.createTimeZone(offsetInMinutes)
创建你的时区。
我遇到了类似的问题,需要将服务器时区保留在客户端。这有点挑战性,因为GWT不允许对最近的java库中的对象进行序列化,例如java.time.ZonedDateTime。
/*
* This method forces a java.util.Date object to use a hard coded timezone.
* The method first discards any local timezone from the Date object,
* then adds a given timezone with the time. The purpose is to keep the
* original timestamp unchanged to avoid server-clinet timezone mismatch and use the
* server side timestamp.
*/
public java.util.Date updateZonedUtil(java.util.Date aDate)
{
// hard coding timezone with server timezone.
String timezone = "America/Toronto";
java.util.Date utilDate = new java.util.Date(aDate.getTime());
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String strDate = formatter.format(utilDate);
DateTimeFormatter localFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
LocalDateTime localdt = LocalDateTime.parse(strDate, localFormatter);
ZonedDateTime zdt = localdt.atZone(ZoneId.of(timezone));
return Date.from(zdt.toInstant());
}