事实证明这似乎是一个复杂的主题,请告诉我我的方法是否太简单了。
基本上,我想做的就是在每天早上7点向用户列表发送一封电子邮件提醒(只有当他们有提醒的时候,但这不是重点)。当然,上午7点对于世界各地的每个人来说都是在不同的时间。
计划是在用户注册时通过javascript从用户那里收集到GMT偏移时间:
var today = new Date();
var offset = -(today.getTimezoneOffset()/60);很简单,我现在知道了偏移时间,并将其与其他用户数据一起存储在数据库中。现在在服务器端,我设置了一个每小时运行一次的TimerTask。我收集系统小时(说它的上午5点),看看离我的目标时间有多远(在这种情况下是2 (7-5)),获得系统偏移小时(在这种情况下是-5),然后从数据库中拉出所有具有-3 (-5 + 2) GMT偏移小时的用户,然后做电子邮件发送等。这将在下一个小时再次运行,并收集时区偏移量为-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<User> users = userDAO.findByZoneOffset(targetZone);
for(User user : users) {
//Send email or whatever I want to do with these users.
}我理解客户端时区可能设置不正确,因此产生off结果,但我愿意冒这个风险,因为提醒没有绝对必要在早上7点整出去,只是更好。
发布于 2012-12-10 15:15:41
计划是在用户注册时通过javascript从用户那里收集到格林尼治标准时间偏移小时数
这将不足以获得一致的时区。它不考虑夏令时。因此,如果用户在任何遵守夏令时的地方,他们要么在大约半年的时间里在早上6点收到电子邮件,要么在大约半年的上午8点收到电子邮件。您最好根据IP地理位置+偏移量来猜测他们的时区。
我有一个每小时运行一次的TimerTask设置。
我建议你多跑几次。否则,你很可能会在发送电子邮件之前醒来--所以你会继续睡觉,并在下次7:59发送电子邮件……根据客户端DST的变化,您当前的方案可能是8:59。在这一点上,您几乎比预期的发送时间差了两个小时!
我收集系统小时数
也不要那样做。此时需要考虑两个时区,而您的服务器时区完全无关紧要。使用UTC,直到您转换为客户端的本地时间。这将使生活变得简单得多。如果你还在使用Calendar,你可以通过设置它的时区来实现。
看看你的代码,看起来你也可能会完全错过一群用户,如果你是通过精确匹配的小时来检查的话。如果你最终在3:59跑了一次,然后在4:01跑了一次,你会错过那些必须在4点跑的人。我建议跟踪你最后一次给每个用户发送邮件的时间--或者可能是你最后一次跑的时间--并用它来确保你总是能赶上每个人。
最后,我强烈建议您使用Joda Time。它是一个更清晰的日期/时间API,它将帮助您在代码中的正确位置思考要使用的正确概念。
https://stackoverflow.com/questions/13796457
复制相似问题