Java每天在同一时间向不同时区发送电子邮件



事实证明这似乎是一个复杂的主题,如果我的方法太简单,请告诉我。

基本上,我想做的是在每天早上7点向用户列表发送电子邮件提醒(只有当他们收到提醒时,但这不是重点)。当然,对于全世界的每个人来说,早上7点是在不同的时间,这取决于服务器的位置。

计划是在用户注册时通过javascript收集到GMT偏移小时:

var today = new Date();  
var offset = -(today.getTimezoneOffset()/60);

很简单,我现在知道了偏移小时数,并将其与其他用户数据一起存储在数据库中。现在,在服务器端,我设置了一个每小时运行一次的TimerTask。我收集系统小时数(比如说凌晨5点),看看离我的目标时间有多远(在这种情况下是2(7-5)),得到系统偏移小时数(在这种情形下是-5),然后从数据库中提取GMT偏移小时数为-3(-5+2)的所有用户,然后发送电子邮件等。在这一点上,我假设我知道时区偏移为-3的每个人的早上7点,我可以继续这个过程。这将在下一个小时再次运行,并收集时区偏移量为-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.
}

我知道客户时区可能设置不正确,因此产生了错误的结果,但我愿意冒这个风险,因为提醒并不是绝对必要的,最好在早上7点发出。

计划是在用户注册时通过javascript收集到GMT偏移小时

这不足以获得一致的时区。它没有考虑夏令时。因此,如果用户在任何遵守夏令时的地方,他们要么在大约半年的时间里在早上6点收到电子邮件,要么在大约半个时间里在上午8点收到电子邮件。你最好根据IP地理位置+偏移量来猜测他们的时区。

我设置了一个每小时运行一次的TimerTask。

我建议你多跑步。否则,你很可能会发现,就在你会发送电子邮件之前,你会醒来,所以你会回去睡觉,并在下次7:59发送电子邮件。。。根据客户夏令时的变化,您当前的方案可能是8:59。在这一点上,你几乎有两个小时的发送时间了!

我收集系统小时

也不要那样做。此时,需要考虑两个时区,而您的服务器时区完全无关。在转换为客户端的本地时间之前,请使用UTC。这会让生活变得更简单。如果您仍在使用Calendar,只需设置其时区即可完成此操作。

看看你的代码,如果你按照小时的精确匹配进行检查,你可能会完全错过一堆用户。如果你在3:59跑一次,然后在4:01跑一次的话,你会想念那些必须在4点跑的人。我建议跟踪你最后一次向每个用户发送邮件的时间,或者可能是最后一次跑步的时间,并使用它来确保你总是抓住每个人。

最后,我强烈建议您使用Joda Time。这是一个更干净的日期/时间API,它将帮助您思考在代码的正确位置使用的正确概念。

最新更新