事实证明这似乎是一个复杂的主题,请告诉我,如果我的方法过于简单.
基本上我正在尝试做的是每天早上7点向用户列表发送电子邮件提醒(只有当他们有提醒时,但这是除了要点之外).当然,早上7点是基于全世界每个人的服务器位置的不同时间.
计划是在用户注册时通过javascript收集GMT抵消小时:
var today = new Date();
var offset = -(today.getTimezoneOffset()/60);
很简单,我现在知道偏移小时并将其与其他用户数据一起存储在数据库中.现在服务器端我有一个TimerTask设置,每小时运行一次.我收集系统小时(比如早上5点),看看离目标时间有多远(在这种情况下是2(7-5)),得到系统偏移小时(在这种情况下是-5),然后拉所有来自数据库的GMT偏移小时为-3(-5 2)的用户,然后发送电子邮件等.此时我假设我知道它上午7点为所有人,时区偏移为-3,我可以继续与过程.这将在下一个小时再次运行,并收集时区偏移为-4的所有用户.这是真的有用的东西,还是我错过了什么?
Calendar systemTime = Calendar.getInstance();
int targetHour = 7;
int currentHour = systemTime.get(Calendar.HOUR_OF_DAY); //Its 5 am.
int difference = targetHour - currentHour; //2
int zoneOffset = systemTime.get(Calendar.ZONE_OFFSET) / (1000*60*60); //-5
int targetZone = zoneOffset + difference; //-3
List users = userDAO.findByZoneOffset(targetZone);
for(User user : users) {
//Send email or whatever I want to do with these users.
}
我理解可能客户端时区可能设置不正确,因此产生了结果,但我愿意承担这种风险,因为它不是绝对必要的提醒出现在正好早上7点,更可取.
解决方法:
The plan is to collect to GMT offset hour via javascript from the user when they register
这不足以一致地获得时区.它没有考虑夏令时.因此,如果用户在任何可以观察夏令时的地方,他们将在早上6点收到电子邮件大约半年,或者他们将在早上8点收到大约半年的电子邮件.你最好根据IP地理位置偏移来猜测他们的时区.
I have a TimerTask set up that runs every hour.
我建议比这更频繁地跑步.否则,您可能会发现在您发送电子邮件之前就已经开始醒来了 – 所以您再回去睡觉,并在下次7:59发送电子邮件…这可能是您当前的8:59方案,基于客户DST的变化.那时你的预计发送时间差不多两个小时了!
I collect the system hour
也不要这样做.此时有两个时区需要考虑 – 并且您的服务器时区完全不相关.使用UTC直到转换为客户端的本地时间.它会让生活变得更加简单.如果您仍在使用日历,则只需设置其时区即可.
看看你的代码,看起来你最终可能会完全错过一堆用户,如果你正在检查完全匹配的小时.如果您最终在(比方说)3:59运行一次,然后在4:01运行一次,那么您将错过任何必须在4运行的人.我建议您记录上次向每个用户发送邮件的时间 – 或者可能在你上次跑步的时候 – 并用它来确保你总能抓住每个人.
最后,我强烈建议您使用Joda Time.这是一个更清晰的日期/时间API,它将帮助您考虑在代码中的正确位置使用正确的概念.
标签:java,timezone,gmt
来源: https://codeday.me/bug/0709/1412225.html