对于我的每个用户,我存储了tzid
,我将其转换为DateTimeZone
,其中包含有关其当地时区的信息。
我想在当地时间上午8点向用户发送每日电子邮件;如果上午8点因为夏令时转移等原因而模棱两可,我只需选择上午8点之一;我不在乎哪个。
我的工作每小时运行一次,我有一个Instant
包含作业的最后一次运行时间,另一个Instant
包含作业的下一个运行时间。
鉴于这两个Instant
名为previousRun
和nextRun
,DateTimeZone
名为tz
,我如何确定localTime
是否eightAM
{1}}落在这个工作的范围之间?如果是,我需要向用户发送电子邮件。
答案 0 :(得分:4)
鉴于这两个Instant调用了previousRun和nextRun,而DateTimeZone调用了tz,我如何确定调用了8AM的localTime是否落在这个作业运行的界限之间?
我认为,以一般方式这样做有点棘手。但是,如果你可以依赖你想要远离午夜的时间和你的工作将每小时运行一次(所以你不需要考虑如果它会发生什么没有在午夜和早上8点之间运行,例如)我认为你可以这样做:
public static bool ShouldSendEmail(Instant previousRun, Instant nextRun,
DateTimeZone zone)
{
// Find the instant at which we should send the email for the day containing
// the last run.
LocalDate date = previousRun.InZone(zone).Date;
LocalDateTime dateTime = date + new LocalTime(8, 0);
Instant instant = dateTime.InZoneLeniently(zone).ToInstant();
// Check whether that's between the last instant and the next one.
return previousRun <= instant && instant < nextRun;
}
您可以查看InZoneLeniently
的文档以确切地检查它会给出什么结果,但听起来您并不介意:这仍然会每天发送一封电子邮件,一小时内包含上午8点
我没有在一天中的时间参数化,因为处理一天中的时间可能接近午夜的一般情况会更难。
编辑:如果您可以存储“下一个发送日期”,那么很容易 - 而且您不需要previousRun
部分:
public static bool ShouldSendEmail(LocalDateTime nextDate, Instant nextRun,
DateTimeZone zone, LocalTime timeOfDay)
{
LocalDateTime nextEmailLocal = nextDate + timeOfDay;
Instant nextEmailInstant = nextDateTime.InZoneLeniently(zone).ToInstant();
return nextRun > nextEmailInstant;
}
基本上说,“当我们下次要发送电子邮件时解决 - 如果下次运行的时间晚于此,我们应该立即发送。”